12 #include <boost/program_options.hpp>
13 #include <boost/tokenizer.hpp>
14 #include <boost/regex.hpp>
15 #include <boost/swap.hpp>
16 #include <boost/algorithm/string/case_conv.hpp>
18 #include <stdair/ui/cmdline/SReadline.hpp>
20 #include <stdair/stdair_basic_types.hpp>
21 #include <stdair/stdair_json.hpp>
22 #include <stdair/basic/BasConst_General.hpp>
23 #include <stdair/basic/ProgressStatusSet.hpp>
24 #include <stdair/basic/DemandGenerationMethod.hpp>
25 #include <stdair/bom/EventStruct.hpp>
26 #include <stdair/bom/BookingRequestStruct.hpp>
27 #include <stdair/bom/BomDisplay.hpp>
28 #include <stdair/service/Logger.hpp>
31 #include <trademgen/config/trademgen-paths.hpp>
53 "/rds01/demand05.csv");
58 const stdair::DemandGenerationMethod
60 stdair::DemandGenerationMethod::POI_PRO;
72 stdair::DEFAULT_RANDOM_SEED;
95 typedef std::vector<std::string> TokenList_T;
124 typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
127 const boost::char_separator<char> lSepatorList(
" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
130 Tokeniser_T lTokens (iPhrase, lSepatorList);
131 for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
132 tok_iter != lTokens.end(); ++tok_iter) {
133 const std::string& lTerm = *tok_iter;
134 ioWordList.push_back (lTerm);
139 std::ostringstream oStr;
141 unsigned short idx = iWordList.size();
142 for (WordList_T::const_iterator itWord = iWordList.begin();
143 itWord != iWordList.end(); ++itWord, --idx) {
144 const std::string& lWord = *itWord;
157 template<
class T> std::ostream&
operator<< (std::ostream& os,
158 const std::vector<T>& v) {
159 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout,
" "));
166 stdair::RandomSeed_T& ioRandomSeed,
167 stdair::Filename_T& ioInputFilename,
168 stdair::Filename_T& ioOutputFilename,
169 stdair::Filename_T& ioLogFilename,
170 stdair::DemandGenerationMethod& ioDemandGenerationMethod) {
173 char lDemandGenerationMethodChar;
179 boost::program_options::options_description
generic (
"Generic options");
180 generic.add_options()
181 (
"prefix",
"print installation prefix")
182 (
"version,v",
"print version string")
183 (
"help,h",
"produce help message");
187 boost::program_options::options_description config (
"Configuration");
190 "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -i/--input option")
192 boost::program_options::value<stdair::RandomSeed_T>(&ioRandomSeed)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_SEED),
193 "Seed for the random generation")
194 (
"demandgeneration,G",
196 "Method used to generate the demand (i.e., the booking requests): Poisson Process (P) or Order Statistics (S)")
199 "(CSV) input file for the demand distributions")
202 "Filepath for the logs")
207 boost::program_options::options_description hidden (
"Hidden options");
210 boost::program_options::value< std::vector<std::string> >(),
211 "Show the copyright (license)");
213 boost::program_options::options_description cmdline_options;
214 cmdline_options.add(
generic).add(config).add(hidden);
216 boost::program_options::options_description config_file_options;
217 config_file_options.add(config).add(hidden);
219 boost::program_options::options_description visible (
"Allowed options");
220 visible.add(
generic).add(config);
222 boost::program_options::positional_options_description p;
223 p.add (
"copyright", -1);
225 boost::program_options::variables_map vm;
226 boost::program_options::
227 store (boost::program_options::command_line_parser (argc, argv).
228 options (cmdline_options).positional(p).run(), vm);
230 std::ifstream ifs (
"trademgen.cfg");
231 boost::program_options::store (parse_config_file (ifs, config_file_options),
233 boost::program_options::notify (vm);
235 if (vm.count (
"help")) {
236 std::cout << visible << std::endl;
240 if (vm.count (
"version")) {
241 std::cout << PACKAGE_NAME <<
", version " << PACKAGE_VERSION << std::endl;
245 if (vm.count (
"prefix")) {
246 std::cout <<
"Installation prefix: " << PREFIXDIR << std::endl;
250 if (vm.count (
"builtin")) {
253 const std::string isBuiltinStr = (ioIsBuiltin ==
true)?
"yes":
"no";
254 std::cout <<
"The BOM should be built-in? " << isBuiltinStr << std::endl;
256 if (ioIsBuiltin ==
false) {
259 if (vm.count (
"input")) {
260 ioInputFilename = vm[
"input"].as< std::string >();
261 std::cout <<
"Input filename is: " << ioInputFilename << std::endl;
266 std::cerr <<
"Either one among the -b/--builtin and -i/--input "
267 <<
"options must be specified" << std::endl;
271 if (vm.count (
"output")) {
272 ioOutputFilename = vm[
"output"].as< std::string >();
273 std::cout <<
"Output filename is: " << ioOutputFilename << std::endl;
276 if (vm.count (
"log")) {
277 ioLogFilename = vm[
"log"].as< std::string >();
278 std::cout <<
"Log filename is: " << ioLogFilename << std::endl;
281 if (vm.count (
"demandgeneration")) {
282 ioDemandGenerationMethod =
283 stdair::DemandGenerationMethod (lDemandGenerationMethodChar);
284 std::cout <<
"Date-time request generation method is: "
285 << ioDemandGenerationMethod.describe() << std::endl;
289 std::cout <<
"The random generation seed is: " << ioRandomSeed << std::endl;
295 void initReadline (swift::SReadline& ioInputReader) {
298 std::vector<std::string> Completers;
303 Completers.push_back (
"help");
304 Completers.push_back (
"list_event");
305 Completers.push_back (
"list_demand_stream");
306 Completers.push_back (
"reset");
307 Completers.push_back (
"generate_next_br");
308 Completers.push_back (
"generate_first_br");
309 Completers.push_back (
"generate_all_br");
310 Completers.push_back (
"next");
311 Completers.push_back (
"json_list");
312 Completers.push_back (
"quit");
316 ioInputReader.RegisterCompletions (Completers);
320 Command_T::Type_T extractCommand (TokenList_T& ioTokenList) {
321 Command_T::Type_T oCommandType = Command_T::LAST_VALUE;
324 if (ioTokenList.empty() ==
false) {
325 TokenList_T::iterator itTok = ioTokenList.begin();
326 std::string lCommand (*itTok);
327 boost::algorithm::to_lower (lCommand);
329 if (lCommand ==
"help") {
330 oCommandType = Command_T::HELP;
332 }
else if (lCommand ==
"list_event") {
333 oCommandType = Command_T::LIST_EVENT;
335 }
else if (lCommand ==
"list_demand_stream") {
336 oCommandType = Command_T::LIST_DEMAND_STREAM;
338 }
else if (lCommand ==
"reset") {
339 oCommandType = Command_T::RESET;
341 }
else if (lCommand ==
"delete_first") {
342 oCommandType = Command_T::NEXT;
344 }
else if (lCommand ==
"generate_first_br") {
345 oCommandType = Command_T::GENERATE_FIRST_BR;
347 }
else if (lCommand ==
"generate_next_br") {
348 oCommandType = Command_T::GENERATE_NEXT_BR;
350 }
else if (lCommand ==
"generate_all_br") {
351 oCommandType = Command_T::GENERATE_ALL_BR;
353 }
else if (lCommand ==
"json_list") {
354 oCommandType = Command_T::JSON_LIST;
356 }
else if (lCommand ==
"quit") {
357 oCommandType = Command_T::QUIT;
362 ioTokenList.erase (itTok);
365 oCommandType = Command_T::NOP;
372 std::string toString (
const TokenList_T& iTokenList) {
373 std::ostringstream oStr;
376 unsigned short idx = 0;
377 for (TokenList_T::const_iterator itTok = iTokenList.begin();
378 itTok != iTokenList.end(); ++itTok, ++idx) {
389 int main (
int argc,
char* argv[]) {
392 const unsigned int lHistorySize (100);
393 const std::string lHistoryFilename (
"trademgen.hist");
394 const std::string lHistoryBackupFilename (
"trademgen.hist.bak");
397 stdair::EventStruct lCurrentInteractiveEventStruct;
398 stdair::DateTime_T lCurrentInteractiveDateTime;
399 std::string lDefaultDemandStreamKey;
405 stdair::RandomSeed_T lRandomSeed;
408 stdair::Filename_T lInputFilename;
411 stdair::Filename_T lOutputFilename;
414 stdair::Filename_T lLogFilename;
417 stdair::DemandGenerationMethod
421 const int lOptionParserStatus =
423 lInputFilename, lOutputFilename, lLogFilename,
424 lDemandGenerationMethod);
426 if (lOptionParserStatus == K_TRADEMGEN_EARLY_RETURN_STATUS) {
431 std::ofstream logOutputFile;
433 logOutputFile.open (lLogFilename.c_str());
434 logOutputFile.clear();
437 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
443 if (isBuiltin ==
true) {
445 trademgenService.buildSampleBom();
446 lDefaultDemandStreamKey =
"SIN-BKK 2010-Feb-08 Y";
451 trademgenService.parseAndLoad (lDemandFilePath);
452 lDefaultDemandStreamKey =
"SIN-BKK 2009-Feb-09 Y";
456 STDAIR_LOG_DEBUG (
"====================================================");
457 STDAIR_LOG_DEBUG (
"= Beginning of the interactive session =");
458 STDAIR_LOG_DEBUG (
"====================================================");
461 swift::SReadline lReader (lHistoryFilename, lHistorySize);
462 initReadline (lReader);
465 std::string lUserInput;
466 bool EndOfInput (
false);
467 Command_T::Type_T lCommandType (Command_T::NOP);
469 while (lCommandType != Command_T::QUIT && EndOfInput ==
false) {
476 std::ostringstream oPromptStr;
477 oPromptStr <<
"trademgen " <<
"> " ;
481 TokenList_T lTokenListByReadline;
482 lUserInput = lReader.GetLine (oPromptStr.str(), lTokenListByReadline,
486 lReader.SaveHistory (lHistoryBackupFilename);
490 std::cout << std::endl;
495 lCommandType = extractCommand (lTokenListByReadline);
497 switch (lCommandType) {
500 case Command_T::HELP: {
501 std::cout << std::endl;
502 std::cout <<
"Commands: " << std::endl;
503 std::cout <<
" help" <<
"\t\t\t" <<
"Display this help" << std::endl;
504 std::cout <<
" quit" <<
"\t\t\t" <<
"Quit the application" << std::endl;
505 std::cout <<
" list_event" <<
"\t\t"
506 <<
"List all the events in the queue" << std::endl;
507 std::cout <<
" list_demand_stream" <<
"\t"
508 <<
"List the streams used to generate demand" << std::endl;
509 std::cout <<
" reset" <<
"\t\t\t" <<
"Reset the service (including the "
510 <<
"event queue)" << std::endl;
511 std::cout <<
" generate_first_br" <<
"\t" <<
"Generate the first booking "
512 <<
"request for each demand stream and add it to the event queue"
514 std::cout <<
" generate_next_br" <<
"\t" <<
"Generate the next event for "
515 <<
"the specified demand stream and add it to the event queue"
516 <<
"\n\t\t\tFor instance:"
517 <<
"\n\t\t\t 'generate_next_br " << lDefaultDemandStreamKey
519 std::cout <<
" generate_all_br" <<
"\t" <<
"Generate all the events for "
520 <<
"the specified demand stream and add it to the event queue"
521 <<
"\n\t\t\tFor instance:"
522 <<
"\n\t\t\t 'generate_all_br " << lDefaultDemandStreamKey
524 std::cout <<
" delete_first" <<
"\t\t"
525 <<
"Pop the next event from the queue"
527 std::cout <<
" \nDebug Commands" << std::endl;
528 std::cout <<
" json_list" <<
"\t\t"
529 <<
"List events in the queue in a JSON format"
531 std::cout << std::endl;
536 case Command_T::QUIT: {
541 case Command_T::LIST_EVENT: {
543 std::cout <<
"List of events" << std::endl;
545 std::ostringstream oEventListStr;
546 oEventListStr << trademgenService.list ();
547 std::cout << oEventListStr.str() << std::endl;
548 STDAIR_LOG_DEBUG (oEventListStr.str());
555 case Command_T::LIST_DEMAND_STREAM: {
557 std::cout <<
"List of demand streams" << std::endl;
559 std::ostringstream oEventListStr;
560 oEventListStr << trademgenService.displayDemandStream ();
561 std::cout << oEventListStr.str() << std::endl;
562 STDAIR_LOG_DEBUG (oEventListStr.str());
569 case Command_T::RESET: {
571 std::cout <<
"Reset" << std::endl;
574 trademgenService.reset();
580 case Command_T::GENERATE_NEXT_BR: {
583 const stdair::DemandGeneratorKey_T lDemandStreamKey =
584 toString(lTokenListByReadline);
587 const bool hasDemandStream =
588 trademgenService.hasDemandStream(lDemandStreamKey);
590 if (hasDemandStream ==
false) {
592 std::ostringstream oNoDemandStreamStr;
593 oNoDemandStreamStr <<
"Wrong demand stream key: '"
594 << lDemandStreamKey <<
"'."
595 <<
"\nExisting demand streams are:\n"
596 << trademgenService.displayDemandStream();
597 std::cout << oNoDemandStreamStr.str() << std::endl;
598 STDAIR_LOG_DEBUG (oNoDemandStreamStr.str());
601 assert (hasDemandStream ==
true);
603 stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
604 const bool stillHavingRequestsToBeGenerated =
605 trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
607 lDemandGenerationMethod);
608 if (stillHavingRequestsToBeGenerated ==
false) {
610 std::ostringstream oNoMoreEventToGenerateStr;
611 oNoMoreEventToGenerateStr <<
"No more events to generate for the demand "
612 <<
"stream: '" << lDemandStreamKey <<
"'.";
613 std::cout << oNoMoreEventToGenerateStr.str() << std::endl;
614 STDAIR_LOG_DEBUG (oNoMoreEventToGenerateStr.str());
617 assert (stillHavingRequestsToBeGenerated ==
true);
619 trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
622 std::ostringstream oOneMoreEventGeneratedStr;
623 oOneMoreEventGeneratedStr <<
"One more event have been generated for the demand "
624 <<
"stream: '" << lDemandStreamKey <<
"'.";
625 std::cout << oOneMoreEventGeneratedStr.str() << std::endl;
626 STDAIR_LOG_DEBUG (oOneMoreEventGeneratedStr.str());
632 case Command_T::GENERATE_FIRST_BR: {
634 std::cout <<
"Generate first requests" << std::endl;
637 trademgenService.generateFirstRequests (lDemandGenerationMethod);
643 case Command_T::GENERATE_ALL_BR: {
646 const stdair::DemandGeneratorKey_T lDemandStreamKey =
647 toString(lTokenListByReadline);
650 const bool hasDemandStream =
651 trademgenService.hasDemandStream(lDemandStreamKey);
653 if (hasDemandStream ==
false) {
655 std::ostringstream oNoDemandStreamStr;
656 oNoDemandStreamStr <<
"Wrong demand stream key: '"
657 << lDemandStreamKey <<
"'."
658 <<
"\nExisting demand streams are:\n"
659 << trademgenService.displayDemandStream();
660 std::cout << oNoDemandStreamStr.str() << std::endl;
661 STDAIR_LOG_DEBUG (oNoDemandStreamStr.str());
664 assert (hasDemandStream ==
true);
666 stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
667 bool stillHavingRequestsToBeGenerated =
668 trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
670 lDemandGenerationMethod);
673 if (stillHavingRequestsToBeGenerated ==
false) {
675 std::ostringstream oNoMoreEventToGenerateStr;
676 oNoMoreEventToGenerateStr <<
"No more events to generate for the demand "
677 <<
"stream: '" << lDemandStreamKey <<
"'.";
678 std::cout << oNoMoreEventToGenerateStr.str() << std::endl;
679 STDAIR_LOG_DEBUG (oNoMoreEventToGenerateStr.str());
682 assert (stillHavingRequestsToBeGenerated ==
true);
684 stdair::Count_T lNumberOfRequests = 0;
685 while (stillHavingRequestsToBeGenerated ==
true) {
687 trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
688 stillHavingRequestsToBeGenerated =
689 trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
691 lDemandGenerationMethod);
696 std::ostringstream oOneMoreEventGeneratedStr;
697 oOneMoreEventGeneratedStr << lNumberOfRequests
698 <<
" more event(s) have been generated for the demand "
699 <<
"stream: '" << lDemandStreamKey <<
"'.";
700 std::cout << oOneMoreEventGeneratedStr.str() << std::endl;
701 STDAIR_LOG_DEBUG (oOneMoreEventGeneratedStr.str());
707 case Command_T::NEXT: {
709 std::cout <<
"Next" << std::endl;
711 if (trademgenService.isQueueDone() ==
true) {
714 std::ostringstream oEmptyQueueStr;
715 oEmptyQueueStr <<
"The event queue is empty: no event can be popped out.";
716 std::cout << oEmptyQueueStr.str() << std::endl;
717 STDAIR_LOG_DEBUG (oEmptyQueueStr.str());
725 trademgenService.popEvent (lCurrentInteractiveEventStruct);
728 std::ostringstream oEventStr;
729 oEventStr <<
"Poped event: '"
730 << lCurrentInteractiveEventStruct.describe() <<
"'.";
731 std::cout << oEventStr.str() << std::endl;
732 STDAIR_LOG_DEBUG (oEventStr.str());
739 case Command_T::JSON_LIST: {
741 std::cout <<
"JSON Event List" << std::endl;
743 std::ostringstream lMyCommandJSONstream;
744 lMyCommandJSONstream <<
"{\"event_list\":"
745 <<
"{ \"event_type\":\"" <<
"all"
749 const stdair::JSONString lJSONCommandString (lMyCommandJSONstream.str());
750 const std::string& lCSVEventListDump =
751 trademgenService.jsonHandler (lJSONCommandString);
754 std::cout << lCSVEventListDump << std::endl;
755 STDAIR_LOG_DEBUG (lCSVEventListDump);
761 case Command_T::NOP: {
765 case Command_T::LAST_VALUE:
768 std::ostringstream oStr;
769 oStr <<
"That command is not yet understood: '" << lUserInput
770 <<
"' => " << lTokenListByReadline;
771 STDAIR_LOG_DEBUG (oStr.str());
772 std::cout << oStr.str() << std::endl;
778 STDAIR_LOG_DEBUG (
"End of the session. Exiting.");
779 std::cout <<
"End of the session. Exiting." << std::endl;
782 logOutputFile.close();