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

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