TraDemGen Logo  1.00.0
C++ Simulated Travel Demand Generation Library
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
trademgen.cpp
Go to the documentation of this file.
1 
5 // STL
6 #include <cassert>
7 #include <iostream>
8 #include <sstream>
9 #include <fstream>
10 #include <string>
11 // Boost (Extended STL)
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>
17 // GNU Readline Wrapper
18 #include <stdair/ui/cmdline/SReadline.hpp>
19 // StdAir
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>
29 // TraDemGen
31 #include <trademgen/config/trademgen-paths.hpp>
32 
33 
34 // //////// Type definitions ///////
38 typedef std::vector<std::string> WordList_T;
39 
40 // //////// Specific type definitions ///////
41 typedef unsigned int NbOfRuns_T;
42 
43 // //////// Constants //////
47 const stdair::Filename_T K_TRADEMGEN_DEFAULT_LOG_FILENAME ("trademgen.log");
48 
52 const stdair::Filename_T K_TRADEMGEN_DEFAULT_INPUT_FILENAME (STDAIR_SAMPLE_DIR
53  "/rds01/demand05.csv");
54 
58 const stdair::DemandGenerationMethod
60  stdair::DemandGenerationMethod::POI_PRO;
61 
67 
71 const stdair::RandomSeed_T K_TRADEMGEN_DEFAULT_RANDOM_SEED =
72  stdair::DEFAULT_RANDOM_SEED;
73 
78 
83 const bool K_TRADEMGEN_DEFAULT_BUILT_IN_INPUT = false;
84 
88 const int K_TRADEMGEN_EARLY_RETURN_STATUS = 99;
89 
90 // //////////////////////////////////////////////////////////////////////
95 typedef std::vector<std::string> TokenList_T;
96 
100 struct Command_T {
101  typedef enum {
102  NOP = 0,
103  QUIT,
104  HELP,
105  LIST_EVENT,
106  LIST_DEMAND_STREAM,
107  RESET,
108  NEXT,
109  GENERATE_NEXT_BR,
110  GENERATE_FIRST_BR,
111  GENERATE_ALL_BR,
112  JSON_LIST,
113  LAST_VALUE
114  } Type_T;
115 };
116 
117 // //////////////////////////////////////////////////////////////////////
118 void tokeniseStringIntoWordList (const std::string& iPhrase,
119  WordList_T& ioWordList) {
120  // Empty the word list
121  ioWordList.clear();
122 
123  // Boost Tokeniser
124  typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
125 
126  // Define the separators
127  const boost::char_separator<char> lSepatorList(" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
128 
129  // Initialise the phrase to be tokenised
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);
135  }
136 
137 }// //////////////////////////////////////////////////////////////////////
138 std::string createStringFromWordList (const WordList_T& iWordList) {
139  std::ostringstream oStr;
140 
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;
145  oStr << lWord;
146  if (idx > 1) {
147  oStr << " ";
148  }
149  }
150 
151  return oStr.str();
152 }
153 
154 
155 // ///////// Parsing of Options & Configuration /////////
156 // A helper function to simplify the main part.
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, " "));
160  return os;
161 }
165 int readConfiguration (int argc, char* argv[], bool& ioIsBuiltin,
166  stdair::RandomSeed_T& ioRandomSeed,
167  stdair::Filename_T& ioInputFilename,
168  stdair::Filename_T& ioOutputFilename,
169  stdair::Filename_T& ioLogFilename,
170  stdair::DemandGenerationMethod& ioDemandGenerationMethod) {
171 
172  // Demand generation method as a single char (e.g., 'P' or 'S').
173  char lDemandGenerationMethodChar;
174 
175  // Default for the built-in input
177 
178  // Declare a group of options that will be allowed only on command line
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");
184 
185  // Declare a group of options that will be allowed both on command
186  // line and in config file
187  boost::program_options::options_description config ("Configuration");
188  config.add_options()
189  ("builtin,b",
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")
191  ("seed,s",
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",
195  boost::program_options::value< char >(&lDemandGenerationMethodChar)->default_value(K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD_CHAR),
196  "Method used to generate the demand (i.e., the booking requests): Poisson Process (P) or Order Statistics (S)")
197  ("input,i",
198  boost::program_options::value< std::string >(&ioInputFilename)->default_value(K_TRADEMGEN_DEFAULT_INPUT_FILENAME),
199  "(CSV) input file for the demand distributions")
200  ("log,l",
201  boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_TRADEMGEN_DEFAULT_LOG_FILENAME),
202  "Filepath for the logs")
203  ;
204 
205  // Hidden options, will be allowed both on command line and
206  // in config file, but will not be shown to the user.
207  boost::program_options::options_description hidden ("Hidden options");
208  hidden.add_options()
209  ("copyright",
210  boost::program_options::value< std::vector<std::string> >(),
211  "Show the copyright (license)");
212 
213  boost::program_options::options_description cmdline_options;
214  cmdline_options.add(generic).add(config).add(hidden);
215 
216  boost::program_options::options_description config_file_options;
217  config_file_options.add(config).add(hidden);
218 
219  boost::program_options::options_description visible ("Allowed options");
220  visible.add(generic).add(config);
221 
222  boost::program_options::positional_options_description p;
223  p.add ("copyright", -1);
224 
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);
229 
230  std::ifstream ifs ("trademgen.cfg");
231  boost::program_options::store (parse_config_file (ifs, config_file_options),
232  vm);
233  boost::program_options::notify (vm);
234 
235  if (vm.count ("help")) {
236  std::cout << visible << std::endl;
238  }
239 
240  if (vm.count ("version")) {
241  std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
243  }
244 
245  if (vm.count ("prefix")) {
246  std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
248  }
249 
250  if (vm.count ("builtin")) {
251  ioIsBuiltin = true;
252  }
253  const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
254  std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
255 
256  if (ioIsBuiltin == false) {
257 
258  // The BOM tree should be built from parsing a demand input file
259  if (vm.count ("input")) {
260  ioInputFilename = vm["input"].as< std::string >();
261  std::cout << "Input filename is: " << ioInputFilename << std::endl;
262 
263  } else {
264  // The built-in option is not selected. However, no demand input file
265  // is specified
266  std::cerr << "Either one among the -b/--builtin and -i/--input "
267  << "options must be specified" << std::endl;
268  }
269  }
270 
271  if (vm.count ("output")) {
272  ioOutputFilename = vm["output"].as< std::string >();
273  std::cout << "Output filename is: " << ioOutputFilename << std::endl;
274  }
275 
276  if (vm.count ("log")) {
277  ioLogFilename = vm["log"].as< std::string >();
278  std::cout << "Log filename is: " << ioLogFilename << std::endl;
279  }
280 
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;
286  }
287 
288  //
289  std::cout << "The random generation seed is: " << ioRandomSeed << std::endl;
290 
291  return 0;
292 }
293 
294 // //////////////////////////////////////////////////////////////////
295 void initReadline (swift::SReadline& ioInputReader) {
296 
297  // Prepare the list of my own completers
298  std::vector<std::string> Completers;
299 
300  // The following is supported:
301  // - "identifiers"
302  // - special identifier %file - means to perform a file name completion
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");
313 
314  // Now register the completers.
315  // Actually it is possible to re-register another set at any time
316  ioInputReader.RegisterCompletions (Completers);
317 }
318 
319 // //////////////////////////////////////////////////////////////////
320 Command_T::Type_T extractCommand (TokenList_T& ioTokenList) {
321  Command_T::Type_T oCommandType = Command_T::LAST_VALUE;
322 
323  // Interpret the user input
324  if (ioTokenList.empty() == false) {
325  TokenList_T::iterator itTok = ioTokenList.begin();
326  std::string lCommand (*itTok);
327  boost::algorithm::to_lower (lCommand);
328 
329  if (lCommand == "help") {
330  oCommandType = Command_T::HELP;
331 
332  } else if (lCommand == "list_event") {
333  oCommandType = Command_T::LIST_EVENT;
334 
335  } else if (lCommand == "list_demand_stream") {
336  oCommandType = Command_T::LIST_DEMAND_STREAM;
337 
338  } else if (lCommand == "reset") {
339  oCommandType = Command_T::RESET;
340 
341  } else if (lCommand == "delete_first") {
342  oCommandType = Command_T::NEXT;
343 
344  } else if (lCommand == "generate_first_br") {
345  oCommandType = Command_T::GENERATE_FIRST_BR;
346 
347  } else if (lCommand == "generate_next_br") {
348  oCommandType = Command_T::GENERATE_NEXT_BR;
349 
350  } else if (lCommand == "generate_all_br") {
351  oCommandType = Command_T::GENERATE_ALL_BR;
352 
353  } else if (lCommand == "json_list") {
354  oCommandType = Command_T::JSON_LIST;
355 
356  } else if (lCommand == "quit") {
357  oCommandType = Command_T::QUIT;
358  }
359 
360  // Remove the first token (the command), as the corresponding information
361  // has been extracted in the form of the returned command type enumeration
362  ioTokenList.erase (itTok);
363 
364  } else {
365  oCommandType = Command_T::NOP;
366  }
367 
368  return oCommandType;
369 }
370 
371 // /////////////////////////////////////////////////////////
372 std::string toString (const TokenList_T& iTokenList) {
373  std::ostringstream oStr;
374 
375  // Re-create the string with all the tokens, trimmed by read-line
376  unsigned short idx = 0;
377  for (TokenList_T::const_iterator itTok = iTokenList.begin();
378  itTok != iTokenList.end(); ++itTok, ++idx) {
379  if (idx != 0) {
380  oStr << " ";
381  }
382  oStr << *itTok;
383  }
384 
385  return oStr.str();
386 }
387 
388 // ///////// M A I N ////////////
389 int main (int argc, char* argv[]) {
390 
391  // Readline history
392  const unsigned int lHistorySize (100);
393  const std::string lHistoryFilename ("trademgen.hist");
394  const std::string lHistoryBackupFilename ("trademgen.hist.bak");
395 
396  // Default parameters for the interactive session
397  stdair::EventStruct lCurrentInteractiveEventStruct;
398  stdair::DateTime_T lCurrentInteractiveDateTime;
399  std::string lDefaultDemandStreamKey;
400 
401  // State whether the BOM tree should be built-in or parsed from an input file
402  bool isBuiltin;
403 
404  // Random generation seed
405  stdair::RandomSeed_T lRandomSeed;
406 
407  // Input file name
408  stdair::Filename_T lInputFilename;
409 
410  // Output file name
411  stdair::Filename_T lOutputFilename;
412 
413  // Output log File
414  stdair::Filename_T lLogFilename;
415 
416  // Demand generation method.
417  stdair::DemandGenerationMethod
418  lDemandGenerationMethod (K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD);
419 
420  // Call the command-line option parser
421  const int lOptionParserStatus =
422  readConfiguration (argc, argv, isBuiltin, lRandomSeed,
423  lInputFilename, lOutputFilename, lLogFilename,
424  lDemandGenerationMethod);
425 
426  if (lOptionParserStatus == K_TRADEMGEN_EARLY_RETURN_STATUS) {
427  return 0;
428  }
429 
430  // Set the log parameters
431  std::ofstream logOutputFile;
432  // Open and clean the log outputfile
433  logOutputFile.open (lLogFilename.c_str());
434  logOutputFile.clear();
435 
436  // Set up the log parameters
437  const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
438 
439  // Initialise the TraDemGen service object
440  TRADEMGEN::TRADEMGEN_Service trademgenService (lLogParams, lRandomSeed);
441 
442  // Check wether or not a (CSV) input file should be read
443  if (isBuiltin == true) {
444  // Create a sample DemandStream object, and insert it within the BOM tree
445  trademgenService.buildSampleBom();
446  lDefaultDemandStreamKey = "SIN-BKK 2010-Feb-08 Y";
447 
448  } else {
449  // Create the DemandStream objects, and insert them within the BOM tree
450  const TRADEMGEN::DemandFilePath lDemandFilePath (lInputFilename);
451  trademgenService.parseAndLoad (lDemandFilePath);
452  lDefaultDemandStreamKey = "SIN-BKK 2009-Feb-09 Y";
453  }
454 
455  // DEBUG
456  STDAIR_LOG_DEBUG ("====================================================");
457  STDAIR_LOG_DEBUG ("= Beginning of the interactive session =");
458  STDAIR_LOG_DEBUG ("====================================================");
459 
460  // Initialise the GNU readline wrapper
461  swift::SReadline lReader (lHistoryFilename, lHistorySize);
462  initReadline (lReader);
463 
464  // Now we can ask user for a line
465  std::string lUserInput;
466  bool EndOfInput (false);
467  Command_T::Type_T lCommandType (Command_T::NOP);
468 
469  while (lCommandType != Command_T::QUIT && EndOfInput == false) {
470 
471  // Update the interactive parameters which have not been updated yet
472  //lCurrentInteractiveDateTime = lCurrentInteractiveEventStruct.getEventTime ();
473  //lCurrentInteractiveEventType = lCurrentInteractiveEventStruct.getEventType ();
474 
475  // Prompt
476  std::ostringstream oPromptStr;
477  oPromptStr << "trademgen " << "> " ;
478  // << stdair::EventType::getTypeLabelAsString(lCurrentInteractiveEventType)
479  // << " / " << lCurrentInteractiveDateTime << "> " ;
480  // Call read-line, which will fill the list of tokens
481  TokenList_T lTokenListByReadline;
482  lUserInput = lReader.GetLine (oPromptStr.str(), lTokenListByReadline,
483  EndOfInput);
484 
485  // The history can be saved to an arbitrary file at any time
486  lReader.SaveHistory (lHistoryBackupFilename);
487 
488  // The end-of-input typically corresponds to a CTRL-D typed by the user
489  if (EndOfInput) {
490  std::cout << std::endl;
491  break;
492  }
493 
494  // Interpret the user input
495  lCommandType = extractCommand (lTokenListByReadline);
496 
497  switch (lCommandType) {
498 
499  // ////////////////////////////// Help ////////////////////////
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"
513  << std::endl;
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
518  << "'" << std::endl;
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
523  << "'" << std::endl;
524  std::cout << " delete_first" << "\t\t"
525  << "Pop the next event from the queue"
526  << std::endl;
527  std::cout << " \nDebug Commands" << std::endl;
528  std::cout << " json_list" << "\t\t"
529  << "List events in the queue in a JSON format"
530  << std::endl;
531  std::cout << std::endl;
532  break;
533  }
534 
535  // ////////////////////////////// Quit ////////////////////////
536  case Command_T::QUIT: {
537  break;
538  }
539 
540  // ////////////////////////////// List /////////////////////////
541  case Command_T::LIST_EVENT: {
542  //
543  std::cout << "List of events" << std::endl;
544 
545  std::ostringstream oEventListStr;
546  oEventListStr << trademgenService.list ();
547  std::cout << oEventListStr.str() << std::endl;
548  STDAIR_LOG_DEBUG (oEventListStr.str());
549 
550  //
551  break;
552  }
553 
554  // ////////////////////////////// List /////////////////////////
555  case Command_T::LIST_DEMAND_STREAM: {
556  //
557  std::cout << "List of demand streams" << std::endl;
558 
559  std::ostringstream oEventListStr;
560  oEventListStr << trademgenService.displayDemandStream ();
561  std::cout << oEventListStr.str() << std::endl;
562  STDAIR_LOG_DEBUG (oEventListStr.str());
563 
564  //
565  break;
566  }
567 
568  // ////////////////////////////// Reset /////////////////////////
569  case Command_T::RESET: {
570 
571  std::cout << "Reset" << std::endl;
572 
573  // Reset the service (including the event queue) for the next run
574  trademgenService.reset();
575 
576  break;
577  }
578 
579  // ////////////////////////////// Generate next request ////////////////////////
580  case Command_T::GENERATE_NEXT_BR: {
581 
582  // Retrieve the corresponding demand stream key
583  const stdair::DemandGeneratorKey_T lDemandStreamKey =
584  toString(lTokenListByReadline);
585 
586  // Check that such demand stream exists
587  const bool hasDemandStream =
588  trademgenService.hasDemandStream(lDemandStreamKey);
589 
590  if (hasDemandStream == false) {
591  // DEBUG
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());
599  break;
600  }
601  assert (hasDemandStream == true);
602 
603  stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
604  const bool stillHavingRequestsToBeGenerated =
605  trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
606  lProgressStatusSet,
607  lDemandGenerationMethod);
608  if (stillHavingRequestsToBeGenerated == false) {
609  // DEBUG
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());
615  break;
616  }
617  assert (stillHavingRequestsToBeGenerated == true);
618 
619  trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
620 
621  // DEBUG
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());
627 
628  break;
629  }
630 
631  // ////////////////////////////// Generate first requests ////////////////////////
632  case Command_T::GENERATE_FIRST_BR: {
633 
634  std::cout << "Generate first requests" << std::endl;
635 
636  // Generate the first event for each demand stream.
637  trademgenService.generateFirstRequests (lDemandGenerationMethod);
638 
639  break;
640  }
641 
642  // ////////////////////////////// Generate all requests ////////////////////////
643  case Command_T::GENERATE_ALL_BR: {
644 
645  // Retrieve the corresponding demand stream key
646  const stdair::DemandGeneratorKey_T lDemandStreamKey =
647  toString(lTokenListByReadline);
648 
649  // Check that such demand stream exists
650  const bool hasDemandStream =
651  trademgenService.hasDemandStream(lDemandStreamKey);
652 
653  if (hasDemandStream == false) {
654  // DEBUG
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());
662  break;
663  }
664  assert (hasDemandStream == true);
665 
666  stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
667  bool stillHavingRequestsToBeGenerated =
668  trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
669  lProgressStatusSet,
670  lDemandGenerationMethod);
671 
672 
673  if (stillHavingRequestsToBeGenerated == false) {
674  // DEBUG
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());
680  break;
681  }
682  assert (stillHavingRequestsToBeGenerated == true);
683 
684  stdair::Count_T lNumberOfRequests = 0;
685  while (stillHavingRequestsToBeGenerated == true) {
686  lNumberOfRequests++;
687  trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
688  stillHavingRequestsToBeGenerated =
689  trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
690  lProgressStatusSet,
691  lDemandGenerationMethod);
692 
693 
694  }
695  // DEBUG
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());
702 
703  break;
704  }
705 
706  // ////////////////////////////// Next ////////////////////////
707  case Command_T::NEXT: {
708  //
709  std::cout << "Next" << std::endl;
710 
711  if (trademgenService.isQueueDone() == true) {
712 
713  // DEBUG
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());
718 
719  //
720  break;
721 
722  }
723 
724  // Get the next event from the event queue
725  trademgenService.popEvent (lCurrentInteractiveEventStruct);
726 
727  // DEBUG
728  std::ostringstream oEventStr;
729  oEventStr << "Poped event: '"
730  << lCurrentInteractiveEventStruct.describe() << "'.";
731  std::cout << oEventStr.str() << std::endl;
732  STDAIR_LOG_DEBUG (oEventStr.str());
733 
734  //
735  break;
736  }
737  // ////////////////////////////// JSon Event List ////////////////////////
738 
739  case Command_T::JSON_LIST: {
740  //
741  std::cout << "JSON Event List" << std::endl;
742 
743  std::ostringstream lMyCommandJSONstream;
744  lMyCommandJSONstream << "{\"event_list\":"
745  << "{ \"event_type\":\"" << "all"
746  << "\"}}";
747 
748  // Delegate the call to the dedicated service
749  const stdair::JSONString lJSONCommandString (lMyCommandJSONstream.str());
750  const std::string& lCSVEventListDump =
751  trademgenService.jsonHandler (lJSONCommandString);
752 
753  // DEBUG: Display the events queue JSON string
754  std::cout << lCSVEventListDump << std::endl;
755  STDAIR_LOG_DEBUG (lCSVEventListDump);
756 
757  break;
758  }
759 
760  // /////////////////////////// Default / No value ///////////////////////
761  case Command_T::NOP: {
762  break;
763  }
764 
765  case Command_T::LAST_VALUE:
766  default: {
767  // DEBUG
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;
773  }
774  }
775  }
776 
777  // DEBUG
778  STDAIR_LOG_DEBUG ("End of the session. Exiting.");
779  std::cout << "End of the session. Exiting." << std::endl;
780 
781  // Close the Log outputFile
782  logOutputFile.close();
783 
784  /*
785  Note: as that program is not intended to be run on a server in
786  production, it is better not to catch the exceptions. When it
787  happens (that an exception is throwned), that way we get the
788  call stack.
789  */
790 
791  return 0;
792 }