$treeview $search $mathjax
TraDemGen Logo  1.00.2
$projectbrief
$projectbrief
$searchbox

trademgen.cpp

Go to the documentation of this file.
00001 
00005 // STL
00006 #include <cassert>
00007 #include <iostream>
00008 #include <sstream>
00009 #include <fstream>
00010 #include <string>
00011 // Boost (Extended STL)
00012 #include <boost/program_options.hpp>
00013 #include <boost/tokenizer.hpp>
00014 #include <boost/regex.hpp>
00015 #include <boost/swap.hpp>
00016 #include <boost/algorithm/string/case_conv.hpp>
00017 // GNU Readline Wrapper
00018 #include <stdair/ui/cmdline/SReadline.hpp>
00019 // StdAir
00020 #include <stdair/stdair_basic_types.hpp>
00021 #include <stdair/stdair_json.hpp>
00022 #include <stdair/basic/BasConst_General.hpp>
00023 #include <stdair/basic/ProgressStatusSet.hpp>
00024 #include <stdair/basic/DemandGenerationMethod.hpp>
00025 #include <stdair/bom/EventStruct.hpp>
00026 #include <stdair/bom/BookingRequestStruct.hpp>
00027 #include <stdair/bom/BomDisplay.hpp>
00028 #include <stdair/service/Logger.hpp>
00029 // TraDemGen
00030 #include <trademgen/TRADEMGEN_Service.hpp>
00031 #include <trademgen/config/trademgen-paths.hpp>
00032 
00033 
00034 // //////// Type definitions ///////
00038 typedef std::vector<std::string> WordList_T;
00039 
00040 // //////// Specific type definitions ///////
00041 typedef unsigned int NbOfRuns_T;
00042 
00043 // //////// Constants //////
00047 const stdair::Filename_T K_TRADEMGEN_DEFAULT_LOG_FILENAME ("trademgen.log");
00048 
00052 const stdair::Filename_T K_TRADEMGEN_DEFAULT_INPUT_FILENAME (STDAIR_SAMPLE_DIR
00053                                                              "/rds01/demand05.csv");
00054 
00058 const stdair::DemandGenerationMethod
00059 K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD =
00060   stdair::DemandGenerationMethod::POI_PRO;
00061 
00065 const char K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD_CHAR =
00066   K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD.getMethodAsChar();
00067 
00071 const stdair::RandomSeed_T K_TRADEMGEN_DEFAULT_RANDOM_SEED =
00072   stdair::DEFAULT_RANDOM_SEED;
00073 
00077 const NbOfRuns_T K_TRADEMGEN_DEFAULT_RANDOM_DRAWS = 1;
00078 
00083 const bool K_TRADEMGEN_DEFAULT_BUILT_IN_INPUT = false;
00084 
00088 const int K_TRADEMGEN_EARLY_RETURN_STATUS = 99;
00089 
00090 // //////////////////////////////////////////////////////////////////////
00095 typedef std::vector<std::string> TokenList_T;
00096 
00100 struct Command_T {
00101   typedef enum {
00102     NOP = 0,
00103     QUIT,
00104     HELP,
00105     LIST_EVENT,
00106     LIST_DEMAND_STREAM,
00107     RESET,
00108     NEXT,
00109     GENERATE_NEXT_BR,
00110     GENERATE_FIRST_BR,
00111     GENERATE_ALL_BR,
00112     JSON_LIST,
00113     LAST_VALUE
00114   } Type_T;
00115 };
00116 
00117 // //////////////////////////////////////////////////////////////////////
00118 void tokeniseStringIntoWordList (const std::string& iPhrase,
00119                                  WordList_T& ioWordList) {
00120   // Empty the word list
00121   ioWordList.clear();
00122   
00123   // Boost Tokeniser
00124   typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
00125   
00126   // Define the separators
00127   const boost::char_separator<char> lSepatorList(" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
00128   
00129   // Initialise the phrase to be tokenised
00130   Tokeniser_T lTokens (iPhrase, lSepatorList);
00131   for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
00132        tok_iter != lTokens.end(); ++tok_iter) {
00133     const std::string& lTerm = *tok_iter;
00134     ioWordList.push_back (lTerm);
00135   }
00136   
00137 }// //////////////////////////////////////////////////////////////////////
00138 std::string createStringFromWordList (const WordList_T& iWordList) {
00139   std::ostringstream oStr;
00140 
00141   unsigned short idx = iWordList.size();
00142   for (WordList_T::const_iterator itWord = iWordList.begin();
00143        itWord != iWordList.end(); ++itWord, --idx) {
00144     const std::string& lWord = *itWord;
00145     oStr << lWord;
00146     if (idx > 1) {
00147       oStr << " ";
00148     }
00149   }
00150   
00151   return oStr.str();
00152 }
00153 
00154 
00155 // ///////// Parsing of Options & Configuration /////////
00156 // A helper function to simplify the main part.
00157 template<class T> std::ostream& operator<< (std::ostream& os,
00158                                             const std::vector<T>& v) {
00159   std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 
00160   return os;
00161 }
00165 int readConfiguration (int argc, char* argv[], bool& ioIsBuiltin,
00166                        stdair::RandomSeed_T& ioRandomSeed,
00167                        stdair::Filename_T& ioInputFilename,
00168                        stdair::Filename_T& ioOutputFilename,
00169                        stdair::Filename_T& ioLogFilename,
00170                        stdair::DemandGenerationMethod& ioDemandGenerationMethod) {
00171 
00172   // Demand generation method as a single char (e.g., 'P' or 'S').
00173   char lDemandGenerationMethodChar;
00174 
00175   // Default for the built-in input
00176   ioIsBuiltin = K_TRADEMGEN_DEFAULT_BUILT_IN_INPUT;
00177 
00178   // Declare a group of options that will be allowed only on command line
00179   boost::program_options::options_description generic ("Generic options");
00180   generic.add_options()
00181     ("prefix", "print installation prefix")
00182     ("version,v", "print version string")
00183     ("help,h", "produce help message");
00184     
00185   // Declare a group of options that will be allowed both on command
00186   // line and in config file
00187   boost::program_options::options_description config ("Configuration");
00188   config.add_options()
00189     ("builtin,b",
00190      "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")
00191     ("seed,s",
00192      boost::program_options::value<stdair::RandomSeed_T>(&ioRandomSeed)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_SEED),
00193      "Seed for the random generation")
00194     ("demandgeneration,G",
00195      boost::program_options::value< char >(&lDemandGenerationMethodChar)->default_value(K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD_CHAR),
00196      "Method used to generate the demand (i.e., the booking requests): Poisson Process (P) or Order Statistics (S)")
00197     ("input,i",
00198      boost::program_options::value< std::string >(&ioInputFilename)->default_value(K_TRADEMGEN_DEFAULT_INPUT_FILENAME),
00199      "(CSV) input file for the demand distributions")
00200     ("log,l",
00201      boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_TRADEMGEN_DEFAULT_LOG_FILENAME),
00202      "Filepath for the logs")
00203     ;
00204 
00205   // Hidden options, will be allowed both on command line and
00206   // in config file, but will not be shown to the user.
00207   boost::program_options::options_description hidden ("Hidden options");
00208   hidden.add_options()
00209     ("copyright",
00210      boost::program_options::value< std::vector<std::string> >(),
00211      "Show the copyright (license)");
00212         
00213   boost::program_options::options_description cmdline_options;
00214   cmdline_options.add(generic).add(config).add(hidden);
00215 
00216   boost::program_options::options_description config_file_options;
00217   config_file_options.add(config).add(hidden);
00218 
00219   boost::program_options::options_description visible ("Allowed options");
00220   visible.add(generic).add(config);
00221         
00222   boost::program_options::positional_options_description p;
00223   p.add ("copyright", -1);
00224         
00225   boost::program_options::variables_map vm;
00226   boost::program_options::
00227     store (boost::program_options::command_line_parser (argc, argv).
00228            options (cmdline_options).positional(p).run(), vm);
00229 
00230   std::ifstream ifs ("trademgen.cfg");
00231   boost::program_options::store (parse_config_file (ifs, config_file_options),
00232                                  vm);
00233   boost::program_options::notify (vm);
00234     
00235   if (vm.count ("help")) {
00236     std::cout << visible << std::endl;
00237     return K_TRADEMGEN_EARLY_RETURN_STATUS;
00238   }
00239 
00240   if (vm.count ("version")) {
00241     std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
00242     return K_TRADEMGEN_EARLY_RETURN_STATUS;
00243   }
00244 
00245   if (vm.count ("prefix")) {
00246     std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
00247     return K_TRADEMGEN_EARLY_RETURN_STATUS;
00248   }
00249 
00250   if (vm.count ("builtin")) {
00251     ioIsBuiltin = true;
00252   }
00253   const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
00254   std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
00255 
00256   if (ioIsBuiltin == false) {
00257 
00258     // The BOM tree should be built from parsing a demand input file
00259     if (vm.count ("input")) {
00260       ioInputFilename = vm["input"].as< std::string >();
00261       std::cout << "Input filename is: " << ioInputFilename << std::endl;
00262 
00263     } else {
00264       // The built-in option is not selected. However, no demand input file
00265       // is specified
00266       std::cerr << "Either one among the -b/--builtin and -i/--input "
00267                 << "options must be specified" << std::endl;
00268     }
00269   }
00270 
00271   if (vm.count ("output")) {
00272     ioOutputFilename = vm["output"].as< std::string >();
00273     std::cout << "Output filename is: " << ioOutputFilename << std::endl;
00274   }
00275 
00276   if (vm.count ("log")) {
00277     ioLogFilename = vm["log"].as< std::string >();
00278     std::cout << "Log filename is: " << ioLogFilename << std::endl;
00279   }
00280 
00281   if (vm.count ("demandgeneration")) {
00282     ioDemandGenerationMethod =
00283       stdair::DemandGenerationMethod (lDemandGenerationMethodChar);
00284     std::cout << "Date-time request generation method is: "
00285               << ioDemandGenerationMethod.describe() << std::endl;
00286   }
00287 
00288   //
00289   std::cout << "The random generation seed is: " << ioRandomSeed << std::endl;
00290   
00291   return 0;
00292 }
00293 
00294 // //////////////////////////////////////////////////////////////////
00295 void initReadline (swift::SReadline& ioInputReader) {
00296 
00297   // Prepare the list of my own completers
00298   std::vector<std::string> Completers;
00299 
00300   // The following is supported:
00301   // - "identifiers"
00302   // - special identifier %file - means to perform a file name completion
00303   Completers.push_back ("help");
00304   Completers.push_back ("list_event");
00305   Completers.push_back ("list_demand_stream");
00306   Completers.push_back ("reset");
00307   Completers.push_back ("generate_next_br");
00308   Completers.push_back ("generate_first_br");
00309   Completers.push_back ("generate_all_br");
00310   Completers.push_back ("next");
00311   Completers.push_back ("json_list");
00312   Completers.push_back ("quit");
00313 
00314   // Now register the completers.
00315   // Actually it is possible to re-register another set at any time
00316   ioInputReader.RegisterCompletions (Completers);
00317 }
00318 
00319 // //////////////////////////////////////////////////////////////////
00320 Command_T::Type_T extractCommand (TokenList_T& ioTokenList) {
00321   Command_T::Type_T oCommandType = Command_T::LAST_VALUE;
00322 
00323   // Interpret the user input
00324   if (ioTokenList.empty() == false) {
00325     TokenList_T::iterator itTok = ioTokenList.begin();
00326     std::string lCommand (*itTok);
00327     boost::algorithm::to_lower (lCommand);
00328     
00329     if (lCommand == "help") {
00330       oCommandType = Command_T::HELP;
00331 
00332     } else if (lCommand == "list_event") {
00333       oCommandType = Command_T::LIST_EVENT;
00334 
00335     } else if (lCommand == "list_demand_stream") {
00336       oCommandType = Command_T::LIST_DEMAND_STREAM;
00337 
00338     } else if (lCommand == "reset") {
00339       oCommandType = Command_T::RESET;
00340 
00341     } else if (lCommand == "delete_first") {
00342       oCommandType = Command_T::NEXT;
00343 
00344     } else if (lCommand == "generate_first_br") {
00345       oCommandType = Command_T::GENERATE_FIRST_BR;
00346 
00347     } else if (lCommand == "generate_next_br") {
00348       oCommandType = Command_T::GENERATE_NEXT_BR;
00349 
00350     } else if (lCommand == "generate_all_br") {
00351       oCommandType = Command_T::GENERATE_ALL_BR;
00352 
00353     } else if (lCommand == "json_list") {
00354       oCommandType = Command_T::JSON_LIST;
00355 
00356     } else if (lCommand == "quit") {
00357       oCommandType = Command_T::QUIT;
00358     }
00359 
00360     // Remove the first token (the command), as the corresponding information
00361     // has been extracted in the form of the returned command type enumeration
00362     ioTokenList.erase (itTok);
00363 
00364   } else {
00365     oCommandType = Command_T::NOP;
00366   }
00367 
00368   return oCommandType;
00369 }  
00370 
00371 // /////////////////////////////////////////////////////////
00372 std::string toString (const TokenList_T& iTokenList) {
00373   std::ostringstream oStr;
00374 
00375   // Re-create the string with all the tokens, trimmed by read-line
00376   unsigned short idx = 0;
00377   for (TokenList_T::const_iterator itTok = iTokenList.begin();
00378        itTok != iTokenList.end(); ++itTok, ++idx) {
00379     if (idx != 0) {
00380       oStr << " ";
00381     }
00382     oStr << *itTok;
00383   }
00384 
00385   return oStr.str();
00386 }
00387 
00388 // ///////// M A I N ////////////
00389 int main (int argc, char* argv[]) {
00390 
00391   // Readline history
00392   const unsigned int lHistorySize (100);
00393   const std::string lHistoryFilename ("trademgen.hist");
00394   const std::string lHistoryBackupFilename ("trademgen.hist.bak");
00395 
00396   // Default parameters for the interactive session
00397   stdair::EventStruct lCurrentInteractiveEventStruct; 
00398   stdair::DateTime_T lCurrentInteractiveDateTime; 
00399   std::string lDefaultDemandStreamKey;
00400 
00401   // State whether the BOM tree should be built-in or parsed from an input file
00402   bool isBuiltin;
00403 
00404   // Random generation seed
00405   stdair::RandomSeed_T lRandomSeed;
00406     
00407   // Input file name
00408   stdair::Filename_T lInputFilename;
00409 
00410   // Output file name
00411   stdair::Filename_T lOutputFilename;
00412 
00413   // Output log File
00414   stdair::Filename_T lLogFilename;
00415   
00416   // Demand generation method.
00417   stdair::DemandGenerationMethod
00418     lDemandGenerationMethod (K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD);
00419 
00420   // Call the command-line option parser
00421   const int lOptionParserStatus = 
00422     readConfiguration (argc, argv, isBuiltin, lRandomSeed,
00423                        lInputFilename, lOutputFilename, lLogFilename,
00424                        lDemandGenerationMethod);
00425 
00426   if (lOptionParserStatus == K_TRADEMGEN_EARLY_RETURN_STATUS) {
00427     return 0;
00428   }
00429 
00430   // Set the log parameters
00431   std::ofstream logOutputFile;
00432   // Open and clean the log outputfile
00433   logOutputFile.open (lLogFilename.c_str());
00434   logOutputFile.clear();
00435 
00436   // Set up the log parameters
00437   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00438 
00439   // Initialise the TraDemGen service object
00440   TRADEMGEN::TRADEMGEN_Service trademgenService (lLogParams, lRandomSeed);
00441 
00442   // Check wether or not a (CSV) input file should be read
00443   if (isBuiltin == true) {
00444     // Create a sample DemandStream object, and insert it within the BOM tree
00445     trademgenService.buildSampleBom();
00446     lDefaultDemandStreamKey = "SIN-BKK 2010-Feb-08 Y";
00447 
00448   } else {
00449     // Create the DemandStream objects, and insert them within the BOM tree
00450     const TRADEMGEN::DemandFilePath lDemandFilePath (lInputFilename);
00451     trademgenService.parseAndLoad (lDemandFilePath);
00452     lDefaultDemandStreamKey = "SIN-BKK 2009-Feb-09 Y";
00453   }
00454 
00455   // DEBUG
00456   STDAIR_LOG_DEBUG ("====================================================");
00457   STDAIR_LOG_DEBUG ("=       Beginning of the interactive session       =");
00458   STDAIR_LOG_DEBUG ("====================================================");
00459 
00460   // Initialise the GNU readline wrapper
00461   swift::SReadline lReader (lHistoryFilename, lHistorySize);
00462   initReadline (lReader);
00463 
00464   // Now we can ask user for a line
00465   std::string lUserInput;
00466   bool EndOfInput (false);
00467   Command_T::Type_T lCommandType (Command_T::NOP);
00468   
00469   while (lCommandType != Command_T::QUIT && EndOfInput == false) {
00470 
00471     // Update the interactive parameters which have not been updated yet
00472     //lCurrentInteractiveDateTime = lCurrentInteractiveEventStruct.getEventTime ();
00473     //lCurrentInteractiveEventType = lCurrentInteractiveEventStruct.getEventType ();
00474     
00475     // Prompt
00476     std::ostringstream oPromptStr;
00477     oPromptStr << "trademgen " << "> " ;
00478       // << stdair::EventType::getTypeLabelAsString(lCurrentInteractiveEventType)
00479       //     << " / " << lCurrentInteractiveDateTime << "> " ;
00480     // Call read-line, which will fill the list of tokens
00481     TokenList_T lTokenListByReadline;
00482     lUserInput = lReader.GetLine (oPromptStr.str(), lTokenListByReadline,
00483                                   EndOfInput);
00484 
00485     // The history can be saved to an arbitrary file at any time
00486     lReader.SaveHistory (lHistoryBackupFilename);
00487 
00488     // The end-of-input typically corresponds to a CTRL-D typed by the user
00489     if (EndOfInput) {
00490       std::cout << std::endl;
00491       break;
00492     }
00493 
00494     // Interpret the user input
00495     lCommandType = extractCommand (lTokenListByReadline);
00496 
00497     switch (lCommandType) {
00498 
00499       // ////////////////////////////// Help ////////////////////////
00500     case Command_T::HELP: {
00501       std::cout << std::endl;
00502       std::cout << "Commands: " << std::endl;
00503       std::cout << " help" << "\t\t\t" << "Display this help" << std::endl;
00504       std::cout << " quit" << "\t\t\t" << "Quit the application" << std::endl;
00505       std::cout << " list_event" << "\t\t"
00506                 << "List all the events in the queue" << std::endl;
00507       std::cout << " list_demand_stream" << "\t"
00508                 << "List the streams used to generate demand" << std::endl;
00509       std::cout << " reset" << "\t\t\t" << "Reset the service (including the "
00510                 << "event queue)" << std::endl;
00511       std::cout << " generate_first_br" << "\t" << "Generate the first booking "
00512                 << "request for each demand stream and add it to the event queue"
00513                 << std::endl;
00514       std::cout << " generate_next_br" << "\t" << "Generate the next event for "
00515                 << "the specified demand stream and add it to the event queue"
00516                 << "\n\t\t\tFor instance:"
00517                 << "\n\t\t\t  'generate_next_br " << lDefaultDemandStreamKey 
00518                 << "'" << std::endl;
00519       std::cout << " generate_all_br" << "\t" << "Generate all the events for "
00520                 << "the specified demand stream and add it to the event queue"
00521                 << "\n\t\t\tFor instance:"
00522                 << "\n\t\t\t  'generate_all_br " << lDefaultDemandStreamKey 
00523                 << "'" << std::endl;
00524       std::cout << " delete_first" << "\t\t"
00525                 << "Pop the next event from the queue"
00526                 << std::endl;
00527       std::cout << " \nDebug Commands" << std::endl;
00528       std::cout << " json_list" << "\t\t"
00529                 << "List events in the queue in a JSON format"
00530                 << std::endl;
00531       std::cout << std::endl;
00532       break;
00533     }
00534  
00535       // ////////////////////////////// Quit ////////////////////////
00536     case Command_T::QUIT: {
00537       break;
00538     }
00539 
00540       // ////////////////////////////// List /////////////////////////
00541     case Command_T::LIST_EVENT: {
00542       //
00543       std::cout << "List of events" << std::endl;   
00544 
00545       std::ostringstream oEventListStr;
00546       oEventListStr << trademgenService.list ();        
00547       std::cout << oEventListStr.str() << std::endl;   
00548       STDAIR_LOG_DEBUG (oEventListStr.str());
00549 
00550       //
00551       break;
00552     }
00553 
00554       // ////////////////////////////// List /////////////////////////
00555     case Command_T::LIST_DEMAND_STREAM: {
00556       //
00557       std::cout << "List of demand streams" << std::endl;   
00558 
00559       std::ostringstream oEventListStr;
00560       oEventListStr << trademgenService.displayDemandStream (); 
00561       std::cout << oEventListStr.str() << std::endl;   
00562       STDAIR_LOG_DEBUG (oEventListStr.str());
00563 
00564       //
00565       break;
00566     }
00567 
00568       // ////////////////////////////// Reset /////////////////////////
00569     case Command_T::RESET: {
00570 
00571       std::cout << "Reset" << std::endl;
00572 
00573       // Reset the service (including the event queue) for the next run
00574       trademgenService.reset();
00575         
00576       break;
00577     }
00578 
00579       // ////////////////////////////// Generate next request ////////////////////////
00580     case Command_T::GENERATE_NEXT_BR: {
00581 
00582       // Retrieve the corresponding demand stream key
00583       const stdair::DemandGeneratorKey_T lDemandStreamKey =
00584         toString(lTokenListByReadline);
00585 
00586       // Check that such demand stream exists
00587       const bool hasDemandStream =
00588         trademgenService.hasDemandStream(lDemandStreamKey);
00589 
00590       if (hasDemandStream == false) {
00591         // DEBUG 
00592         std::ostringstream oNoDemandStreamStr;
00593         oNoDemandStreamStr << "Wrong demand stream key: '"
00594                            << lDemandStreamKey << "'."
00595                            << "\nExisting demand streams are:\n"
00596                            << trademgenService.displayDemandStream();
00597         std::cout << oNoDemandStreamStr.str() << std::endl;
00598         STDAIR_LOG_DEBUG (oNoDemandStreamStr.str());
00599         break;
00600       }
00601       assert (hasDemandStream == true);
00602       
00603       stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
00604       const bool stillHavingRequestsToBeGenerated =
00605         trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
00606                                                            lProgressStatusSet,
00607                                                            lDemandGenerationMethod);
00608       if (stillHavingRequestsToBeGenerated == false) {
00609         // DEBUG 
00610         std::ostringstream oNoMoreEventToGenerateStr;
00611         oNoMoreEventToGenerateStr << "No more events to generate for the demand "
00612                                     << "stream: '" << lDemandStreamKey << "'.";
00613         std::cout << oNoMoreEventToGenerateStr.str() << std::endl;
00614         STDAIR_LOG_DEBUG (oNoMoreEventToGenerateStr.str());
00615         break;
00616       }
00617       assert (stillHavingRequestsToBeGenerated == true);
00618 
00619       trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
00620       
00621       // DEBUG 
00622       std::ostringstream oOneMoreEventGeneratedStr;
00623       oOneMoreEventGeneratedStr << "One more event have been generated for the demand "
00624                                 << "stream: '" << lDemandStreamKey << "'.";
00625       std::cout << oOneMoreEventGeneratedStr.str() << std::endl;
00626       STDAIR_LOG_DEBUG (oOneMoreEventGeneratedStr.str());
00627     
00628       break;
00629     }
00630 
00631       // ////////////////////////////// Generate first requests ////////////////////////
00632     case Command_T::GENERATE_FIRST_BR: {
00633 
00634       std::cout << "Generate first requests" << std::endl;
00635 
00636       // Generate the first event for each demand stream.
00637       trademgenService.generateFirstRequests (lDemandGenerationMethod);
00638 
00639       break;
00640     }
00641 
00642       // ////////////////////////////// Generate all requests ////////////////////////
00643     case Command_T::GENERATE_ALL_BR: {
00644 
00645       // Retrieve the corresponding demand stream key
00646       const stdair::DemandGeneratorKey_T lDemandStreamKey =
00647         toString(lTokenListByReadline);
00648 
00649       // Check that such demand stream exists
00650       const bool hasDemandStream =
00651         trademgenService.hasDemandStream(lDemandStreamKey);
00652 
00653       if (hasDemandStream == false) {
00654         // DEBUG 
00655         std::ostringstream oNoDemandStreamStr;
00656         oNoDemandStreamStr << "Wrong demand stream key: '"
00657                            << lDemandStreamKey << "'."
00658                            << "\nExisting demand streams are:\n"
00659                            << trademgenService.displayDemandStream();
00660         std::cout << oNoDemandStreamStr.str() << std::endl;
00661         STDAIR_LOG_DEBUG (oNoDemandStreamStr.str());
00662         break;
00663       }
00664       assert (hasDemandStream == true);
00665       
00666       stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
00667       bool stillHavingRequestsToBeGenerated =
00668         trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
00669                                                            lProgressStatusSet,
00670                                                            lDemandGenerationMethod);
00671       
00672 
00673       if (stillHavingRequestsToBeGenerated == false) {
00674         // DEBUG 
00675         std::ostringstream oNoMoreEventToGenerateStr;
00676         oNoMoreEventToGenerateStr << "No more events to generate for the demand "
00677                                     << "stream: '" << lDemandStreamKey << "'.";
00678         std::cout << oNoMoreEventToGenerateStr.str() << std::endl;
00679         STDAIR_LOG_DEBUG (oNoMoreEventToGenerateStr.str());
00680         break;
00681       }
00682       assert (stillHavingRequestsToBeGenerated == true);
00683 
00684       stdair::Count_T lNumberOfRequests = 0;
00685       while (stillHavingRequestsToBeGenerated == true) {
00686         lNumberOfRequests++;
00687         trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
00688         stillHavingRequestsToBeGenerated =
00689           trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
00690                                                              lProgressStatusSet,
00691                                                              lDemandGenerationMethod);
00692 
00693 
00694       }
00695       // DEBUG 
00696       std::ostringstream oOneMoreEventGeneratedStr;
00697       oOneMoreEventGeneratedStr << lNumberOfRequests
00698                                 << " more event(s) have been generated for the demand "
00699                                 << "stream: '" << lDemandStreamKey << "'.";
00700       std::cout << oOneMoreEventGeneratedStr.str() << std::endl;
00701       STDAIR_LOG_DEBUG (oOneMoreEventGeneratedStr.str());
00702       
00703       break;
00704     }
00705 
00706       // ////////////////////////////// Next ////////////////////////
00707     case Command_T::NEXT: {
00708       //
00709       std::cout << "Next" << std::endl;  
00710 
00711       if (trademgenService.isQueueDone() == true) { 
00712 
00713         // DEBUG 
00714         std::ostringstream oEmptyQueueStr;
00715         oEmptyQueueStr << "The event queue is empty: no event can be popped out.";
00716         std::cout << oEmptyQueueStr.str() << std::endl;   
00717         STDAIR_LOG_DEBUG (oEmptyQueueStr.str());
00718 
00719         //
00720         break;
00721 
00722       }
00723 
00724       // Get the next event from the event queue
00725       trademgenService.popEvent (lCurrentInteractiveEventStruct);
00726 
00727       // DEBUG 
00728       std::ostringstream oEventStr;
00729       oEventStr << "Poped event: '" 
00730                 << lCurrentInteractiveEventStruct.describe() << "'.";
00731       std::cout << oEventStr.str() << std::endl;
00732       STDAIR_LOG_DEBUG (oEventStr.str());
00733 
00734       //
00735       break;
00736     }     
00737       // ////////////////////////////// JSon Event List ////////////////////////
00738 
00739     case Command_T::JSON_LIST: {
00740       //
00741       std::cout << "JSON Event List" << std::endl;
00742 
00743       std::ostringstream lMyCommandJSONstream;
00744       lMyCommandJSONstream << "{\"event_list\":"
00745                            << "{ \"event_type\":\"" << "all"
00746                            << "\"}}";
00747 
00748       // Delegate the call to the dedicated service
00749       const stdair::JSONString lJSONCommandString (lMyCommandJSONstream.str());
00750       const std::string& lCSVEventListDump =
00751         trademgenService.jsonHandler (lJSONCommandString);
00752 
00753       // DEBUG: Display the events queue JSON string
00754       std::cout << lCSVEventListDump << std::endl;
00755       STDAIR_LOG_DEBUG (lCSVEventListDump);
00756 
00757       break;
00758     } 
00759 
00760       // /////////////////////////// Default / No value ///////////////////////
00761     case Command_T::NOP: {
00762       break;
00763     }
00764  
00765     case Command_T::LAST_VALUE:
00766     default: {
00767       // DEBUG
00768       std::ostringstream oStr;
00769       oStr << "That command is not yet understood: '" << lUserInput
00770            << "' => " << lTokenListByReadline;
00771       STDAIR_LOG_DEBUG (oStr.str());
00772       std::cout << oStr.str() << std::endl;
00773     }
00774     }
00775   }
00776 
00777   // DEBUG
00778   STDAIR_LOG_DEBUG ("End of the session. Exiting.");
00779   std::cout << "End of the session. Exiting." << std::endl;
00780 
00781   // Close the Log outputFile
00782   logOutputFile.close();
00783 
00784   /*
00785     Note: as that program is not intended to be run on a server in
00786     production, it is better not to catch the exceptions. When it
00787     happens (that an exception is throwned), that way we get the
00788     call stack.
00789   */
00790 
00791   return 0;     
00792 }