$treeview $search $mathjax
SimFQT Logo  1.00.1
$projectbrief
$projectbrief
$searchbox

FareParserHelper.cpp

Go to the documentation of this file.
00001  // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 #include <vector>
00007 #include <fstream>
00008 // StdAir
00009 #include <stdair/basic/BasFileMgr.hpp>
00010 #include <stdair/basic/BasConst_Request.hpp>
00011 #include <stdair/bom/BomRoot.hpp>
00012 #include <stdair/service/Logger.hpp>
00013 //#define BOOST_SPIRIT_DEBUG
00014 #include <stdair/basic/BasParserTypes.hpp>
00015 // SIMFQT
00016 #include <simfqt/command/FareParserHelper.hpp>
00017 #include <simfqt/command/FareRuleGenerator.hpp>
00018 
00019 
00020 
00021 namespace SIMFQT {
00022 
00023   namespace FareParserHelper {
00024       
00025     // //////////////////////////////////////////////////////////////////
00026     //  Semantic actions
00027     // //////////////////////////////////////////////////////////////////
00028 
00029     ParserSemanticAction::
00030     ParserSemanticAction (FareRuleStruct& ioFareRule)
00031       : _fareRule (ioFareRule) {
00032     }      
00033    
00034     // //////////////////////////////////////////////////////////////////
00035     storeFareId::
00036     storeFareId (FareRuleStruct& ioFareRule)
00037       : ParserSemanticAction (ioFareRule) {
00038     }
00039     
00040     // //////////////////////////////////////////////////////////////////
00041     void storeFareId::operator() (unsigned int iFareId,
00042                                   boost::spirit::qi::unused_type,
00043                                   boost::spirit::qi::unused_type) const {
00044       _fareRule.setFareID (iFareId);
00045       
00046       // DEBUG
00047       //STDAIR_LOG_DEBUG ( "Fare Id: " << _fareRule.getFareID ());
00048       const stdair::AirlineCode_T lEmptyAirlineCode ("");
00049       _fareRule.setAirlineCode(lEmptyAirlineCode);
00050       _fareRule.clearAirlineCodeList();
00051       const stdair::ClassCode_T lEmptyClassCode ("");
00052       _fareRule.setClassCode(lEmptyClassCode);
00053       _fareRule.clearClassCodeList();
00054       _fareRule._itSeconds = 0; 
00055     }
00056     
00057     // //////////////////////////////////////////////////////////////////
00058     storeOrigin ::
00059     storeOrigin (FareRuleStruct& ioFareRule)
00060       : ParserSemanticAction (ioFareRule) {
00061     }
00062     
00063     // //////////////////////////////////////////////////////////////////
00064     void storeOrigin::operator() (std::vector<char> iChar,
00065                                   boost::spirit::qi::unused_type,
00066                                   boost::spirit::qi::unused_type) const {
00067        const stdair::AirportCode_T lOrigin (iChar.begin(), iChar.end());
00068        _fareRule.setOrigin (lOrigin);
00069        // DEBUG
00070        //STDAIR_LOG_DEBUG ( "Origin: " << _fareRule.getOrigin ());
00071     }
00072 
00073     // //////////////////////////////////////////////////////////////////
00074     storeDestination ::
00075     storeDestination (FareRuleStruct& ioFareRule)
00076       : ParserSemanticAction (ioFareRule) {
00077     }
00078     
00079     // //////////////////////////////////////////////////////////////////
00080     void storeDestination::operator() (std::vector<char> iChar,
00081                                        boost::spirit::qi::unused_type,
00082                                        boost::spirit::qi::unused_type) const {
00083        const stdair::AirportCode_T lDestination (iChar.begin(), iChar.end());
00084        _fareRule.setDestination (lDestination);
00085        // DEBUG
00086        //STDAIR_LOG_DEBUG ( "Destination: " << _fareRule.getDestination ());
00087     }
00088 
00089     // //////////////////////////////////////////////////////////////////
00090     storeTripType ::
00091     storeTripType (FareRuleStruct& ioFareRule)
00092       : ParserSemanticAction (ioFareRule) {
00093     }
00094     
00095     // //////////////////////////////////////////////////////////////////
00096     void storeTripType::operator() (std::vector<char> iChar,
00097                                        boost::spirit::qi::unused_type,
00098                                        boost::spirit::qi::unused_type) const {
00099       const stdair::TripType_T lTripType (iChar.begin(), iChar.end());
00100       if (lTripType == "OW" || lTripType == "RT") {
00101         _fareRule.setTripType (lTripType);
00102       } else {
00103         // ERROR
00104         STDAIR_LOG_ERROR ("Invalid trip type  " << lTripType);
00105       }                       
00106       // DEBUG
00107       //STDAIR_LOG_DEBUG ("TripType: " << _fareRule.getTripType ());
00108     }
00109 
00110     
00111     // //////////////////////////////////////////////////////////////////
00112     storeDateRangeStart::
00113     storeDateRangeStart (FareRuleStruct& ioFareRule)
00114       : ParserSemanticAction (ioFareRule) {
00115     }
00116     
00117     // //////////////////////////////////////////////////////////////////
00118     void storeDateRangeStart::operator() (boost::spirit::qi::unused_type,
00119                                           boost::spirit::qi::unused_type,
00120                                           boost::spirit::qi::unused_type) const {
00121       const stdair::Date_T& lDateStart = _fareRule.calculateDate ();
00122       _fareRule.setDateRangeStart (lDateStart);
00123       // DEBUG
00124       //STDAIR_LOG_DEBUG ("Date Range Start: " << _fareRule.getDateRangeStart ());
00125     }
00126 
00127     // //////////////////////////////////////////////////////////////////
00128     storeDateRangeEnd::
00129     storeDateRangeEnd(FareRuleStruct& ioFareRule)
00130       : ParserSemanticAction (ioFareRule) {
00131     }
00132     
00133     // //////////////////////////////////////////////////////////////////
00134     void storeDateRangeEnd::operator() (boost::spirit::qi::unused_type,
00135                                         boost::spirit::qi::unused_type,
00136                                         boost::spirit::qi::unused_type) const {
00137       const stdair::Date_T& lDateEnd = _fareRule.calculateDate ();
00138       // As a Boost date period (DatePeriod_T) defines the last day of
00139       // the period to be end-date - one day, we have to add one day to that
00140       // end date before.
00141       const stdair::DateOffset_T oneDay (1);
00142       const stdair::Date_T lBoostDateEnd = lDateEnd + oneDay;
00143       _fareRule.setDateRangeEnd (lBoostDateEnd);
00144        // DEBUG
00145       //STDAIR_LOG_DEBUG ("Date Range End: " << _fareRule.getDateRangeEnd ());
00146     }
00147 
00148     // //////////////////////////////////////////////////////////////////
00149     storeStartRangeTime::
00150     storeStartRangeTime (FareRuleStruct& ioFareRule)
00151       : ParserSemanticAction (ioFareRule) {
00152     }
00153     
00154     // //////////////////////////////////////////////////////////////////
00155     void storeStartRangeTime::operator() (boost::spirit::qi::unused_type,
00156                                           boost::spirit::qi::unused_type,
00157                                           boost::spirit::qi::unused_type) const {
00158       const stdair::Duration_T& lTimeStart = _fareRule.calculateTime ();
00159       _fareRule.setTimeRangeStart (lTimeStart);
00160       // DEBUG
00161       //STDAIR_LOG_DEBUG ("Time Range Start: " << _fareRule.getTimeRangeStart ());
00162       // Reset the number of seconds
00163       _fareRule._itSeconds = 0;
00164     }
00165 
00166     // //////////////////////////////////////////////////////////////////
00167     storeEndRangeTime::
00168     storeEndRangeTime (FareRuleStruct& ioFareRule)
00169       : ParserSemanticAction (ioFareRule) {
00170     }
00171     
00172     // //////////////////////////////////////////////////////////////////
00173     void storeEndRangeTime::operator() (boost::spirit::qi::unused_type,
00174                                         boost::spirit::qi::unused_type,
00175                                         boost::spirit::qi::unused_type) const {
00176       const stdair::Duration_T& lTimeEnd = _fareRule.calculateTime ();
00177       _fareRule.setTimeRangeEnd (lTimeEnd);
00178       // DEBUG
00179       //STDAIR_LOG_DEBUG ("Time Range End: " << _fareRule.getTimeRangeEnd ());
00180       // Reset the number of seconds
00181       _fareRule._itSeconds = 0;
00182     }
00183    
00184     // //////////////////////////////////////////////////////////////////
00185     storePOS ::
00186     storePOS (FareRuleStruct& ioFareRule)
00187       : ParserSemanticAction (ioFareRule) {
00188     }
00189     
00190     // //////////////////////////////////////////////////////////////////
00191     void storePOS::operator() (std::vector<char> iChar,
00192                                boost::spirit::qi::unused_type,
00193                                boost::spirit::qi::unused_type) const {
00194       const stdair::CityCode_T lPOS (iChar.begin(), iChar.end());
00195       if (lPOS == _fareRule.getOrigin() || lPOS == _fareRule.getDestination()) {
00196         _fareRule.setPOS (lPOS);
00197       } else if (lPOS == "ROW") {
00198         const stdair::CityCode_T lPOSROW ("ROW");
00199         _fareRule.setPOS (lPOSROW);
00200       } else if (lPOS == stdair::DEFAULT_POS) {
00201         _fareRule.setPOS (stdair::DEFAULT_POS);
00202       } else {
00203         // ERROR
00204         STDAIR_LOG_ERROR ("Invalid point of sale " << lPOS);
00205       }
00206       // DEBUG
00207       //STDAIR_LOG_DEBUG ("POS: " << _fareRule.getPOS ());
00208     }
00209 
00210     // //////////////////////////////////////////////////////////////////
00211     storeCabinCode ::
00212     storeCabinCode (FareRuleStruct& ioFareRule)
00213       : ParserSemanticAction (ioFareRule) {
00214     }
00215     
00216     // //////////////////////////////////////////////////////////////////
00217     void storeCabinCode::operator() (char iChar,
00218                                      boost::spirit::qi::unused_type,
00219                                      boost::spirit::qi::unused_type) const {
00220       std::ostringstream ostr;
00221       ostr << iChar;
00222       const std::string cabinCodeStr = ostr.str();
00223       const stdair::CabinCode_T& lCabinCode (cabinCodeStr);
00224       _fareRule.setCabinCode (lCabinCode);
00225      
00226       // DEBUG
00227       //STDAIR_LOG_DEBUG ("Cabin Code: " << _fareRule.getCabinCode ());                 
00228     
00229     }
00230 
00231     // //////////////////////////////////////////////////////////////////
00232     storeChannel ::
00233     storeChannel (FareRuleStruct& ioFareRule)
00234       : ParserSemanticAction (ioFareRule) {
00235     }
00236     
00237     // //////////////////////////////////////////////////////////////////
00238     void storeChannel::operator() (std::vector<char> iChar,
00239                                    boost::spirit::qi::unused_type,
00240                                    boost::spirit::qi::unused_type) const {
00241       const stdair::ChannelLabel_T lChannel (iChar.begin(), iChar.end());
00242       if (lChannel != "IN" && lChannel != "IF" && lChannel != "DN"
00243           && lChannel != "DF" && lChannel != stdair::DEFAULT_CHANNEL) {
00244         // ERROR
00245         STDAIR_LOG_ERROR ("Invalid channel " << lChannel);
00246       }
00247       _fareRule.setChannel (lChannel);
00248       // DEBUG
00249       //STDAIR_LOG_DEBUG ("Channel: " << _fareRule.getChannel ());
00250     }
00251     
00252     // //////////////////////////////////////////////////////////////////
00253     storeAdvancePurchase ::
00254     storeAdvancePurchase (FareRuleStruct& ioFareRule)
00255       : ParserSemanticAction (ioFareRule) {
00256     }
00257     
00258     // //////////////////////////////////////////////////////////////////
00259     void storeAdvancePurchase::operator() (unsigned int iAdancePurchase,
00260                                            boost::spirit::qi::unused_type,
00261                                            boost::spirit::qi::unused_type) const {
00262       const stdair::DayDuration_T& lAdancePurchase = iAdancePurchase;
00263       _fareRule.setAdvancePurchase (lAdancePurchase);
00264       // DEBUG
00265       //STDAIR_LOG_DEBUG ( "Advance Purchase: " << _fareRule.getAdvancePurchase ());
00266     }
00267     
00268     // //////////////////////////////////////////////////////////////////
00269     storeSaturdayStay ::
00270     storeSaturdayStay (FareRuleStruct& ioFareRule)
00271       : ParserSemanticAction (ioFareRule) {
00272     }
00273     
00274     // //////////////////////////////////////////////////////////////////
00275     void storeSaturdayStay::operator() (char iSaturdayStay,
00276                                         boost::spirit::qi::unused_type,
00277                                         boost::spirit::qi::unused_type) const {
00278       bool lBool = false;
00279       if (iSaturdayStay == 'T') {
00280         lBool = true;
00281       } else {
00282         if (iSaturdayStay != 'F') {
00283           // DEBUG
00284           STDAIR_LOG_DEBUG ("Invalid saturdayStay char " << iSaturdayStay);
00285         }
00286       }
00287       const stdair::SaturdayStay_T lSaturdayStay (lBool);
00288       _fareRule.setSaturdayStay (lSaturdayStay);
00289       // DEBUG
00290       //STDAIR_LOG_DEBUG ("Saturday Stay: " << _fareRule.getSaturdayStay ());
00291     }
00292 
00293     // //////////////////////////////////////////////////////////////////
00294     storeChangeFees ::
00295     storeChangeFees (FareRuleStruct& ioFareRule)
00296       : ParserSemanticAction (ioFareRule) {
00297     }
00298     
00299     // //////////////////////////////////////////////////////////////////
00300     void storeChangeFees::operator() (char iChangefees,
00301                                       boost::spirit::qi::unused_type,
00302                                       boost::spirit::qi::unused_type) const {
00303       
00304       bool lBool = false;
00305       if (iChangefees == 'T') {
00306         lBool = true;
00307       } else {
00308         if (iChangefees != 'F') {
00309           // DEBUG
00310           STDAIR_LOG_DEBUG ("Invalid change fees char " << iChangefees);
00311         }
00312       }
00313       const stdair::ChangeFees_T lChangefees (lBool);
00314       _fareRule.setChangeFees (lChangefees);
00315       // DEBUG
00316       //STDAIR_LOG_DEBUG ("Change fees: " << _fareRule.getChangeFees ());
00317     }
00318     
00319     // //////////////////////////////////////////////////////////////////
00320     storeNonRefundable ::
00321     storeNonRefundable (FareRuleStruct& ioFareRule)
00322       : ParserSemanticAction (ioFareRule) {
00323     }
00324     
00325     // //////////////////////////////////////////////////////////////////
00326     void storeNonRefundable::operator() (char iNonRefundable,
00327                                          boost::spirit::qi::unused_type,
00328                                          boost::spirit::qi::unused_type) const {
00329        bool lBool = false;
00330        if (iNonRefundable == 'T') {
00331          lBool = true;
00332        } else {
00333          if (iNonRefundable != 'F') {
00334            // DEBUG
00335            STDAIR_LOG_DEBUG ("Invalid non refundable char " << iNonRefundable);
00336          }
00337        }
00338        const stdair::NonRefundable_T lNonRefundable (lBool);
00339        _fareRule.setNonRefundable (lNonRefundable);
00340        // DEBUG
00341        //STDAIR_LOG_DEBUG ("Non refundable: " << _fareRule.getNonRefundable ());
00342     }
00343     
00344     // //////////////////////////////////////////////////////////////////
00345     storeMinimumStay ::
00346     storeMinimumStay (FareRuleStruct& ioFareRule)
00347       : ParserSemanticAction (ioFareRule) {
00348     }
00349     
00350     // //////////////////////////////////////////////////////////////////
00351     void storeMinimumStay::operator() (unsigned int iMinStay,
00352                                        boost::spirit::qi::unused_type,
00353                                        boost::spirit::qi::unused_type) const {
00354       const stdair::DayDuration_T lMinStay = iMinStay;
00355       _fareRule.setMinimumStay (lMinStay);
00356       // DEBUG
00357       //STDAIR_LOG_DEBUG ("Minimum Stay: " << _fareRule.getMinimumStay ());
00358     }
00359 
00360     // //////////////////////////////////////////////////////////////////
00361     storeFare ::
00362     storeFare (FareRuleStruct& ioFareRule)
00363       : ParserSemanticAction (ioFareRule) {
00364     }
00365     
00366     // //////////////////////////////////////////////////////////////////
00367     void storeFare::operator() (double iFare,
00368                                 boost::spirit::qi::unused_type,
00369                                 boost::spirit::qi::unused_type) const {
00370      const stdair::PriceValue_T lFare = iFare;
00371       _fareRule.setFare (lFare);
00372       // DEBUG
00373       //STDAIR_LOG_DEBUG ("Fare: " << _fareRule.getFare ());
00374     }
00375 
00376     // //////////////////////////////////////////////////////////////////
00377     storeAirlineCode ::
00378     storeAirlineCode (FareRuleStruct& ioFareRule)
00379       : ParserSemanticAction (ioFareRule) {
00380     }
00381     
00382     // //////////////////////////////////////////////////////////////////
00383     void storeAirlineCode::operator() (std::vector<char> iChar,
00384                                        boost::spirit::qi::unused_type,
00385                                        boost::spirit::qi::unused_type) const {
00386 
00387       const stdair::AirlineCode_T lAirlineCode (iChar.begin(), iChar.end());
00388       // Insertion of this airline Code list in the whole AirlineCode name
00389       _fareRule.addAirlineCode (lAirlineCode);
00390       // DEBUG
00391       //STDAIR_LOG_DEBUG ( "Airline code: " << lAirlineCode);
00392     }
00393 
00394     // //////////////////////////////////////////////////////////////////
00395     storeClass ::
00396     storeClass (FareRuleStruct& ioFareRule)
00397       : ParserSemanticAction (ioFareRule) {
00398     }
00399     
00400     // //////////////////////////////////////////////////////////////////
00401     void storeClass::operator() (std::vector<char> iChar,
00402                                  boost::spirit::qi::unused_type,
00403                                  boost::spirit::qi::unused_type) const {
00404       std::ostringstream ostr;
00405       for (std::vector<char>::const_iterator lItVector = iChar.begin();
00406          lItVector != iChar.end();
00407          lItVector++) {
00408         ostr << *lItVector;
00409       }
00410       const std::string classCodeStr = ostr.str();
00411       const stdair::ClassCode_T lClassCode (classCodeStr);
00412       // Insertion of this class Code list in the whole classCode name
00413       _fareRule.addClassCode (lClassCode);
00414       // DEBUG
00415       //STDAIR_LOG_DEBUG ("Class Code: " << lClassCode);
00416     }
00417     
00418     // //////////////////////////////////////////////////////////////////
00419     doEndFare::
00420     doEndFare (stdair::BomRoot& ioBomRoot,
00421                FareRuleStruct& ioFareRule)
00422       : ParserSemanticAction (ioFareRule),
00423         _bomRoot (ioBomRoot) {
00424     }
00425     
00426     // //////////////////////////////////////////////////////////////////
00427     void doEndFare::operator() (boost::spirit::qi::unused_type,
00428                                 boost::spirit::qi::unused_type,
00429                                 boost::spirit::qi::unused_type) const {
00430       // DEBUG
00431       //STDAIR_LOG_DEBUG ("Do End");
00432       // Generation of the fare rule object.
00433       FareRuleGenerator::createAirportPair (_bomRoot, _fareRule);
00434       STDAIR_LOG_DEBUG(_fareRule.describe());
00435     }  
00436 
00437     // ///////////////////////////////////////////////////////////////////
00438     //
00439     //  Utility Parsers
00440     //
00441     // ///////////////////////////////////////////////////////////////////
00443     namespace bsq = boost::spirit::qi;
00444     namespace bsa = boost::spirit::ascii;
00445     
00447     stdair::int1_p_t int1_p;
00448     
00450     stdair::uint2_p_t uint2_p;
00451 
00453     stdair::uint4_p_t uint4_p;
00454     
00456     stdair::uint1_4_p_t uint1_4_p;
00457 
00459     stdair::hour_p_t hour_p;
00460     stdair::minute_p_t minute_p;
00461     stdair::second_p_t second_p;
00462 
00464     stdair::year_p_t year_p;
00465     stdair::month_p_t month_p;
00466     stdair::day_p_t day_p;
00467 
00469     //
00470     //  (Boost Spirit) Grammar Definition
00471     //
00473 
00502     template <typename Iterator>        
00503     struct FareRuleParser : 
00504       public boost::spirit::qi::grammar<Iterator, 
00505                                         boost::spirit::ascii::space_type> {
00506 
00507       FareRuleParser (stdair::BomRoot& ioBomRoot,
00508                       FareRuleStruct& iofareRule) : 
00509 
00510         FareRuleParser::base_type(start),
00511         _bomRoot(ioBomRoot), _fareRule(iofareRule) {
00512 
00513 
00514       start = *(comments | fare_rule);
00515 
00516       comments = (bsq::lexeme[bsq::repeat(2)[bsa::char_('/')]
00517                               >> +(bsa::char_ - bsq::eol)
00518                               >> bsq::eol]
00519                   | bsq::lexeme[bsa::char_('/') >>bsa::char_('*') 
00520                                 >> +(bsa::char_ - bsa::char_('*')) 
00521                                 >> bsa::char_('*') >> bsa::char_('/')]);
00522 
00523       fare_rule = fare_key
00524         >> +( ';' >> segment )
00525         >> fare_rule_end[doEndFare(_bomRoot, _fareRule)];
00526 
00527       fare_rule_end = bsa::char_(';');
00528 
00529       fare_key = fare_id
00530         >> ';' >> origin >> ';' >> destination
00531         >> ';' >> tripType
00532         >> ';' >> dateRangeStart >> ';' >> dateRangeEnd
00533         >> ';' >> timeRangeStart >> ';' >> timeRangeEnd
00534         >> ';' >> point_of_sale >>  ';' >> cabinCode >> ';' >> channel
00535         >> ';' >> advancePurchase >> ';' >> saturdayStay
00536         >> ';' >> changeFees >> ';' >> nonRefundable
00537         >> ';' >> minimumStay >> ';' >> fare;
00538 
00539       fare_id = uint1_4_p[storeFareId(_fareRule)];
00540 
00541       origin = bsq::repeat(3)[bsa::char_("A-Z")][storeOrigin(_fareRule)];
00542       
00543       destination =  
00544         bsq::repeat(3)[bsa::char_("A-Z")][storeDestination(_fareRule)];
00545 
00546       tripType =
00547         bsq::repeat(2)[bsa::char_("A-Z")][storeTripType(_fareRule)];
00548       
00549       dateRangeStart = date[storeDateRangeStart(_fareRule)];
00550 
00551       dateRangeEnd = date[storeDateRangeEnd(_fareRule)];
00552       
00553       date = bsq::lexeme
00554         [year_p[boost::phoenix::ref(_fareRule._itYear) = bsq::labels::_1]
00555         >> '-'
00556         >> month_p[boost::phoenix::ref(_fareRule._itMonth) = bsq::labels::_1]
00557         >> '-'
00558         >> day_p[boost::phoenix::ref(_fareRule._itDay) = bsq::labels::_1] ];
00559 
00560       timeRangeStart = time[storeStartRangeTime(_fareRule)];
00561       
00562       timeRangeEnd = time[storeEndRangeTime(_fareRule)];
00563 
00564       time =  bsq::lexeme
00565         [hour_p[boost::phoenix::ref(_fareRule._itHours) = bsq::labels::_1]
00566         >> ':'
00567         >> minute_p[boost::phoenix::ref(_fareRule._itMinutes) = bsq::labels::_1]      
00568         >> - (':' >> second_p[boost::phoenix::ref(_fareRule._itSeconds) = bsq::labels::_1]) ];
00569       
00570       point_of_sale = bsq::repeat(3)[bsa::char_("A-Z")][storePOS(_fareRule)];
00571 
00572       cabinCode = bsa::char_("A-Z")[storeCabinCode(_fareRule)];
00573             
00574       channel = bsq::repeat(2)[bsa::char_("A-Z")][storeChannel(_fareRule)];
00575       
00576       advancePurchase = uint1_4_p[storeAdvancePurchase(_fareRule)];
00577 
00578       saturdayStay = bsa::char_("A-Z")[storeSaturdayStay(_fareRule)];
00579 
00580       changeFees = bsa::char_("A-Z")[storeChangeFees(_fareRule)];
00581 
00582       nonRefundable = bsa::char_("A-Z")[storeNonRefundable(_fareRule)];
00583       
00584       minimumStay = uint1_4_p[storeMinimumStay(_fareRule)];
00585 
00586       fare = bsq::double_[storeFare(_fareRule)];
00587       
00588       segment = bsq::repeat(2)[bsa::char_("A-Z")][storeAirlineCode(_fareRule)]
00589         >> ';'
00590         >> bsq::repeat(1,bsq::inf)[bsa::char_("A-Z")][storeClass(_fareRule)];
00591 
00592       //BOOST_SPIRIT_DEBUG_NODE (FareRuleParser);
00593       BOOST_SPIRIT_DEBUG_NODE (start);
00594       BOOST_SPIRIT_DEBUG_NODE (comments);
00595       BOOST_SPIRIT_DEBUG_NODE (fare_rule);
00596       BOOST_SPIRIT_DEBUG_NODE (fare_rule_end);
00597       BOOST_SPIRIT_DEBUG_NODE (fare_key);
00598       BOOST_SPIRIT_DEBUG_NODE (fare_id);
00599       BOOST_SPIRIT_DEBUG_NODE (origin);
00600       BOOST_SPIRIT_DEBUG_NODE (destination);
00601       BOOST_SPIRIT_DEBUG_NODE (tripType);
00602       BOOST_SPIRIT_DEBUG_NODE (dateRangeStart);
00603       BOOST_SPIRIT_DEBUG_NODE (dateRangeEnd);
00604       BOOST_SPIRIT_DEBUG_NODE (date);
00605       BOOST_SPIRIT_DEBUG_NODE (timeRangeStart);
00606       BOOST_SPIRIT_DEBUG_NODE (time);
00607       BOOST_SPIRIT_DEBUG_NODE (point_of_sale);
00608       BOOST_SPIRIT_DEBUG_NODE (cabinCode);
00609       BOOST_SPIRIT_DEBUG_NODE (channel);
00610       BOOST_SPIRIT_DEBUG_NODE (advancePurchase);
00611       BOOST_SPIRIT_DEBUG_NODE (saturdayStay);
00612       BOOST_SPIRIT_DEBUG_NODE (changeFees);
00613       BOOST_SPIRIT_DEBUG_NODE (nonRefundable);
00614       BOOST_SPIRIT_DEBUG_NODE (minimumStay);
00615       BOOST_SPIRIT_DEBUG_NODE (fare);
00616       BOOST_SPIRIT_DEBUG_NODE (segment);
00617 
00618       }
00619 
00620       // Instantiation of rules
00621       boost::spirit::qi::rule<Iterator, 
00622                               boost::spirit::ascii::space_type>
00623       start, comments, fare_rule, fare_rule_end, fare_key, fare_id, origin,
00624         destination, tripType, dateRangeStart, dateRangeEnd, date,
00625         timeRangeStart, timeRangeEnd, time, point_of_sale, cabinCode, channel,
00626         advancePurchase, saturdayStay, changeFees, nonRefundable, minimumStay,
00627         fare, segment;
00628       
00629       // Parser Context
00630       stdair::BomRoot& _bomRoot;
00631       FareRuleStruct& _fareRule;
00632     };
00633     
00634   }
00635 
00636 
00638   //
00639   //  Entry class for the file parser
00640   //
00642     
00643   // //////////////////////////////////////////////////////////////////////
00644   FareRuleFileParser::
00645   FareRuleFileParser (stdair::BomRoot& ioBomRoot,
00646                       const stdair::Filename_T& iFilename)
00647     : _filename (iFilename), _bomRoot (ioBomRoot) {
00648     init();
00649   }
00650 
00651   // //////////////////////////////////////////////////////////////////////
00652   void FareRuleFileParser::init() {
00653     // Check that the file exists and is readable
00654     const bool doesExistAndIsReadable =
00655       stdair::BasFileMgr::doesExistAndIsReadable (_filename);
00656 
00657     if (doesExistAndIsReadable == false) {
00658       STDAIR_LOG_ERROR ("The fare schedule file " << _filename
00659                         << " does not exist or can not be  read.");
00660       
00661       throw FareInputFileNotFoundException ("The fare file " + _filename
00662                                             + " does not exist or can not be read");
00663     }
00664   }
00665     
00666   // //////////////////////////////////////////////////////////////////////
00667   void FareRuleFileParser::generateFareRules () {
00668       
00669     STDAIR_LOG_DEBUG ("Parsing fare input file: " << _filename);
00670 
00671     // File to be parsed
00672     const std::string* lFileName = &_filename;
00673     const char *lChar = (*lFileName).c_str();
00674     std::ifstream fileToBeParsed(lChar, std::ios_base::in);
00675 
00676     // Check if the filename exist and can be open
00677     if (fileToBeParsed.is_open() == false) {
00678       STDAIR_LOG_ERROR ("The fare file " << _filename << " can not be open."
00679                           << std::endl);
00680 
00681       throw FareInputFileNotFoundException ("The file " + _filename
00682                                             + " does not exist or can not be read");
00683     }
00684     
00685     // Create an input iterator
00686     stdair::base_iterator_t inputBegin (fileToBeParsed);
00687 
00688     // Convert input iterator to an iterator usable by spirit parser  
00689     stdair::iterator_t 
00690       start (boost::spirit::make_default_multi_pass (inputBegin));
00691     stdair::iterator_t end;
00692 
00693     // Initialise the parser (grammar) with the helper/staging structure.
00694     FareParserHelper::FareRuleParser<stdair::iterator_t> lFPParser(_bomRoot, _fareRule);
00695       
00696     // Launch the parsing of the file and, thanks to the doEndFare
00697     // call-back structure, the building of the whole BomRoot BOM
00698     const bool hasParsingBeenSuccesful = 
00699        boost::spirit::qi::phrase_parse (start, end, lFPParser,
00700                                         boost::spirit::ascii::space);
00701       
00702     if (hasParsingBeenSuccesful == false) {
00703       STDAIR_LOG_ERROR ("Parsing of fare input file: " << _filename
00704                         << " failed");
00705       throw FareFileParsingFailedException ("Parsing of fare input file: "
00706                                             + _filename + " failed");
00707     }
00708     
00709     if  (start != end) {
00710       STDAIR_LOG_ERROR ("Parsing of fare input file: " << _filename
00711                         << " failed");
00712       throw FareFileParsingFailedException ("Parsing of fare input file: "
00713                                             + _filename + " failed");
00714     }
00715     
00716     if (hasParsingBeenSuccesful == true && start == end) {
00717       STDAIR_LOG_DEBUG ("Parsing of fare input file: " << _filename
00718       << " succeeded");
00719     }
00720  
00721   }
00722     
00723 }