$treeview $search $mathjax
AirInv Logo  1.00.1
$projectbrief
$projectbrief
$searchbox

airinv_parseInventory.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 // StdAir
00015 #include <stdair/basic/BasLogParams.hpp>
00016 #include <stdair/basic/BasDBParams.hpp>
00017 #include <stdair/service/Logger.hpp>
00018 // AirInv
00019 #include <airinv/AIRINV_Master_Service.hpp>
00020 #include <airinv/config/airinv-paths.hpp>
00021 
00022 // //////// Constants //////
00026 const std::string K_AIRINV_DEFAULT_LOG_FILENAME ("airinv_parseInventory.log");
00027 
00031 const std::string K_AIRINV_DEFAULT_INVENTORY_FILENAME (STDAIR_SAMPLE_DIR
00032                                                        "/invdump01.csv");
00036 const std::string K_AIRINV_DEFAULT_SCHEDULE_FILENAME (STDAIR_SAMPLE_DIR
00037                                                       "/schedule01.csv");
00041 const std::string K_AIRINV_DEFAULT_OND_FILENAME (STDAIR_SAMPLE_DIR
00042                                                  "/ond01.csv");
00046 const std::string K_AIRINV_DEFAULT_FRAT5_INPUT_FILENAME (STDAIR_SAMPLE_DIR
00047                                                        "/frat5.csv");
00051 const std::string K_AIRINV_DEFAULT_FF_DISUTILITY_INPUT_FILENAME (STDAIR_SAMPLE_DIR
00052                                                                "/ffDisutility.csv");
00053 
00057 const std::string K_AIRINV_DEFAULT_YIELD_FILENAME (STDAIR_SAMPLE_DIR
00058                                                    "/yieldstore01.csv");
00059 
00063 const std::string K_AIRINV_DEFAULT_SEGMENT_DATE_KEY ("SV,5,2010-03-11,KBP,JFK");
00064 
00068 const stdair::ClassCode_T K_AIRINV_DEFAULT_CLASS_CODE ("Y");
00069 
00073 const stdair::PartySize_T K_AIRINV_DEFAULT_PARTY_SIZE (2);
00074 
00079 const bool K_AIRINV_DEFAULT_BUILT_IN_INPUT = false;
00080 
00085 const bool K_AIRINV_DEFAULT_FOR_SCHEDULE = false;
00086 
00090 const int K_AIRINV_EARLY_RETURN_STATUS = 99;
00091 
00092 // ///////// Parsing of Options & Configuration /////////
00093 // A helper function to simplify the main part.
00094 template<class T> std::ostream& operator<< (std::ostream& os,
00095                                             const std::vector<T>& v) {
00096   std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 
00097   return os;
00098 }
00099 
00103 int readConfiguration (int argc, char* argv[],
00104                        bool& ioIsBuiltin, bool& ioIsForSchedule,
00105                        stdair::Filename_T& ioInventoryFilename,
00106                        stdair::Filename_T& ioScheduleInputFilename,
00107                        stdair::Filename_T& ioODInputFilename,
00108                        stdair::Filename_T& ioFRAT5Filename,
00109                        stdair::Filename_T& ioFFDisutilityFilename,
00110                        stdair::Filename_T& ioYieldInputFilename,
00111                        std::string& ioSegmentDateKey,
00112                        stdair::ClassCode_T& ioClassCode,
00113                        stdair::PartySize_T& ioPartySize,
00114                        std::string& ioLogFilename) {
00115   // Default for the built-in input
00116   ioIsBuiltin = K_AIRINV_DEFAULT_BUILT_IN_INPUT;
00117 
00118   // Default for the inventory or schedule option
00119   ioIsForSchedule = K_AIRINV_DEFAULT_FOR_SCHEDULE;
00120 
00121   // Declare a group of options that will be allowed only on command line
00122   boost::program_options::options_description generic ("Generic options");
00123   generic.add_options()
00124     ("prefix", "print installation prefix")
00125     ("version,v", "print version string")
00126     ("help,h", "produce help message");
00127     
00128   // Declare a group of options that will be allowed both on command
00129   // line and in config file
00130 
00131   boost::program_options::options_description config ("Configuration");
00132   config.add_options()
00133     ("builtin,b",
00134      "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -i/--inventory or -s/--schedule option")
00135     ("for_schedule,f",
00136      "The BOM tree should be built from a schedule file (instead of from an inventory dump)")
00137     ("inventory,i",
00138      boost::program_options::value< std::string >(&ioInventoryFilename)->default_value(K_AIRINV_DEFAULT_INVENTORY_FILENAME),
00139      "(CSV) input file for the inventory")
00140     ("schedule,s",
00141      boost::program_options::value< std::string >(&ioScheduleInputFilename)->default_value(K_AIRINV_DEFAULT_SCHEDULE_FILENAME),
00142      "(CSV) input file for the schedule")
00143     ("ond,o",
00144      boost::program_options::value< std::string >(&ioODInputFilename)->default_value(K_AIRINV_DEFAULT_OND_FILENAME),
00145      "(CSV) input file for the O&D")
00146     ("frat5,F",
00147      boost::program_options::value< std::string >(&ioFRAT5Filename)->default_value(K_AIRINV_DEFAULT_FRAT5_INPUT_FILENAME),
00148      "(CSV) input file for the FRAT5 Curve")
00149     ("ff_disutility,D",
00150      boost::program_options::value< std::string >(&ioFFDisutilityFilename)->default_value(K_AIRINV_DEFAULT_FF_DISUTILITY_INPUT_FILENAME),
00151      "(CSV) input file for the FF disutility Curve")
00152     ("yield,y",
00153      boost::program_options::value< std::string >(&ioYieldInputFilename)->default_value(K_AIRINV_DEFAULT_YIELD_FILENAME),
00154      "(CSV) input file for the yield")
00155     ("segment_date_key,k",
00156      boost::program_options::value< std::string >(&ioSegmentDateKey)->default_value(K_AIRINV_DEFAULT_SEGMENT_DATE_KEY),
00157      "Segment-date key")
00158     ("class_code,c",
00159      boost::program_options::value< stdair::ClassCode_T >(&ioClassCode)->default_value(K_AIRINV_DEFAULT_CLASS_CODE),
00160      "Class code")
00161     ("party_size,p",
00162      boost::program_options::value< stdair::PartySize_T >(&ioPartySize)->default_value(K_AIRINV_DEFAULT_PARTY_SIZE),
00163      "Party size")
00164     ("log,l",
00165      boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_AIRINV_DEFAULT_LOG_FILENAME),
00166      "Filename for the logs")
00167     ;
00168 
00169   // Hidden options, will be allowed both on command line and
00170   // in config file, but will not be shown to the user.
00171   boost::program_options::options_description hidden ("Hidden options");
00172   hidden.add_options()
00173     ("copyright",
00174      boost::program_options::value< std::vector<std::string> >(),
00175      "Show the copyright (license)");
00176         
00177   boost::program_options::options_description cmdline_options;
00178   cmdline_options.add(generic).add(config).add(hidden);
00179 
00180   boost::program_options::options_description config_file_options;
00181   config_file_options.add(config).add(hidden);
00182   boost::program_options::options_description visible ("Allowed options");
00183   visible.add(generic).add(config);
00184         
00185   boost::program_options::positional_options_description p;
00186   p.add ("copyright", -1);
00187         
00188   boost::program_options::variables_map vm;
00189   boost::program_options::
00190     store (boost::program_options::command_line_parser (argc, argv).
00191            options (cmdline_options).positional(p).run(), vm);
00192 
00193   std::ifstream ifs ("airinv.cfg");
00194   boost::program_options::store (parse_config_file (ifs, config_file_options),
00195                                  vm);
00196   boost::program_options::notify (vm);
00197     
00198   if (vm.count ("help")) {
00199     std::cout << visible << std::endl;
00200     return K_AIRINV_EARLY_RETURN_STATUS;
00201   }
00202 
00203   if (vm.count ("version")) {
00204     std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
00205     return K_AIRINV_EARLY_RETURN_STATUS;
00206   }
00207 
00208   if (vm.count ("prefix")) {
00209     std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
00210     return K_AIRINV_EARLY_RETURN_STATUS;
00211   }
00212 
00213   if (vm.count ("builtin")) {
00214     ioIsBuiltin = true;
00215   }
00216   const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
00217   std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
00218 
00219   if (vm.count ("for_schedule")) {
00220     ioIsForSchedule = true;
00221   }
00222   const std::string isForScheduleStr = (ioIsForSchedule == true)?"yes":"no";
00223   std::cout << "The BOM should be built from schedule? " << isForScheduleStr
00224             << std::endl;
00225 
00226   if (ioIsBuiltin == false) {
00227 
00228     if (ioIsForSchedule == false) {
00229       // The BOM tree should be built from parsing an inventory dump
00230       if (vm.count ("inventory")) {
00231         ioInventoryFilename = vm["inventory"].as< std::string >();
00232         std::cout << "Input inventory filename is: " << ioInventoryFilename
00233                   << std::endl;
00234 
00235       } else {
00236         // The built-in option is not selected. However, no inventory dump
00237         // file is specified
00238         std::cerr << "Either one among the -b/--builtin, -i/--inventory or "
00239                   << " -f/--for_schedule and -s/--schedule options "
00240                   << "must be specified" << std::endl;
00241       }
00242 
00243     } else {
00244       // The BOM tree should be built from parsing a schedule (and O&D) file
00245       if (vm.count ("schedule")) {
00246         ioScheduleInputFilename = vm["schedule"].as< std::string >();
00247         std::cout << "Input schedule filename is: " << ioScheduleInputFilename
00248                   << std::endl;
00249 
00250       } else {
00251         // The built-in option is not selected. However, no schedule file
00252         // is specified
00253         std::cerr << "Either one among the -b/--builtin, -i/--inventory or "
00254                   << " -f/--for_schedule and -s/--schedule options "
00255                   << "must be specified" << std::endl;
00256       }
00257 
00258       if (vm.count ("ond")) {
00259         ioODInputFilename = vm["ond"].as< std::string >();
00260         std::cout << "Input O&D filename is: " << ioODInputFilename << std::endl;
00261       }
00262 
00263       if (vm.count ("frat5")) {
00264         ioFRAT5Filename = vm["frat5"].as< std::string >();
00265         std::cout << "FRAT5 input filename is: " << ioFRAT5Filename << std::endl;
00266 
00267       }
00268       
00269       if (vm.count ("ff_disutility")) {
00270         ioFFDisutilityFilename = vm["ff_disutility"].as< std::string >();
00271         std::cout << "FF disutility input filename is: "
00272                   << ioFFDisutilityFilename << std::endl;
00273         
00274       }
00275 
00276       if (vm.count ("yield")) {
00277         ioYieldInputFilename = vm["yield"].as< std::string >();
00278         std::cout << "Input yield filename is: "
00279                   << ioYieldInputFilename << std::endl;
00280       }
00281     }
00282   }
00283 
00284   if (vm.count ("log")) {
00285     ioLogFilename = vm["log"].as< std::string >();
00286     std::cout << "Log filename is: " << ioLogFilename << std::endl;
00287   }
00288 
00289   return 0;
00290 }
00291 
00292 
00293 // ///////// M A I N ////////////
00294 int main (int argc, char* argv[]) {
00295 
00296   // State whether the BOM tree should be built-in or parsed from an
00297   // input file
00298   bool isBuiltin;
00299   bool isForSchedule;
00300 
00301   // Input file names
00302   stdair::Filename_T lInventoryFilename;
00303   stdair::Filename_T lScheduleInputFilename;
00304   stdair::Filename_T lODInputFilename;
00305   stdair::Filename_T lFRAT5InputFilename;
00306   stdair::Filename_T lFFDisutilityInputFilename;
00307   stdair::Filename_T lYieldInputFilename;
00308 
00309   // Parameters for the sale
00310   std::string lSegmentDateKey;
00311   stdair::ClassCode_T lClassCode;
00312   stdair::PartySize_T lPartySize;
00313 
00314   // Output log File
00315   stdair::Filename_T lLogFilename;
00316 
00317   // Call the command-line option parser
00318   const int lOptionParserStatus =
00319     readConfiguration (argc, argv, isBuiltin, isForSchedule, lInventoryFilename,
00320                        lScheduleInputFilename, lODInputFilename,
00321                        lFRAT5InputFilename, lFFDisutilityInputFilename,
00322                        lYieldInputFilename, lSegmentDateKey, lClassCode,
00323                        lPartySize, lLogFilename);
00324 
00325   if (lOptionParserStatus == K_AIRINV_EARLY_RETURN_STATUS) {
00326     return 0;
00327   }
00328 
00329   // Set the log parameters
00330   std::ofstream logOutputFile;
00331   // Open and clean the log outputfile
00332   logOutputFile.open (lLogFilename.c_str());
00333   logOutputFile.clear();
00334 
00335   // Initialise the inventory service
00336   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00337   AIRINV::AIRINV_Master_Service airinvService (lLogParams);
00338 
00339   // DEBUG
00340   STDAIR_LOG_DEBUG ("Welcome to AirInv");
00341 
00342   // Check wether or not a (CSV) input file should be read
00343   if (isBuiltin == true) {
00344 
00345     // Build the sample BOM tree for RMOL
00346     airinvService.buildSampleBom();
00347 
00348     // Define a specific segment-date key for the sample BOM tree
00349     lSegmentDateKey = "BA,9,2011-06-10,LHR,SYD";
00350 
00351   } else {
00352     if (isForSchedule == true) {
00353       // Build the BOM tree from parsing a schedule file (and O&D list)
00354       stdair::ScheduleFilePath lScheduleFilePath (lScheduleInputFilename);
00355       stdair::ODFilePath lODFilePath (lODInputFilename);
00356       stdair::FRAT5FilePath lFRAT5FilePath (lFRAT5InputFilename);
00357       stdair::FFDisutilityFilePath lFFDisutilityFilePath (lFFDisutilityInputFilename);
00358       AIRRAC::YieldFilePath lYieldFilePath (lYieldInputFilename);
00359       airinvService.parseAndLoad (lScheduleFilePath, lODFilePath,
00360                                   lFRAT5FilePath, lFFDisutilityFilePath,
00361                                   lYieldFilePath);
00362 
00363       if (lSegmentDateKey == K_AIRINV_DEFAULT_SEGMENT_DATE_KEY) {
00364         // Define a specific segment-date key for the schedule-based inventory
00365         lSegmentDateKey = "SQ,11,2010-01-15,SIN,BKK";
00366       }
00367 
00368     } else {
00369       // Build the BOM tree from parsing an inventory dump file
00370       AIRINV::InventoryFilePath lInventoryFilePath (lInventoryFilename);
00371       airinvService.parseAndLoad (lInventoryFilePath);
00372     }
00373   }
00374 
00375   // Make a booking
00376   const bool isSellSuccessful =
00377     airinvService.sell (lSegmentDateKey, lClassCode, lPartySize);
00378 
00379   // DEBUG
00380   STDAIR_LOG_DEBUG ("Sale ('" << lSegmentDateKey << "', " << lClassCode << ": "
00381                     << lPartySize << ") successful? " << isSellSuccessful);
00382 
00383   // DEBUG: Display the whole BOM tree
00384   const std::string& lCSVDump = airinvService.csvDisplay();
00385   STDAIR_LOG_DEBUG (lCSVDump);
00386 
00387   // Close the Log outputFile
00388   logOutputFile.close();
00389 
00390   /*
00391     Note: as that program is not intended to be run on a server in
00392     production, it is better not to catch the exceptions. When it
00393     happens (that an exception is throwned), that way we get the
00394     call stack.
00395   */
00396 
00397   return 0;     
00398 }