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