TravelCCM Logo  0.5.2
C++ Travel Customer Choice Model Library
travelccm.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 // StdAir
00014 #include <stdair/basic/BasLogParams.hpp>
00015 #include <stdair/basic/BasDBParams.hpp>
00016 #include <stdair/bom/BookingRequestStruct.hpp>
00017 #include <stdair/bom/TravelSolutionStruct.hpp>
00018 #include <stdair/service/Logger.hpp>
00019 // TravelCCM
00020 #include <travelccm/TRAVELCCM_Service.hpp>
00021 #include <travelccm/config/travelccm-paths.hpp>
00022 
00023 // //////// Constants //////
00027 const std::string K_TRAVELCCM_DEFAULT_LOG_FILENAME ("travelccm.log");
00028 
00032 const std::string K_TRAVELCCM_DEFAULT_INPUT_FILENAME (STDAIR_SAMPLE_DIR
00033                                                       "/ccm_01.csv");
00034 
00039 const bool K_TRAVELCCM_DEFAULT_BUILT_IN_INPUT = false;
00040 
00044 const int K_TRAVELCCM_EARLY_RETURN_STATUS = 99;
00045 
00046 
00047 // ///////// Parsing of Options & Configuration /////////
00048 // A helper function to simplify the main part.
00049 template<class T> std::ostream& operator<< (std::ostream& os,
00050                                             const std::vector<T>& v) {
00051   std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 
00052   return os;
00053 }
00054 
00058 int readConfiguration (int argc, char* argv[], bool& ioIsBuiltin,
00059                        stdair::Filename_T& lInputFilename,
00060                        stdair::Filename_T& lLogFilename) {
00061   
00062   // Default for the built-in input
00063   ioIsBuiltin = K_TRAVELCCM_DEFAULT_BUILT_IN_INPUT;
00064     
00065   // Declare a group of options that will be allowed only on command line
00066   boost::program_options::options_description generic ("Generic options");
00067   generic.add_options()
00068     ("prefix", "print installation prefix")
00069     ("version,v", "print version string")
00070     ("help,h", "produce help message");
00071     
00072   // Declare a group of options that will be allowed both on command
00073   // line and in config file
00074   boost::program_options::options_description config ("Configuration");
00075   config.add_options()
00076     ("builtin,b",
00077      "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")
00078     ("input,i",
00079      boost::program_options::value< std::string >(&lInputFilename)->default_value(K_TRAVELCCM_DEFAULT_INPUT_FILENAME),
00080      "(CSV) input file for the customer choice rule sets")
00081     ("log,l",
00082      boost::program_options::value< std::string >(&lLogFilename)->default_value(K_TRAVELCCM_DEFAULT_LOG_FILENAME),
00083      "Filename for the logs")
00084     ;
00085 
00086   // Hidden options, will be allowed both on command line and
00087   // in config file, but will not be shown to the user.
00088   boost::program_options::options_description hidden ("Hidden options");
00089   hidden.add_options()
00090     ("copyright",
00091      boost::program_options::value< std::vector<std::string> >(),
00092      "Show the copyright (license)");
00093         
00094   boost::program_options::options_description cmdline_options;
00095   cmdline_options.add(generic).add(config).add(hidden);
00096 
00097   boost::program_options::options_description config_file_options;
00098   config_file_options.add(config).add(hidden);
00099 
00100   boost::program_options::options_description visible ("Allowed options");
00101   visible.add(generic).add(config);
00102         
00103   boost::program_options::positional_options_description p;
00104   p.add ("copyright", -1);
00105         
00106   boost::program_options::variables_map vm;
00107   boost::program_options::
00108     store (boost::program_options::command_line_parser (argc, argv).
00109            options (cmdline_options).positional(p).run(), vm);
00110 
00111   std::ifstream ifs ("travelccm.cfg");
00112   boost::program_options::store (parse_config_file (ifs, config_file_options),
00113                                  vm);
00114   boost::program_options::notify (vm);
00115     
00116   if (vm.count ("help")) {
00117     std::cout << visible << std::endl;
00118     return K_TRAVELCCM_EARLY_RETURN_STATUS;
00119   }
00120 
00121   if (vm.count ("version")) {
00122     std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
00123     return K_TRAVELCCM_EARLY_RETURN_STATUS;
00124   }
00125 
00126   if (vm.count ("prefix")) {
00127     std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
00128     return K_TRAVELCCM_EARLY_RETURN_STATUS;
00129   }
00130 
00131   if (vm.count ("builtin")) {
00132     ioIsBuiltin = true;
00133   }
00134   const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
00135   std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
00136 
00137   if (ioIsBuiltin == false) {
00138 
00139     // The BOM tree should be built from parsing a customer-choice rule file
00140     if (vm.count ("input")) {
00141       lInputFilename = vm["input"].as< std::string >();
00142       std::cout << "Input filename is: " << lInputFilename << std::endl;
00143 
00144     } else {
00145       // The built-in option is not selected. However, no demand input file
00146       // is specified
00147       std::cerr << "Either one among the -b/--builtin and -i/--input "
00148                 << "options must be specified" << std::endl;
00149     }
00150   }
00151 
00152   if (vm.count ("log")) {
00153     lLogFilename = vm["log"].as< std::string >();
00154     std::cout << "Log filename is: " << lLogFilename << std::endl;
00155   }
00156   
00157   return 0;
00158 }
00159 
00160 
00161 // ///////// M A I N ////////////
00162 int main (int argc, char* argv[]) {
00163     
00164   // State whether the BOM tree should be built-in or parsed from an input file
00165   bool isBuiltin;
00166 
00167   // Input file name
00168   stdair::Filename_T lInputFilename;
00169   
00170   // Output log File
00171   stdair::Filename_T lLogFilename;
00172   
00173   // Call the command-line option parser
00174   const int lOptionParserStatus = 
00175     readConfiguration (argc, argv, isBuiltin, lInputFilename, lLogFilename);
00176   
00177   if (lOptionParserStatus == K_TRAVELCCM_EARLY_RETURN_STATUS) {
00178     return 0;
00179   }
00180   
00181   // Set the log parameters
00182   std::ofstream logOutputFile;
00183   // Open and clean the log outputfile
00184   logOutputFile.open (lLogFilename.c_str());
00185   logOutputFile.clear();
00186   
00187   // Initialise the service context
00188   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00189   
00190   // Build the BOM tree
00191   TRAVELCCM::TRAVELCCM_Service travelccmService (lLogParams);
00192 
00193   // DEBUG
00194   STDAIR_LOG_DEBUG ("Welcome to TravelCCM");
00195 
00196   // Check wether or not a (CSV) input file should be read
00197   if (isBuiltin == true) {
00198     // Create a sample Customer-Choice rule object, and insert it
00199     // within the BOM tree
00200     travelccmService.buildSampleBom();
00201 
00202   } else {
00209     // travelccmService.parseAndLoad (lInputFilename);
00210   }  
00211 
00212   // Build a list of travel solutions
00213   const stdair::BookingRequestStruct& lBookingRequest =
00214     travelccmService.buildSampleBookingRequest();
00215 
00216   // DEBUG
00217   STDAIR_LOG_DEBUG ("Booking request: " << lBookingRequest.display());
00218 
00219   // Build the sample BOM tree
00220   stdair::TravelSolutionList_T lTSList;
00221   travelccmService.buildSampleTravelSolutions (lTSList);
00222 
00223   // DEBUG: Display the list of travel solutions
00224   const std::string& lCSVDump = travelccmService.csvDisplay (lTSList);
00225   STDAIR_LOG_DEBUG (lCSVDump);
00226   
00227   // Choose a travel solution
00228   const stdair::TravelSolutionStruct* lTS_ptr =
00229     travelccmService.chooseTravelSolution (lTSList, lBookingRequest);
00230 
00231   if (lTS_ptr != NULL) {
00232     // DEBUG
00233     STDAIR_LOG_DEBUG ("Chosen travel solution: " << lTS_ptr->display());
00234 
00235   } else {
00236     // DEBUG
00237     STDAIR_LOG_DEBUG ("No travel solution can be found for "
00238                       << lBookingRequest.display()
00239                       << " within the following list of travel solutions");
00240     STDAIR_LOG_DEBUG (lCSVDump);
00241   }
00242 
00243   // Close the Log outputFile
00244   logOutputFile.close();
00245 
00253   return 0;     
00254 }