$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 ("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 }