$treeview $search $mathjax
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 }