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