SimFQT Logo  0.1.3
C++ Simulated Fare Quote System Library
simfqt_parseFareRules.cpp
Go to the documentation of this file.
00001 // STL
00002 #include <cassert>
00003 #include <iostream>
00004 #include <sstream>
00005 #include <fstream>
00006 #include <vector>
00007 #include <list>
00008 #include <string>
00009 // Boost (Extended STL)
00010 #include <boost/date_time/posix_time/posix_time.hpp>
00011 #include <boost/date_time/gregorian/gregorian.hpp>
00012 #include <boost/tokenizer.hpp>
00013 #include <boost/program_options.hpp>
00014 // StdAir
00015 #include <stdair/STDAIR_Service.hpp>
00016 #include <stdair/bom/TravelSolutionStruct.hpp>
00017 #include <stdair/bom/BookingRequestStruct.hpp>
00018 #include <stdair/service/Logger.hpp>
00019 // Simfqt
00020 #include <simfqt/SIMFQT_Service.hpp>
00021 #include <simfqt/config/simfqt-paths.hpp>
00022 
00023 // //////// Type definitions ///////
00024 typedef std::vector<std::string> WordList_T;
00025 
00026 
00027 // //////// Constants //////
00029 const std::string K_SIMFQT_DEFAULT_LOG_FILENAME ("simfqt_parseFareRules.log");
00030 
00032 const std::string K_SIMFQT_DEFAULT_FARE_INPUT_FILENAME (STDAIR_SAMPLE_DIR
00033                                                          "/fare01.csv");
00034 
00037 const bool K_SIMFQT_DEFAULT_BUILT_IN_INPUT = false;
00038 
00040 const int K_SIMFQT_EARLY_RETURN_STATUS = 99;
00041 
00042 // ///////// Parsing of Options & Configuration /////////
00043 // A helper function to simplify the main part.
00044 template<class T> std::ostream& operator<< (std::ostream& os,
00045                                             const std::vector<T>& v) {
00046   std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 
00047   return os;
00048 }
00049 
00051 int readConfiguration (int argc, char* argv[], bool& ioIsBuiltin,
00052                        stdair::Filename_T& ioFareInputFilename,
00053                        std::string& ioLogFilename) {
00054 
00055   // Default for the built-in input
00056   ioIsBuiltin = K_SIMFQT_DEFAULT_BUILT_IN_INPUT;
00057 
00058   // Declare a group of options that will be allowed only on command line
00059   boost::program_options::options_description generic ("Generic options");
00060   generic.add_options()
00061     ("prefix", "print installation prefix")
00062     ("version,v", "print version string")
00063     ("help,h", "produce help message");
00064     
00065   // Declare a group of options that will be allowed both on command
00066   // line and in config file
00067   boost::program_options::options_description config ("Configuration");
00068   config.add_options()
00069     ("builtin,b",
00070      "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -f/--fare option")
00071     ("fare,f",
00072      boost::program_options::value< std::string >(&ioFareInputFilename)->default_value(K_SIMFQT_DEFAULT_FARE_INPUT_FILENAME),
00073      "(CSV) input file for the fare rules")
00074     ("log,l",
00075      boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_SIMFQT_DEFAULT_LOG_FILENAME),
00076      "Filename for the logs")
00077     ;
00078 
00079   // Hidden options, will be allowed both on command line and
00080   // in config file, but will not be shown to the user.
00081   boost::program_options::options_description hidden ("Hidden options");
00082   hidden.add_options()
00083     ("copyright",
00084      boost::program_options::value< std::vector<std::string> >(),
00085      "Show the copyright (license)");
00086         
00087   boost::program_options::options_description cmdline_options;
00088   cmdline_options.add(generic).add(config).add(hidden);
00089 
00090   boost::program_options::options_description config_file_options;
00091   config_file_options.add(config).add(hidden);
00092 
00093   boost::program_options::options_description visible ("Allowed options");
00094   visible.add(generic).add(config);
00095         
00096   boost::program_options::positional_options_description p;
00097   p.add ("copyright", -1);
00098         
00099   boost::program_options::variables_map vm;
00100   boost::program_options::
00101     store (boost::program_options::command_line_parser (argc, argv).
00102            options (cmdline_options).positional(p).run(), vm);
00103 
00104   std::ifstream ifs ("simfqt.cfg");
00105   boost::program_options::store (parse_config_file (ifs, config_file_options),
00106                                  vm);
00107   boost::program_options::notify (vm); if (vm.count ("help")) {
00108     std::cout << visible << std::endl;
00109     return K_SIMFQT_EARLY_RETURN_STATUS;
00110   }
00111 
00112   if (vm.count ("version")) {
00113     std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
00114     return K_SIMFQT_EARLY_RETURN_STATUS;
00115   }
00116 
00117   if (vm.count ("prefix")) {
00118     std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
00119     return K_SIMFQT_EARLY_RETURN_STATUS;
00120   }
00121 
00122   if (vm.count ("builtin")) {
00123     ioIsBuiltin = true;
00124   }
00125   const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
00126   std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
00127 
00128   if (ioIsBuiltin == false) {
00129 
00130     // The BOM tree should be built from parsing a fare (and O&D) file
00131     if (vm.count ("fare")) {
00132       ioFareInputFilename = vm["fare"].as< std::string >();
00133       std::cout << "Input fare filename is: " << ioFareInputFilename
00134                 << std::endl;
00135 
00136     } else {
00137       // The built-in option is not selected. However, no fare file
00138       // is specified
00139       std::cerr << "Either one among the -b/--builtin and -f/--fare "
00140                 << "options must be specified" << std::endl;
00141     }
00142   }
00143 
00144   if (vm.count ("log")) {
00145     ioLogFilename = vm["log"].as< std::string >();
00146     std::cout << "Log filename is: " << ioLogFilename << std::endl;
00147   }
00148   
00149   return 0;
00150 }
00151 
00152 
00153 // /////////////// M A I N /////////////////
00154 int main (int argc, char* argv[]) {
00155 
00156   // State whether the BOM tree should be built-in or parsed from an input file
00157   bool isBuiltin;
00158     
00159   // Fare input filename
00160   stdair::Filename_T lFareInputFilename;
00161   
00162   // Output log File
00163   stdair::Filename_T lLogFilename;
00164     
00165   // Call the command-line option parser
00166   const int lOptionParserStatus = 
00167     readConfiguration (argc, argv, isBuiltin, lFareInputFilename, lLogFilename);
00168     
00169   if (lOptionParserStatus == K_SIMFQT_EARLY_RETURN_STATUS) {
00170     return 0;
00171   }
00172     
00173   // Set the log parameters
00174   std::ofstream logOutputFile;
00175   // Open and clean the log outputfile
00176   logOutputFile.open (lLogFilename.c_str());
00177   logOutputFile.clear();
00178     
00179   // Initialise the Simfqt service object
00180   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00181 
00182   SIMFQT::SIMFQT_Service simfqtService (lLogParams);
00183     
00184   // DEBUG
00185   STDAIR_LOG_DEBUG ("Welcome to Simfqt");
00186 
00187   // Build a default sample list of travel solutions
00188   stdair::TravelSolutionList_T lTravelSolutionList;
00189   simfqtService.buildSampleTravelSolutions (lTravelSolutionList);
00190 
00191   // Build a default booking request
00192   stdair::BookingRequestStruct lBookingRequest =
00193     simfqtService.buildBookingRequest();
00194 
00195   // Check wether or not a (CSV) input file should be read
00196   if (isBuiltin == true) {
00197 
00198     // Build the default sample BOM tree (filled with fares) for Simfqt
00199     simfqtService.buildSampleBom();
00200 
00201   } else {
00202     
00203     // Build the BOM tree from parsing a fare file
00204     SIMFQT::FareFilePath lFareFilePath (lFareInputFilename);
00205     simfqtService.parseAndLoad (lFareFilePath);
00206 
00207   }
00208 
00209   // DEBUG: Display the travel solutions
00210   const std::string& lTSCSVDump =
00211     simfqtService.csvDisplay (lTravelSolutionList);
00212   STDAIR_LOG_DEBUG (lTSCSVDump);
00213   
00214   // FareQuote the sample list of travel solutions
00215   simfqtService.quotePrices (lBookingRequest, lTravelSolutionList);
00216 
00217   // DEBUG: Display the whole BOM tree
00218   const std::string& lBOMCSVDump = simfqtService.csvDisplay();
00219   STDAIR_LOG_DEBUG ("BOM tree: " << lBOMCSVDump);
00220   
00221   // DEBUG: Display the travel solutions
00222   const std::string& lTSCSVDumpEnd
00223     = simfqtService.csvDisplay (lTravelSolutionList);
00224   STDAIR_LOG_DEBUG (lTSCSVDumpEnd);
00225   
00226   // Close the Log outputFile
00227   logOutputFile.close();
00228 
00229   /*
00230     Note: as that program is not intended to be run on a server in
00231     production, it is better not to catch the exceptions. When it
00232     happens (that an exception is throwned), that way we get the
00233     call stack.
00234   */
00235 
00236   return 0;     
00237 }
00238