00001
00002
00003
00004
00005 #include <cassert>
00006 #include <vector>
00007 #include <fstream>
00008
00009 #include <stdair/basic/BasFileMgr.hpp>
00010 #include <stdair/bom/BomRoot.hpp>
00011 #include <stdair/service/Logger.hpp>
00012
00013 #include <simfqt/command/FareParserHelper.hpp>
00014 #include <simfqt/command/FareRuleGenerator.hpp>
00015
00016 namespace SIMFQT {
00017
00018 namespace FareParserHelper {
00019
00020
00021
00022
00023
00024 ParserSemanticAction::
00025 ParserSemanticAction (FareRuleStruct& ioFareRule)
00026 : _fareRule (ioFareRule) {
00027 }
00028
00029
00030 storeFareId::
00031 storeFareId (FareRuleStruct& ioFareRule)
00032 : ParserSemanticAction (ioFareRule) {
00033 }
00034
00035
00036 void storeFareId::operator() (unsigned int iFareId,
00037 boost::spirit::qi::unused_type,
00038 boost::spirit::qi::unused_type) const {
00039 _fareRule.setFareID (iFareId);
00040
00041
00042
00043 const stdair::AirlineCode_T lEmptyAirlineCode ("");
00044 _fareRule.setAirlineCode(lEmptyAirlineCode);
00045 _fareRule.clearAirlineCodeList();
00046 const stdair::ClassCode_T lEmptyClassCode ("");
00047 _fareRule.setClassCode(lEmptyClassCode);
00048 _fareRule.clearClassCodeList();
00049 _fareRule._itSeconds = 0;
00050 }
00051
00052
00053 storeOrigin ::
00054 storeOrigin (FareRuleStruct& ioFareRule)
00055 : ParserSemanticAction (ioFareRule) {
00056 }
00057
00058
00059 void storeOrigin::operator() (std::vector<char> iChar,
00060 boost::spirit::qi::unused_type,
00061 boost::spirit::qi::unused_type) const {
00062 const stdair::AirportCode_T lOrigin (iChar.begin(), iChar.end());
00063 _fareRule.setOrigin (lOrigin);
00064
00065
00066 }
00067
00068
00069 storeDestination ::
00070 storeDestination (FareRuleStruct& ioFareRule)
00071 : ParserSemanticAction (ioFareRule) {
00072 }
00073
00074
00075 void storeDestination::operator() (std::vector<char> iChar,
00076 boost::spirit::qi::unused_type,
00077 boost::spirit::qi::unused_type) const {
00078 const stdair::AirportCode_T lDestination (iChar.begin(), iChar.end());
00079 _fareRule.setDestination (lDestination);
00080
00081
00082 }
00083
00084
00085 storeTripType ::
00086 storeTripType (FareRuleStruct& ioFareRule)
00087 : ParserSemanticAction (ioFareRule) {
00088 }
00089
00090
00091 void storeTripType::operator() (std::vector<char> iChar,
00092 boost::spirit::qi::unused_type,
00093 boost::spirit::qi::unused_type) const {
00094 const stdair::TripType_T lTripType (iChar.begin(), iChar.end());
00095 if (lTripType == "OW" || lTripType == "RT") {
00096 _fareRule.setTripType (lTripType);
00097 } else {
00098
00099 STDAIR_LOG_ERROR ("Invalid trip type " << lTripType);
00100 }
00101
00102
00103 }
00104
00105
00106
00107 storeDateRangeStart::
00108 storeDateRangeStart (FareRuleStruct& ioFareRule)
00109 : ParserSemanticAction (ioFareRule) {
00110 }
00111
00112
00113 void storeDateRangeStart::operator() (boost::spirit::qi::unused_type,
00114 boost::spirit::qi::unused_type,
00115 boost::spirit::qi::unused_type) const {
00116 const stdair::Date_T& lDateStart = _fareRule.calculateDate ();
00117 _fareRule.setDateRangeStart (lDateStart);
00118
00119
00120 }
00121
00122
00123 storeDateRangeEnd::
00124 storeDateRangeEnd(FareRuleStruct& ioFareRule)
00125 : ParserSemanticAction (ioFareRule) {
00126 }
00127
00128
00129 void storeDateRangeEnd::operator() (boost::spirit::qi::unused_type,
00130 boost::spirit::qi::unused_type,
00131 boost::spirit::qi::unused_type) const {
00132 const stdair::Date_T& lDateEnd = _fareRule.calculateDate ();
00133
00134
00135
00136 const stdair::DateOffset_T oneDay (1);
00137 const stdair::Date_T lBoostDateEnd = lDateEnd + oneDay;
00138 _fareRule.setDateRangeEnd (lBoostDateEnd);
00139
00140
00141 }
00142
00143
00144 storeStartRangeTime::
00145 storeStartRangeTime (FareRuleStruct& ioFareRule)
00146 : ParserSemanticAction (ioFareRule) {
00147 }
00148
00149
00150 void storeStartRangeTime::operator() (boost::spirit::qi::unused_type,
00151 boost::spirit::qi::unused_type,
00152 boost::spirit::qi::unused_type) const {
00153 const stdair::Duration_T& lTimeStart = _fareRule.calculateTime ();
00154 _fareRule.setTimeRangeStart (lTimeStart);
00155
00156
00157
00158 _fareRule._itSeconds = 0;
00159 }
00160
00161
00162 storeEndRangeTime::
00163 storeEndRangeTime (FareRuleStruct& ioFareRule)
00164 : ParserSemanticAction (ioFareRule) {
00165 }
00166
00167
00168 void storeEndRangeTime::operator() (boost::spirit::qi::unused_type,
00169 boost::spirit::qi::unused_type,
00170 boost::spirit::qi::unused_type) const {
00171 const stdair::Duration_T& lTimeEnd = _fareRule.calculateTime ();
00172 _fareRule.setTimeRangeEnd (lTimeEnd);
00173
00174
00175
00176 _fareRule._itSeconds = 0;
00177 }
00178
00179
00180 storePOS ::
00181 storePOS (FareRuleStruct& ioFareRule)
00182 : ParserSemanticAction (ioFareRule) {
00183 }
00184
00185
00186 void storePOS::operator() (std::vector<char> iChar,
00187 boost::spirit::qi::unused_type,
00188 boost::spirit::qi::unused_type) const {
00189 const stdair::CityCode_T lPOS (iChar.begin(), iChar.end());
00190 if (lPOS == _fareRule.getOrigin() || lPOS == _fareRule.getDestination()) {
00191 _fareRule.setPOS (lPOS);
00192 } else if (lPOS == "ROW") {
00193 const stdair::CityCode_T lPOSROW ("ROW");
00194 _fareRule.setPOS (lPOSROW);
00195 } else {
00196
00197 STDAIR_LOG_ERROR ("Invalid point of sale " << lPOS);
00198 }
00199
00200
00201 }
00202
00203
00204 storeCabinCode ::
00205 storeCabinCode (FareRuleStruct& ioFareRule)
00206 : ParserSemanticAction (ioFareRule) {
00207 }
00208
00209
00210 void storeCabinCode::operator() (char iChar,
00211 boost::spirit::qi::unused_type,
00212 boost::spirit::qi::unused_type) const {
00213 std::ostringstream ostr;
00214 ostr << iChar;
00215 const std::string cabinCodeStr = ostr.str();
00216 const stdair::CabinCode_T& lCabinCode (cabinCodeStr);
00217 _fareRule.setCabinCode (lCabinCode);
00218
00219
00220
00221
00222 }
00223
00224
00225 storeChannel ::
00226 storeChannel (FareRuleStruct& ioFareRule)
00227 : ParserSemanticAction (ioFareRule) {
00228 }
00229
00230
00231 void storeChannel::operator() (std::vector<char> iChar,
00232 boost::spirit::qi::unused_type,
00233 boost::spirit::qi::unused_type) const {
00234 const stdair::ChannelLabel_T lChannel (iChar.begin(), iChar.end());
00235 if (lChannel != "IN" && lChannel != "IF"
00236 && lChannel != "DN" && lChannel != "DF") {
00237
00238 STDAIR_LOG_ERROR ("Invalid channel " << lChannel);
00239 }
00240 _fareRule.setChannel (lChannel);
00241
00242
00243 }
00244
00245
00246 storeAdvancePurchase ::
00247 storeAdvancePurchase (FareRuleStruct& ioFareRule)
00248 : ParserSemanticAction (ioFareRule) {
00249 }
00250
00251
00252 void storeAdvancePurchase::operator() (unsigned int iAdancePurchase,
00253 boost::spirit::qi::unused_type,
00254 boost::spirit::qi::unused_type) const {
00255 const stdair::DayDuration_T& lAdancePurchase = iAdancePurchase;
00256 _fareRule.setAdvancePurchase (lAdancePurchase);
00257
00258
00259 }
00260
00261
00262 storeSaturdayStay ::
00263 storeSaturdayStay (FareRuleStruct& ioFareRule)
00264 : ParserSemanticAction (ioFareRule) {
00265 }
00266
00267
00268 void storeSaturdayStay::operator() (char iSaturdayStay,
00269 boost::spirit::qi::unused_type,
00270 boost::spirit::qi::unused_type) const {
00271 bool lBool = false;
00272 if (iSaturdayStay == 'T') {
00273 lBool = true;
00274 } else {
00275 if (iSaturdayStay != 'F') {
00276
00277 STDAIR_LOG_DEBUG ("Invalid saturdayStay char " << iSaturdayStay);
00278 }
00279 }
00280 const stdair::SaturdayStay_T lSaturdayStay (lBool);
00281 _fareRule.setSaturdayStay (lSaturdayStay);
00282
00283
00284 }
00285
00286
00287 storeChangeFees ::
00288 storeChangeFees (FareRuleStruct& ioFareRule)
00289 : ParserSemanticAction (ioFareRule) {
00290 }
00291
00292
00293 void storeChangeFees::operator() (char iChangefees,
00294 boost::spirit::qi::unused_type,
00295 boost::spirit::qi::unused_type) const {
00296
00297 bool lBool = false;
00298 if (iChangefees == 'T') {
00299 lBool = true;
00300 } else {
00301 if (iChangefees != 'F') {
00302
00303 STDAIR_LOG_DEBUG ("Invalid change fees char " << iChangefees);
00304 }
00305 }
00306 const stdair::ChangeFees_T lChangefees (lBool);
00307 _fareRule.setChangeFees (lChangefees);
00308
00309
00310 }
00311
00312
00313 storeNonRefundable ::
00314 storeNonRefundable (FareRuleStruct& ioFareRule)
00315 : ParserSemanticAction (ioFareRule) {
00316 }
00317
00318
00319 void storeNonRefundable::operator() (char iNonRefundable,
00320 boost::spirit::qi::unused_type,
00321 boost::spirit::qi::unused_type) const {
00322 bool lBool = false;
00323 if (iNonRefundable == 'T') {
00324 lBool = true;
00325 } else {
00326 if (iNonRefundable != 'F') {
00327
00328 STDAIR_LOG_DEBUG ("Invalid non refundable char " << iNonRefundable);
00329 }
00330 }
00331 const stdair::NonRefundable_T lNonRefundable (lBool);
00332 _fareRule.setNonRefundable (lNonRefundable);
00333
00334
00335 }
00336
00337
00338 storeMinimumStay ::
00339 storeMinimumStay (FareRuleStruct& ioFareRule)
00340 : ParserSemanticAction (ioFareRule) {
00341 }
00342
00343
00344 void storeMinimumStay::operator() (unsigned int iMinStay,
00345 boost::spirit::qi::unused_type,
00346 boost::spirit::qi::unused_type) const {
00347 const stdair::DayDuration_T lMinStay = iMinStay;
00348 _fareRule.setMinimumStay (lMinStay);
00349
00350
00351 }
00352
00353
00354 storeFare ::
00355 storeFare (FareRuleStruct& ioFareRule)
00356 : ParserSemanticAction (ioFareRule) {
00357 }
00358
00359
00360 void storeFare::operator() (double iFare,
00361 boost::spirit::qi::unused_type,
00362 boost::spirit::qi::unused_type) const {
00363 const stdair::PriceValue_T lFare = iFare;
00364 _fareRule.setFare (lFare);
00365
00366
00367 }
00368
00369
00370 storeAirlineCode ::
00371 storeAirlineCode (FareRuleStruct& ioFareRule)
00372 : ParserSemanticAction (ioFareRule) {
00373 }
00374
00375
00376 void storeAirlineCode::operator() (std::vector<char> iChar,
00377 boost::spirit::qi::unused_type,
00378 boost::spirit::qi::unused_type) const {
00379
00380 const stdair::AirlineCode_T lAirlineCode (iChar.begin(), iChar.end());
00381
00382 _fareRule.addAirlineCode (lAirlineCode);
00383
00384
00385 }
00386
00387
00388 storeClass ::
00389 storeClass (FareRuleStruct& ioFareRule)
00390 : ParserSemanticAction (ioFareRule) {
00391 }
00392
00393
00394 void storeClass::operator() (std::vector<char> iChar,
00395 boost::spirit::qi::unused_type,
00396 boost::spirit::qi::unused_type) const {
00397 std::ostringstream ostr;
00398 for (std::vector<char>::const_iterator lItVector = iChar.begin();
00399 lItVector != iChar.end();
00400 lItVector++) {
00401 ostr << *lItVector;
00402 }
00403 const std::string classCodeStr = ostr.str();
00404 const stdair::ClassCode_T lClassCode (classCodeStr);
00405
00406 _fareRule.addClassCode (lClassCode);
00407
00408
00409 }
00410
00411
00412 doEndFare::
00413 doEndFare (stdair::BomRoot& ioBomRoot,
00414 FareRuleStruct& ioFareRule)
00415 : ParserSemanticAction (ioFareRule),
00416 _bomRoot (ioBomRoot) {
00417 }
00418
00419
00420 void doEndFare::operator() (boost::spirit::qi::unused_type,
00421 boost::spirit::qi::unused_type,
00422 boost::spirit::qi::unused_type) const {
00423
00424
00425
00426 FareRuleGenerator::createAirportPair (_bomRoot, _fareRule);
00427 STDAIR_LOG_DEBUG(_fareRule.describe());
00428 }
00429
00430
00431
00432
00433
00434
00436 namespace bsq = boost::spirit::qi;
00437 namespace bsa = boost::spirit::ascii;
00438
00440 stdair::int1_p_t int1_p;
00441
00443 stdair::uint2_p_t uint2_p;
00444
00446 stdair::uint4_p_t uint4_p;
00447
00449 stdair::uint1_4_p_t uint1_4_p;
00450
00452 stdair::hour_p_t hour_p;
00453 stdair::minute_p_t minute_p;
00454 stdair::second_p_t second_p;
00455
00457 stdair::year_p_t year_p;
00458 stdair::month_p_t month_p;
00459 stdair::day_p_t day_p;
00460
00461
00462
00463
00464
00465
00466 FareRuleParser::FareRuleParser (stdair::BomRoot& ioBomRoot,
00467 FareRuleStruct& iofareRule) :
00468 FareRuleParser::base_type(start),
00469 _bomRoot(ioBomRoot), _fareRule(iofareRule) {
00470
00471 start = *(comments | fare_rule);
00472
00473 comments = (bsq::lexeme[bsq::repeat(2)[bsa::char_('/')]
00474 >> +(bsa::char_ - bsq::eol)
00475 >> bsq::eol]
00476 | bsq::lexeme[bsa::char_('/') >>bsa::char_('*')
00477 >> +(bsa::char_ - bsa::char_('*'))
00478 >> bsa::char_('*') >> bsa::char_('/')]);
00479
00480 fare_rule = fare_key
00481 >> +( ';' >> segment )
00482 >> fare_rule_end[doEndFare(_bomRoot, _fareRule)];
00483
00484 fare_rule_end = bsa::char_(';');
00485
00486 fare_key = fare_id
00487 >> ';' >> origin >> ';' >> destination
00488 >> ';' >> tripType
00489 >> ';' >> dateRangeStart >> ';' >> dateRangeEnd
00490 >> ';' >> timeRangeStart >> ';' >> timeRangeEnd
00491 >> ';' >> point_of_sale >> ';' >> cabinCode >> ';' >> channel
00492 >> ';' >> advancePurchase >> ';' >> saturdayStay
00493 >> ';' >> changeFees >> ';' >> nonRefundable
00494 >> ';' >> minimumStay >> ';' >> fare;
00495
00496 fare_id = uint1_4_p[storeFareId(_fareRule)];
00497
00498 origin = bsq::repeat(3)[bsa::char_("A-Z")][storeOrigin(_fareRule)];
00499
00500 destination =
00501 bsq::repeat(3)[bsa::char_("A-Z")][storeDestination(_fareRule)];
00502
00503 tripType =
00504 bsq::repeat(2)[bsa::char_("A-Z")][storeTripType(_fareRule)];
00505
00506 dateRangeStart = date[storeDateRangeStart(_fareRule)];
00507
00508 dateRangeEnd = date[storeDateRangeEnd(_fareRule)];
00509
00510 date = bsq::lexeme
00511 [year_p[boost::phoenix::ref(_fareRule._itYear) = bsq::labels::_1]
00512 >> '-'
00513 >> month_p[boost::phoenix::ref(_fareRule._itMonth) = bsq::labels::_1]
00514 >> '-'
00515 >> day_p[boost::phoenix::ref(_fareRule._itDay) = bsq::labels::_1] ];
00516
00517 timeRangeStart = time[storeStartRangeTime(_fareRule)];
00518
00519 timeRangeEnd = time[storeEndRangeTime(_fareRule)];
00520
00521 time = bsq::lexeme
00522 [hour_p[boost::phoenix::ref(_fareRule._itHours) = bsq::labels::_1]
00523 >> ':'
00524 >> minute_p[boost::phoenix::ref(_fareRule._itMinutes) = bsq::labels::_1]
00525 >> - (':' >> second_p[boost::phoenix::ref(_fareRule._itSeconds) = bsq::labels::_1]) ];
00526
00527 point_of_sale = bsq::repeat(3)[bsa::char_("A-Z")][storePOS(_fareRule)];
00528
00529 cabinCode = bsa::char_("A-Z")[storeCabinCode(_fareRule)];
00530
00531 channel = bsq::repeat(2)[bsa::char_("A-Z")][storeChannel(_fareRule)];
00532
00533 advancePurchase = uint1_4_p[storeAdvancePurchase(_fareRule)];
00534
00535 saturdayStay = bsa::char_("A-Z")[storeSaturdayStay(_fareRule)];
00536
00537 changeFees = bsa::char_("A-Z")[storeChangeFees(_fareRule)];
00538
00539 nonRefundable = bsa::char_("A-Z")[storeNonRefundable(_fareRule)];
00540
00541 minimumStay = uint1_4_p[storeMinimumStay(_fareRule)];
00542
00543 fare = bsq::double_[storeFare(_fareRule)];
00544
00545 segment = bsq::repeat(2)[bsa::char_("A-Z")][storeAirlineCode(_fareRule)]
00546 >> ';'
00547 >> bsq::repeat(1,bsq::inf)[bsa::char_("A-Z")][storeClass(_fareRule)];
00548
00549
00550 BOOST_SPIRIT_DEBUG_NODE (start);
00551 BOOST_SPIRIT_DEBUG_NODE (comments);
00552 BOOST_SPIRIT_DEBUG_NODE (fare_rule);
00553 BOOST_SPIRIT_DEBUG_NODE (fare_rule_end);
00554 BOOST_SPIRIT_DEBUG_NODE (fare_key);
00555 BOOST_SPIRIT_DEBUG_NODE (fare_id);
00556 BOOST_SPIRIT_DEBUG_NODE (origin);
00557 BOOST_SPIRIT_DEBUG_NODE (destination);
00558 BOOST_SPIRIT_DEBUG_NODE (tripType);
00559 BOOST_SPIRIT_DEBUG_NODE (dateRangeStart);
00560 BOOST_SPIRIT_DEBUG_NODE (dateRangeEnd);
00561 BOOST_SPIRIT_DEBUG_NODE (date);
00562 BOOST_SPIRIT_DEBUG_NODE (timeRangeStart);
00563 BOOST_SPIRIT_DEBUG_NODE (timeRangeEnd);
00564 BOOST_SPIRIT_DEBUG_NODE (time);
00565 BOOST_SPIRIT_DEBUG_NODE (point_of_sale);
00566 BOOST_SPIRIT_DEBUG_NODE (cabinCode);
00567 BOOST_SPIRIT_DEBUG_NODE (channel);
00568 BOOST_SPIRIT_DEBUG_NODE (advancePurchase);
00569 BOOST_SPIRIT_DEBUG_NODE (saturdayStay);
00570 BOOST_SPIRIT_DEBUG_NODE (changeFees);
00571 BOOST_SPIRIT_DEBUG_NODE (nonRefundable);
00572 BOOST_SPIRIT_DEBUG_NODE (minimumStay);
00573 BOOST_SPIRIT_DEBUG_NODE (fare);
00574 BOOST_SPIRIT_DEBUG_NODE (segment);
00575 }
00576 }
00577
00579
00580
00581
00583
00584
00585 FareRuleFileParser::
00586 FareRuleFileParser (stdair::BomRoot& ioBomRoot,
00587 const stdair::Filename_T& iFilename)
00588 : _filename (iFilename), _bomRoot (ioBomRoot) {
00589 init();
00590 }
00591
00592
00593 void FareRuleFileParser::init() {
00594
00595 const bool doesExistAndIsReadable =
00596 stdair::BasFileMgr::doesExistAndIsReadable (_filename);
00597
00598 if (doesExistAndIsReadable == false) {
00599 STDAIR_LOG_ERROR ("The fare schedule file " << _filename
00600 << " does not exist or can not be read.");
00601
00602 throw FareInputFileNotFoundException ("The fare file " + _filename
00603 + " does not exist or can not be read");
00604 }
00605 }
00606
00607
00608 void FareRuleFileParser::generateFareRules () {
00609
00610 STDAIR_LOG_DEBUG ("Parsing fare input file: " << _filename);
00611
00612
00613 const std::string* lFileName = &_filename;
00614 const char *lChar = (*lFileName).c_str();
00615 std::ifstream fileToBeParsed(lChar, std::ios_base::in);
00616
00617
00618 if (fileToBeParsed == false) {
00619 STDAIR_LOG_ERROR ("The fare file " << _filename << " can not be open."
00620 << std::endl);
00621
00622 throw FareInputFileNotFoundException ("The file " + _filename
00623 + " does not exist or can not be read");
00624 }
00625
00626
00627 stdair::base_iterator_t inputBegin (fileToBeParsed);
00628
00629
00630 stdair::iterator_t
00631 start (boost::spirit::make_default_multi_pass (inputBegin));
00632 stdair::iterator_t end;
00633
00634
00635 FareParserHelper::FareRuleParser lFPParser(_bomRoot, _fareRule);
00636
00637
00638
00639 const bool hasParsingBeenSuccesful =
00640 boost::spirit::qi::phrase_parse (start, end, lFPParser,
00641 boost::spirit::ascii::space);
00642
00643 if (hasParsingBeenSuccesful == false) {
00644
00645 STDAIR_LOG_ERROR ("Parsing of fare input file: " << _filename
00646 << " failed");
00647 throw FareFileParsingFailedException ("Parsing of fare input file: "
00648 + _filename + " failed");
00649 }
00650
00651 if (start != end) {
00652
00653 STDAIR_LOG_ERROR ("Parsing of fare input file: " << _filename
00654 << " failed");
00655 throw FareFileParsingFailedException ("Parsing of fare input file: "
00656 + _filename + " failed");
00657 }
00658
00659 if (hasParsingBeenSuccesful == true && start == end) {
00660 STDAIR_LOG_DEBUG ("Parsing of fare input file: " << _filename
00661 << " succeeded");
00662 }
00663
00664 }
00665
00666 }