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

sevmgr.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 // StdAir
00018 #include <stdair/stdair_exceptions.hpp>
00019 #include <stdair/basic/BasLogParams.hpp>
00020 #include <stdair/basic/BasDBParams.hpp>
00021 #include <stdair/service/Logger.hpp>
00022 #include <stdair/bom/BookingRequestStruct.hpp>
00023 #include <stdair/bom/BookingRequestTypes.hpp>
00024 #include <stdair/basic/ProgressStatusSet.hpp>
00025 #include <stdair/bom/EventStruct.hpp>
00026 // GNU Readline Wrapper
00027 #include <stdair/ui/cmdline/SReadline.hpp>
00028 // SEvMgr
00029 #include <sevmgr/SEVMGR_Service.hpp>
00030 #include <sevmgr/config/sevmgr-paths.hpp>
00031 
00032 // //////// Constants //////
00036 const std::string K_SEVMGR_DEFAULT_LOG_FILENAME ("sevmgr.log");
00037 
00041 const int K_SEVMGR_EARLY_RETURN_STATUS = 99;
00042 
00047 typedef std::vector<std::string> TokenList_T;
00048 
00052 struct Command_T {
00053   typedef enum {
00054     NOP = 0,
00055     QUIT,
00056     HELP,
00057     LIST,
00058     DISPLAY,
00059     SELECT,
00060     NEXT,
00061     RUN,
00062     JSON_LIST,
00063     JSON_DISPLAY,
00064     LAST_VALUE
00065   } Type_T;
00066 };
00067 
00068 // ///////// Parsing of Options & Configuration /////////
00069 // A helper function to simplify the main part.
00070 template<class T> std::ostream& operator<< (std::ostream& os,
00071                                             const std::vector<T>& v) {
00072   std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 
00073   return os;
00074 }
00075 
00079 int readConfiguration (int argc, char* argv[], std::string& ioLogFilename) {
00080   // Declare a group of options that will be allowed only on command line
00081   boost::program_options::options_description generic ("Generic options");
00082   generic.add_options()
00083     ("prefix", "print installation prefix")
00084     ("version,v", "print version string")
00085     ("help,h", "produce help message");
00086     
00087   // Declare a group of options that will be allowed both on command
00088   // line and in config file
00089 
00090   boost::program_options::options_description config ("Configuration");
00091   config.add_options()
00092     ("log,l",
00093      boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_SEVMGR_DEFAULT_LOG_FILENAME),
00094      "Filename for the logs")
00095     ;
00096 
00097   // Hidden options, will be allowed both on command line and
00098   // in config file, but will not be shown to the user.
00099   boost::program_options::options_description hidden ("Hidden options");
00100   hidden.add_options()
00101     ("copyright",
00102      boost::program_options::value< std::vector<std::string> >(),
00103      "Show the copyright (license)");
00104         
00105   boost::program_options::options_description cmdline_options;
00106   cmdline_options.add(generic).add(config).add(hidden);
00107 
00108   boost::program_options::options_description config_file_options;
00109   config_file_options.add(config).add(hidden);
00110   boost::program_options::options_description visible ("Allowed options");
00111   visible.add(generic).add(config);
00112         
00113   boost::program_options::positional_options_description p;
00114   p.add ("copyright", -1);
00115         
00116   boost::program_options::variables_map vm;
00117   boost::program_options::
00118     store (boost::program_options::command_line_parser (argc, argv).
00119            options (cmdline_options).positional(p).run(), vm);
00120 
00121   std::ifstream ifs ("sevmgr.cfg");
00122   boost::program_options::store (parse_config_file (ifs, config_file_options),
00123                                  vm);
00124   boost::program_options::notify (vm);
00125     
00126   if (vm.count ("help")) {
00127     std::cout << visible << std::endl;
00128     return K_SEVMGR_EARLY_RETURN_STATUS;
00129   }
00130 
00131   if (vm.count ("version")) {
00132     std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
00133     return K_SEVMGR_EARLY_RETURN_STATUS;
00134   }
00135 
00136   if (vm.count ("prefix")) {
00137     std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
00138     return K_SEVMGR_EARLY_RETURN_STATUS;
00139   }
00140 
00141   if (vm.count ("log")) {
00142     ioLogFilename = vm["log"].as< std::string >();
00143     std::cout << "Log filename is: " << ioLogFilename << std::endl;
00144   }
00145 
00146   return 0;
00147 }
00148 
00149 // //////////////////////////////////////////////////////////////////
00150 void initReadline (swift::SReadline& ioInputReader) {
00151 
00152   // Prepare the list of my own completers
00153   std::vector<std::string> Completers;
00154 
00155   // The following is supported:
00156   // - "identifiers"
00157   // - special identifier %file - means to perform a file name completion
00158   Completers.push_back ("help");
00159   Completers.push_back ("list");  
00160   Completers.push_back ("list BookingRequest");
00161   Completers.push_back ("list BreakPoint");
00162   Completers.push_back ("select %date %time");
00163   Completers.push_back ("display");
00164   Completers.push_back ("next");
00165   Completers.push_back ("run");
00166   Completers.push_back ("json_list");
00167   Completers.push_back ("json_display");
00168   Completers.push_back ("quit");
00169 
00170 
00171   // Now register the completers.
00172   // Actually it is possible to re-register another set at any time
00173   ioInputReader.RegisterCompletions (Completers);
00174 }
00175 
00176 // //////////////////////////////////////////////////////////////////
00177 void parseEventDateTime (const TokenList_T& iTokenList,
00178                          stdair::Date_T& ioEventDate,
00179                          stdair::Duration_T& ioEventTime) {
00180   //
00181   const std::string kMonthStr[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
00182                                      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
00183   //
00184   unsigned short ioEventDateYear = ioEventDate.year();
00185   unsigned short ioEventDateMonth = ioEventDate.month();
00186   std::string ioEventDateMonthStr = kMonthStr[ioEventDateMonth-1];
00187   unsigned short ioEventDateDay = ioEventDate.day();
00188   //
00189   unsigned short ioEventTimeHours = ioEventTime.hours();
00190   unsigned short ioEventTimeMinutes = ioEventTime.minutes();
00191   unsigned short ioEventTimeSeconds = ioEventTime.seconds();
00192 
00193   // Interpret the user input
00194   if (iTokenList.empty() == false) {
00195     
00196     // Read the date year
00197     TokenList_T::const_iterator itTok = iTokenList.begin();
00198 
00199     // Read the year for the event date
00200     if (itTok != iTokenList.end()) {
00201 
00202       if (itTok->empty() == false) {
00203         try {
00204           
00205           ioEventDateYear = boost::lexical_cast<unsigned short> (*itTok);
00206           if (ioEventDateYear < 100) {
00207             ioEventDateYear += 2000;
00208           }
00209           
00210         } catch (boost::bad_lexical_cast& eCast) {
00211           std::cerr << "The year of the event date ('" << *itTok
00212                     << "') cannot be understood. The default value ("
00213                     << ioEventDateYear << ") is kept. " << std::endl;
00214           return;
00215         }
00216       }
00217       
00218     } else {
00219       return;
00220     }
00221   
00222     // Read the month for the event date
00223     ++itTok;
00224     if (itTok != iTokenList.end()) {
00225 
00226       if (itTok->empty() == false) {
00227         try {
00228 
00229           const boost::regex lMonthRegex ("^(\\d{1,2})$");
00230           const bool isMonthANumber = regex_match (*itTok, lMonthRegex);
00231         
00232           if (isMonthANumber == true) {
00233             const unsigned short lMonth =
00234               boost::lexical_cast<unsigned short> (*itTok);
00235             if (lMonth > 12) {
00236               throw boost::bad_lexical_cast();
00237             }
00238             ioEventDateMonthStr = kMonthStr[lMonth-1];
00239 
00240         } else {
00241             const std::string lMonthStr (*itTok);
00242             if (lMonthStr.size() < 3) {
00243               throw boost::bad_lexical_cast();
00244             }
00245             std::string lMonthStr1 (lMonthStr.substr (0, 1));
00246             boost::algorithm::to_upper (lMonthStr1);
00247             std::string lMonthStr23 (lMonthStr.substr (1, 2));
00248             boost::algorithm::to_lower (lMonthStr23);
00249             ioEventDateMonthStr = lMonthStr1 + lMonthStr23;
00250           }
00251 
00252         } catch (boost::bad_lexical_cast& eCast) {
00253           std::cerr << "The month of the event date ('" << *itTok
00254                     << "') cannot be understood. The default value ("
00255                     << ioEventDateMonthStr << ") is kept. " << std::endl;
00256           return;
00257         }
00258       }
00259     }
00260 
00261     // Read the day for the event date
00262     ++itTok;
00263     if (itTok != iTokenList.end()) {
00264     
00265       if (itTok->empty() == false) {
00266         try {
00267           
00268           ioEventDateDay = boost::lexical_cast<unsigned short> (*itTok);
00269 
00270         } catch (boost::bad_lexical_cast& eCast) {
00271           std::cerr << "The day of the event date ('" << *itTok
00272                     << "') cannot be understood. The default value ("
00273                     << ioEventDateDay << ") is kept. " << std::endl;
00274           return;
00275         }
00276       }
00277 
00278     } else {
00279       return;
00280     }
00281 
00282     // Re-compose the event date
00283     std::ostringstream lEventDateStr;
00284     lEventDateStr << ioEventDateYear << "-" << ioEventDateMonthStr
00285                   << "-" << ioEventDateDay;
00286 
00287     try {
00288 
00289       ioEventDate =
00290         boost::gregorian::from_simple_string (lEventDateStr.str());
00291     
00292     } catch (boost::gregorian::bad_month& eCast) {
00293       std::cerr << "The event date ('" << lEventDateStr.str()
00294                 << "') cannot be understood. The default value ("
00295                 << ioEventDate << ") is kept. " << std::endl;
00296       return;
00297     }
00298 
00299     // Read the hours of the event time
00300     ++itTok;
00301     if (itTok != iTokenList.end()) {
00302 
00303       if (itTok->empty() == false) {
00304         try {
00305           
00306           ioEventTimeHours = boost::lexical_cast<unsigned short> (*itTok);
00307           
00308         } catch (boost::bad_lexical_cast& eCast) {
00309           std::cerr << "The hours of the event time ('" << *itTok
00310                     << "') cannot be understood. The default value ("
00311                     << ioEventTimeHours << ") is kept. " << std::endl;
00312           return;
00313         }
00314       }
00315       
00316     } else {
00317       return;
00318     }
00319 
00320     // Read the minutes of the event time
00321     ++itTok;
00322     if (itTok != iTokenList.end()) {
00323 
00324       if (itTok->empty() == false) {
00325         try {
00326           
00327           ioEventTimeMinutes = boost::lexical_cast<unsigned short> (*itTok);
00328           
00329         } catch (boost::bad_lexical_cast& eCast) {
00330           std::cerr << "The minutes of the event time ('" << *itTok
00331                     << "') cannot be understood. The default value ("
00332                     << ioEventTimeMinutes << ") is kept. " << std::endl;
00333           return;
00334         }
00335       }
00336       
00337     } else {
00338       return;
00339     }
00340 
00341     // Read the seconds of the event time
00342     ++itTok;
00343     if (itTok != iTokenList.end()) {
00344 
00345       if (itTok->empty() == false) {
00346         try {
00347           
00348           ioEventTimeSeconds = boost::lexical_cast<unsigned short> (*itTok);
00349           
00350         } catch (boost::bad_lexical_cast& eCast) {
00351           std::cerr << "The seconds of the event time ('" << *itTok
00352                     << "') cannot be understood. The default value ("
00353                     << ioEventTimeSeconds << ") is kept. " << std::endl;
00354           return;
00355         }
00356       }
00357       
00358     } else {
00359       return;
00360     }
00361 
00362     // Re-compose the event time
00363     std::ostringstream lEventTimeStr;
00364     lEventTimeStr << ioEventTimeHours << ":" << ioEventTimeMinutes
00365                   << ":" << ioEventTimeSeconds;
00366 
00367     try {
00368 
00369       ioEventTime =
00370         boost::posix_time::duration_from_string (lEventTimeStr.str());
00371     
00372     } catch (boost::gregorian::bad_month& eCast) {
00373       std::cerr << "The event time ('" << lEventTimeStr.str()
00374                 << "') cannot be understood. The default value ("
00375                 << ioEventTime << ") is kept. " << std::endl;
00376       return;
00377     }
00378     
00379   }
00380  
00381 }
00382 
00383 // //////////////////////////////////////////////////////////////////
00384 Command_T::Type_T extractCommand (TokenList_T& ioTokenList) {
00385   Command_T::Type_T oCommandType = Command_T::LAST_VALUE;
00386 
00387   // Interpret the user input
00388   if (ioTokenList.empty() == false) {
00389     TokenList_T::iterator itTok = ioTokenList.begin();
00390     std::string lCommand (*itTok);
00391     boost::algorithm::to_lower (lCommand);
00392     
00393     if (lCommand == "help") {
00394       oCommandType = Command_T::HELP;
00395 
00396     } else if (lCommand == "list") {
00397       oCommandType = Command_T::LIST;
00398 
00399     } else if (lCommand == "display") {
00400       oCommandType = Command_T::DISPLAY;
00401 
00402     } else if (lCommand == "select") {
00403       oCommandType = Command_T::SELECT;
00404 
00405     } else if (lCommand == "next") {
00406       oCommandType = Command_T::NEXT;
00407 
00408     } else if (lCommand == "run") {
00409       oCommandType = Command_T::RUN;
00410 
00411     } else if (lCommand == "json_list") {
00412       oCommandType = Command_T::JSON_LIST;
00413     
00414     } else if (lCommand == "json_display") {
00415       oCommandType = Command_T::JSON_DISPLAY;
00416 
00417     } else if (lCommand == "quit") {
00418       oCommandType = Command_T::QUIT;
00419     }
00420 
00421     // Remove the first token (the command), as the corresponding information
00422     // has been extracted in the form of the returned command type enumeration
00423     ioTokenList.erase (itTok);
00424 
00425   } else {
00426     oCommandType = Command_T::NOP;
00427   }
00428 
00429   return oCommandType;
00430 }
00431 
00432 // /////////////////////////////////////////////////////////
00433 std::string toString (const TokenList_T& iTokenList) {
00434   std::ostringstream oStr;
00435 
00436   // Re-create the string with all the tokens, trimmed by read-line
00437   unsigned short idx = 0;
00438   for (TokenList_T::const_iterator itTok = iTokenList.begin();
00439        itTok != iTokenList.end(); ++itTok, ++idx) {
00440     if (idx != 0) {
00441       oStr << " ";
00442     }
00443     oStr << *itTok;
00444   }
00445 
00446   return oStr.str();
00447 }
00448 
00449 // /////////////////////////////////////////////////////////
00450 TokenList_T extractTokenList (const TokenList_T& iTokenList,
00451                               const std::string& iRegularExpression) {
00452   TokenList_T oTokenList;
00453 
00454   // Re-create the string with all the tokens (which had been trimmed
00455   // by read-line)
00456   const std::string lFullLine = toString (iTokenList);
00457 
00458   // See the caller for the regular expression
00459   boost::regex expression (iRegularExpression);
00460   
00461   std::string::const_iterator start = lFullLine.begin();
00462   std::string::const_iterator end = lFullLine.end();
00463 
00464   boost::match_results<std::string::const_iterator> what;
00465   boost::match_flag_type flags = boost::match_default | boost::format_sed; 
00466   regex_search (start, end, what, expression, flags);
00467   
00468   // Put the matched strings in the list of tokens to be returned back
00469   // to the caller
00470   const unsigned short lMatchSetSize = what.size();
00471   for (unsigned short matchIdx = 1; matchIdx != lMatchSetSize; ++matchIdx) {
00472     const std::string lMatchedString (std::string (what[matchIdx].first,
00473                                                    what[matchIdx].second));
00474     //if (lMatchedString.empty() == false) {
00475     oTokenList.push_back (lMatchedString);
00476     //}
00477   }
00478 
00479   // DEBUG
00480   // std::cout << "After (token list): " << oTokenList << std::endl;
00481 
00482   return oTokenList;
00483 }    
00484 
00485 // /////////////////////////////////////////////////////////
00486 TokenList_T extractTokenListForDateTime (const TokenList_T& iTokenList) {
00499   const std::string lRegEx("^([[:digit:]]{2,4})?[/-]?[[:space:]]*"
00500                            "([[:alpha:]]{3}|[[:digit:]]{1,2})?[/-]?[[:space:]]*"
00501                            "([[:digit:]]{1,2})?[[:space:]]*"
00502                            "([[:digit:]]{1,2})?[:-]?[[:space:]]*"
00503                            "([[:alpha:]]{3}|[[:digit:]]{1,2})?[:-]?[[:space:]]*"
00504                            "([[:digit:]]{1,2})?[[:space:]]*$");
00505 
00506   //
00507   const TokenList_T& oTokenList = extractTokenList (iTokenList, lRegEx);
00508   return oTokenList;
00509 }    
00510 
00511 // ///////// M A I N ////////////
00512 int main (int argc, char* argv[]) {
00513 
00514   // Readline history
00515   const unsigned int lHistorySize (100);
00516   const std::string lHistoryFilename ("sevmgr.hist");
00517   const std::string lHistoryBackupFilename ("sevmgr.hist.bak");  
00518 
00519   // Default parameters for the interactive session
00520   stdair::EventStruct lCurrentInteractiveEventStruct; 
00521   stdair::DateTime_T lCurrentInteractiveDateTime; 
00522   stdair::EventType::EN_EventType lCurrentInteractiveEventType;
00523 
00524   // Output log File
00525   stdair::Filename_T lLogFilename;
00526 
00527   // Call the command-line option parser
00528   const int lOptionParserStatus = readConfiguration (argc, argv, lLogFilename);
00529 
00530   if (lOptionParserStatus == K_SEVMGR_EARLY_RETURN_STATUS) {
00531     return 0;
00532   }
00533 
00534   // Set the log parameters
00535   std::ofstream logOutputFile;
00536   // Open and clean the log outputfile
00537   logOutputFile.open (lLogFilename.c_str());
00538   logOutputFile.clear();
00539 
00540   // Initialise the inventory service
00541   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00542   SEVMGR::SEVMGR_Service sevmgrService (lLogParams);
00543 
00544   // Build the sample event queue.
00545   sevmgrService.buildSampleQueue();  
00546 
00547   // Pop out the first event from the queue.
00548   sevmgrService.popEvent(lCurrentInteractiveEventStruct);
00549 
00550   // DEBUG
00551   STDAIR_LOG_DEBUG ("====================================================");
00552   STDAIR_LOG_DEBUG ("=       Beginning of the interactive session       =");
00553   STDAIR_LOG_DEBUG ("====================================================");
00554 
00555   // Initialise the GNU readline wrapper
00556   swift::SReadline lReader (lHistoryFilename, lHistorySize);
00557   initReadline (lReader);
00558 
00559   // Now we can ask user for a line
00560   std::string lUserInput;
00561   bool EndOfInput (false);
00562   Command_T::Type_T lCommandType (Command_T::NOP);
00563   
00564   while (lCommandType != Command_T::QUIT && EndOfInput == false) {  
00565 
00566     // Update the interactive parameters which have not been updated yet
00567     lCurrentInteractiveDateTime = lCurrentInteractiveEventStruct.getEventTime ();
00568     lCurrentInteractiveEventType = lCurrentInteractiveEventStruct.getEventType ();
00569 
00570     // Prompt
00571     std::ostringstream oPromptStr;
00572     oPromptStr << "sevmgr " 
00573                << stdair::EventType::getTypeLabelAsString(lCurrentInteractiveEventType)
00574                << " / " << lCurrentInteractiveDateTime << "> " ;
00575     // Call read-line, which will fill the list of tokens
00576     TokenList_T lTokenListByReadline;
00577     lUserInput = lReader.GetLine (oPromptStr.str(), lTokenListByReadline,
00578                                   EndOfInput);
00579 
00580     // The history can be saved to an arbitrary file at any time
00581     lReader.SaveHistory (lHistoryBackupFilename);
00582 
00583     // The end-of-input typically corresponds to a CTRL-D typed by the user
00584     if (EndOfInput) {
00585       std::cout << std::endl;
00586       break;
00587     }
00588 
00589     // Interpret the user input
00590     lCommandType = extractCommand (lTokenListByReadline);
00591 
00592     switch (lCommandType) {
00593 
00594       // ////////////////////////////// Help ////////////////////////
00595     case Command_T::HELP: {
00596       std::cout << std::endl;
00597       std::cout << "Commands: " << std::endl;
00598       std::cout << " help" << "\t\t" << "Display this help" << std::endl;
00599       std::cout << " quit" << "\t\t" << "Quit the application" << std::endl;
00600       std::cout << " list" << "\t\t" << "List events in the queue. It is "
00601                 << "possible to filter events according to their types" 
00602                 << std::endl    
00603                 << "\t\t\t\t  'list_event BookingRequest' "
00604                 << "list all the booking requests" << std::endl
00605                 << "\t\t\t\t  'list_event BreakPoint' "
00606                 << "list all the break points" << std::endl;
00607       std::cout << " select" << "\t\t"
00608                 << "Select an event into the 'list' to become the current one. For instance, try the command:\n"
00609                 << "\t\t  'select 2011-May-14 00:00:00'"
00610                 << std::endl;
00611       std::cout << " display" << "\t"
00612                 << "Display the current event" << std::endl;
00613       std::cout << " next" << "\t\t"
00614                 << "Play the current event and pop the next one from the queue"
00615                 << std::endl;
00616       std::cout << " run" << "\t\t"
00617                 << "Play all the events until the next break-point, if any"
00618                 << std::endl;
00619       std::cout << " \nDebug Commands" << std::endl;
00620       std::cout << " json_list" << "\t"
00621                 << "List events in the queue in a JSON format"
00622                 << std::endl;
00623       std::cout << " json_display" << "\t"
00624                 << "Display the current event in a JSON format"
00625                 << std::endl;
00626       std::cout << std::endl;
00627       break;
00628     }
00629  
00630       // ////////////////////////////// Quit ////////////////////////
00631     case Command_T::QUIT: {
00632       break;
00633     }
00634 
00635       // ////////////////////////////// List /////////////////////////
00636     case Command_T::LIST: { 
00637 
00638       //
00639       std::ostringstream oEventListStr;
00640 
00641       if (lTokenListByReadline.empty() == true) { 
00642 
00643         // If no parameter is given, list all the events in the queue
00644         oEventListStr << sevmgrService.list ();
00645 
00646       } else if (lTokenListByReadline.size() == 1) { 
00647 
00648         assert (lTokenListByReadline.empty() == false);
00649         const std::string lEventTypeStr (lTokenListByReadline[0]);
00650 
00651         // If exactly one parameter is given, try to convert it into
00652         // an event type
00653         try {
00654           
00655           const stdair::EventType lEventType (lEventTypeStr);
00656           const stdair::EventType::EN_EventType& lActualEventType =
00657             lEventType.getType();
00658           oEventListStr << sevmgrService.list (lActualEventType);       
00659           
00660         } catch (stdair::CodeConversionException e) {
00661           oEventListStr << "The event type '" << lEventTypeStr
00662                         << "' is not known. Try 'help' for "
00663                         << "more information on the 'list_event' command."
00664                         << std::endl;
00665         }
00666       } else {
00667         
00668         // If more than one parameter is given, display an error message        
00669         oEventListStr << "The event type is not understood: try 'help' for "
00670                       << "more information on the 'list_event' command."
00671                       << std::endl;
00672       } 
00673       std::cout << oEventListStr.str() << std::endl;   
00674       STDAIR_LOG_DEBUG (oEventListStr.str());
00675 
00676       //
00677       break;
00678     }
00679 
00680       // ////////////////////////////// Select ////////////////////////
00681     case Command_T::SELECT: {
00682 
00683       //
00684       TokenList_T lTokenList = extractTokenListForDateTime (lTokenListByReadline);
00685       stdair::Date_T lUserDate = lCurrentInteractiveDateTime.date();
00686       stdair::Duration_T lUserTime = lCurrentInteractiveDateTime.time_of_day();
00687       parseEventDateTime (lTokenList, lUserDate, lUserTime);
00688       
00689       std::cout << "Try to select event: "
00690                 << lUserDate << " " << lUserTime
00691                 << std::endl;
00692 
00693       const stdair::DateTime_T lUserDateTime =
00694         boost::posix_time::ptime (lUserDate, lUserTime);
00695 
00696       const bool hasSelectBeenSuccessful =
00697         sevmgrService.select (lCurrentInteractiveEventStruct,
00698                               lUserDateTime);
00699 
00700       std::cout << "Selection successful: "
00701                 << hasSelectBeenSuccessful << std::endl;
00702 
00703       //
00704       break;
00705     }
00706 
00707       // ////////////////////////////// Display ////////////////////////
00708     case Command_T::DISPLAY: {
00709       //
00710       std::cout << "Display" << std::endl;     
00711 
00712       // DEBUG 
00713       std::ostringstream oEventStr;
00714       oEventStr << lCurrentInteractiveEventStruct.describe(); 
00715       std::cout << oEventStr.str() << std::endl;
00716       STDAIR_LOG_DEBUG (oEventStr.str());
00717 
00718       //
00719       break;
00720     }
00721 
00722       // ////////////////////////////// Next ////////////////////////
00723     case Command_T::NEXT: {
00724       //
00725       std::cout << "Next" << std::endl;  
00726 
00727       if (sevmgrService.isQueueDone() == true) { 
00728 
00729         // DEBUG 
00730         std::ostringstream oEmptyQueueStr;
00731         oEmptyQueueStr << "The event queue is empty: no event can be popped out.";
00732         std::cout << oEmptyQueueStr.str() << std::endl;   
00733         STDAIR_LOG_DEBUG (oEmptyQueueStr.str());
00734 
00735         //
00736         break;
00737 
00738       }
00739 
00740       // Get the next event from the event queue
00741       stdair::ProgressStatusSet lPPS = 
00742         sevmgrService.popEvent (lCurrentInteractiveEventStruct);
00743 
00744       // DEBUG 
00745       std::ostringstream oEventStr;
00746       oEventStr << "Poped event: '" 
00747                 << lCurrentInteractiveEventStruct.describe() << "'.";
00748       std::cout << oEventStr.str() << std::endl;
00749       STDAIR_LOG_DEBUG (oEventStr.str());
00750 
00751       //
00752       break;
00753     }     
00754 
00755       // ////////////////////////////// Run ////////////////////////
00756     case Command_T::RUN: {
00757       //
00758       std::cout << "Run" << std::endl;
00759 
00760       // Delegate the call to the dedicated service
00761       sevmgrService.run (lCurrentInteractiveEventStruct);
00762       lCurrentInteractiveEventType = lCurrentInteractiveEventStruct.getEventType ();
00763 
00764       // DEBUG 
00765       if (lCurrentInteractiveEventType == stdair::EventType::BRK_PT) {
00766         std::ostringstream oBreakPointStr;
00767         oBreakPointStr << "Break point found. Stop at: '" 
00768                        << lCurrentInteractiveEventStruct.describe() << "'.";
00769         std::cout << oBreakPointStr.str() << std::endl;
00770         STDAIR_LOG_DEBUG (oBreakPointStr.str());
00771       } else {
00772         std::ostringstream oNoBreakPointStr;
00773         oNoBreakPointStr << "No break point found. All the events have been played.\n"
00774                          << "The current event is the last one.";
00775         std::cout << oNoBreakPointStr.str() << std::endl;
00776         STDAIR_LOG_DEBUG (oNoBreakPointStr.str());
00777       }
00778                 
00779       //
00780       break;
00781     }     
00782 
00783       // ////////////////////////////// JSon List ////////////////////////
00784 
00785     case Command_T::JSON_LIST: { 
00786       //
00787       std::cout << "JSON List" << std::endl;
00788 
00789       // Delegate the call to the dedicated service
00790       const std::string& lCSVEventQueueDumpAfter =
00791         sevmgrService.jsonExportEventQueue ();
00792 
00793       // DEBUG: Display the events queue JSON string
00794       std::cout << lCSVEventQueueDumpAfter << std::endl;
00795       STDAIR_LOG_DEBUG (lCSVEventQueueDumpAfter);
00796       
00797       break;
00798     } 
00799 
00800       // ////////////////////////////// JSon Display ////////////////////////
00801 
00802     case Command_T::JSON_DISPLAY: {      
00803       //
00804       std::cout << "JSON Display" << std::endl; 
00805 
00806       // Delegate the call to the dedicated service
00807       const std::string& lCSVEventDumpAfter =
00808         sevmgrService.jsonExportEvent (lCurrentInteractiveEventStruct);
00809 
00810       // DEBUG: Display the event JSON string
00811       std::cout << lCSVEventDumpAfter << std::endl;
00812       STDAIR_LOG_DEBUG (lCSVEventDumpAfter);
00813 
00814       //
00815       break;
00816     }
00817 
00818       // /////////////////////////// Default / No value ///////////////////////
00819     case Command_T::NOP: {
00820       break;
00821     }
00822  
00823     case Command_T::LAST_VALUE:
00824     default: {
00825       // DEBUG
00826       std::ostringstream oStr;
00827       oStr << "That command is not yet understood: '" << lUserInput
00828            << "' => " << lTokenListByReadline;
00829       STDAIR_LOG_DEBUG (oStr.str());
00830       std::cout << oStr.str() << std::endl;
00831     }
00832     }
00833   }
00834 
00835   // DEBUG
00836   STDAIR_LOG_DEBUG ("End of the session. Exiting.");
00837   std::cout << "End of the session. Exiting." << std::endl;
00838 
00839   // Close the Log outputFile
00840   logOutputFile.close();
00841 
00842   /*
00843     Note: as that program is not intended to be run on a server in
00844     production, it is better not to catch the exceptions. When it
00845     happens (that an exception is throwned), that way we get the
00846     call stack.
00847   */
00848 
00849   return 0;     
00850 }