SimFQT Logo  0.1.2
C++ Simulated Fare Quote System Library
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/bom/BomRoot.hpp>
00011 #include <stdair/service/Logger.hpp>
00012 // SIMFQT
00013 #include <simfqt/command/FareParserHelper.hpp>
00014 #include <simfqt/command/FareRuleGenerator.hpp>
00015 
00016 namespace SIMFQT {
00017 
00018   namespace FareParserHelper {
00019       
00020     // //////////////////////////////////////////////////////////////////
00021     //  Semantic actions
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       // DEBUG
00042       //STDAIR_LOG_DEBUG ( "Fare Id: " << _fareRule.getFareID ());
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        // DEBUG
00065        //STDAIR_LOG_DEBUG ( "Origin: " << _fareRule.getOrigin ());
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        // DEBUG
00081        //STDAIR_LOG_DEBUG ( "Destination: " << _fareRule.getDestination ());
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         // ERROR
00099         STDAIR_LOG_ERROR ("Invalid trip type  " << lTripType);
00100       }                       
00101       // DEBUG
00102       //STDAIR_LOG_DEBUG ("TripType: " << _fareRule.getTripType ());
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       // DEBUG
00119       //STDAIR_LOG_DEBUG ("Date Range Start: " << _fareRule.getDateRangeStart ());
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       // As a Boost date period (DatePeriod_T) defines the last day of
00134       // the period to be end-date - one day, we have to add one day to that
00135       // end date before.
00136       const stdair::DateOffset_T oneDay (1);
00137       const stdair::Date_T lBoostDateEnd = lDateEnd + oneDay;
00138       _fareRule.setDateRangeEnd (lBoostDateEnd);
00139        // DEBUG
00140       //STDAIR_LOG_DEBUG ("Date Range End: " << _fareRule.getDateRangeEnd ());
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       // DEBUG
00156       //STDAIR_LOG_DEBUG ("Time Range Start: " << _fareRule.getTimeRangeStart ());
00157       // Reset the number of seconds
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       // DEBUG
00174       //STDAIR_LOG_DEBUG ("Time Range End: " << _fareRule.getTimeRangeEnd ());
00175       // Reset the number of seconds
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         // ERROR
00197         STDAIR_LOG_ERROR ("Invalid point of sale " << lPOS);
00198       }
00199       // DEBUG
00200       //STDAIR_LOG_DEBUG ("POS: " << _fareRule.getPOS ());
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       // DEBUG
00220       //STDAIR_LOG_DEBUG ("Cabin Code: " << _fareRule.getCabinCode ());                 
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         // ERROR
00238         STDAIR_LOG_ERROR ("Invalid channel " << lChannel);
00239       }
00240       _fareRule.setChannel (lChannel);
00241       // DEBUG
00242       //STDAIR_LOG_DEBUG ("Channel: " << _fareRule.getChannel ());
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       // DEBUG
00258       //STDAIR_LOG_DEBUG ( "Advance Purchase: " << _fareRule.getAdvancePurchase ());
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           // DEBUG
00277           STDAIR_LOG_DEBUG ("Invalid saturdayStay char " << iSaturdayStay);
00278         }
00279       }
00280       const stdair::SaturdayStay_T lSaturdayStay (lBool);
00281       _fareRule.setSaturdayStay (lSaturdayStay);
00282       // DEBUG
00283       //STDAIR_LOG_DEBUG ("Saturday Stay: " << _fareRule.getSaturdayStay ());
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           // DEBUG
00303           STDAIR_LOG_DEBUG ("Invalid change fees char " << iChangefees);
00304         }
00305       }
00306       const stdair::ChangeFees_T lChangefees (lBool);
00307       _fareRule.setChangeFees (lChangefees);
00308       // DEBUG
00309       //STDAIR_LOG_DEBUG ("Change fees: " << _fareRule.getChangeFees ());
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            // DEBUG
00328            STDAIR_LOG_DEBUG ("Invalid non refundable char " << iNonRefundable);
00329          }
00330        }
00331        const stdair::NonRefundable_T lNonRefundable (lBool);
00332        _fareRule.setNonRefundable (lNonRefundable);
00333        // DEBUG
00334        //STDAIR_LOG_DEBUG ("Non refundable: " << _fareRule.getNonRefundable ());
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       // DEBUG
00350       //STDAIR_LOG_DEBUG ("Minimum Stay: " << _fareRule.getMinimumStay ());
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       // DEBUG
00366       //STDAIR_LOG_DEBUG ("Fare: " << _fareRule.getFare ());
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       // Insertion of this airline Code list in the whole AirlineCode name
00382       _fareRule.addAirlineCode (lAirlineCode);
00383       // DEBUG
00384       //STDAIR_LOG_DEBUG ( "Airline code: " << lAirlineCode);
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       // Insertion of this class Code list in the whole classCode name
00406       _fareRule.addClassCode (lClassCode);
00407       // DEBUG
00408       //STDAIR_LOG_DEBUG ("Class Code: " << lClassCode);
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       // DEBUG
00424       //STDAIR_LOG_DEBUG ("Do End");
00425       // Generation of the fare rule object.
00426       FareRuleGenerator::createAirportPair (_bomRoot, _fareRule);
00427       STDAIR_LOG_DEBUG(_fareRule.describe());
00428     }  
00429 
00430     // ///////////////////////////////////////////////////////////////////
00431     //
00432     //  Utility Parsers
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     //  (Boost Spirit) Grammar Definition
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       //BOOST_SPIRIT_DEBUG_NODE (FareRuleParser);
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   //  Entry class for the file parser
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     // Check that the file exists and is readable
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     // File to be parsed
00613     const std::string* lFileName = &_filename;
00614     const char *lChar = (*lFileName).c_str();
00615     std::ifstream fileToBeParsed(lChar, std::ios_base::in);
00616 
00617     // Check if the filename exist and can be open
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     // Create an input iterator
00627     stdair::base_iterator_t inputBegin (fileToBeParsed);
00628 
00629     // Convert input iterator to an iterator usable by spirit parser  
00630     stdair::iterator_t 
00631       start (boost::spirit::make_default_multi_pass (inputBegin));
00632     stdair::iterator_t end;
00633 
00634     // Initialise the parser (grammar) with the helper/staging structure.
00635     FareParserHelper::FareRuleParser lFPParser(_bomRoot, _fareRule);
00636       
00637     // Launch the parsing of the file and, thanks to the doEndFare
00638     // call-back structure, the building of the whole BomRoot BOM
00639     const bool hasParsingBeenSuccesful = 
00640        boost::spirit::qi::phrase_parse (start, end, lFPParser,
00641                                         boost::spirit::ascii::space);
00642       
00643     if (hasParsingBeenSuccesful == false) {
00644       // TODO: decide whether to throw an exceqption
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       // TODO: decide whether to throw an exception
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 }