$treeview $search $mathjax
00001 // ////////////////////////////////////////////////////////////////////// 00002 // Import section 00003 // ////////////////////////////////////////////////////////////////////// 00004 // STL 00005 #include <cassert> 00006 // Boost 00007 #include <boost/date_time/date_iterator.hpp> 00008 // StdAir 00009 #include <stdair/stdair_types.hpp> 00010 #include <stdair/basic/BasConst_Inventory.hpp> 00011 #include <stdair/basic/BasConst_SellUpCurves.hpp> 00012 #include <stdair/bom/BomManager.hpp> 00013 #include <stdair/bom/BomRoot.hpp> 00014 #include <stdair/bom/Inventory.hpp> 00015 #include <stdair/bom/AirlineFeature.hpp> 00016 #include <stdair/bom/FlightDate.hpp> 00017 #include <stdair/bom/SegmentDate.hpp> 00018 #include <stdair/bom/SegmentCabin.hpp> 00019 #include <stdair/bom/FareFamily.hpp> 00020 #include <stdair/bom/BookingClass.hpp> 00021 #include <stdair/bom/LegDate.hpp> 00022 #include <stdair/bom/LegCabin.hpp> 00023 #include <stdair/bom/SimpleNestingStructure.hpp> 00024 #include <stdair/bom/NestingNode.hpp> 00025 #include <stdair/bom/Policy.hpp> 00026 #include <stdair/bom/Bucket.hpp> 00027 #include <stdair/bom/BomKeyManager.hpp> 00028 #include <stdair/factory/FacBomManager.hpp> 00029 #include <stdair/service/Logger.hpp> 00030 // AirInv 00031 #include <airinv/bom/FlightPeriodStruct.hpp> 00032 #include <airinv/command/InventoryGenerator.hpp> 00033 00034 namespace AIRINV { 00035 00036 // //////////////////////////////////////////////////////////////////// 00037 void InventoryGenerator:: 00038 createFlightDate (stdair::BomRoot& ioBomRoot, 00039 const FlightPeriodStruct& iFlightPeriod) { 00040 const stdair::AirlineCode_T& lAirlineCode = iFlightPeriod._airlineCode; 00041 00042 // Instantiate an inventory object (if not exist) 00043 // for the given key (airline code) 00044 stdair::Inventory* lInventory_ptr = stdair::BomManager:: 00045 getObjectPtr<stdair::Inventory> (ioBomRoot, lAirlineCode); 00046 if (lInventory_ptr == NULL) { 00047 stdair::InventoryKey lKey (lAirlineCode); 00048 lInventory_ptr = 00049 &stdair::FacBom<stdair::Inventory>::instance().create (lKey); 00050 stdair::FacBomManager::addToListAndMap (ioBomRoot, *lInventory_ptr); 00051 stdair::FacBomManager::linkWithParent (ioBomRoot, *lInventory_ptr); 00052 00053 // Add the airline feature object to the inventory 00054 const stdair::AirlineFeatureKey lAirlineFeatureKey (lAirlineCode); 00055 stdair::AirlineFeature& lAirlineFeature = 00056 stdair::FacBom<stdair::AirlineFeature>::instance().create (lAirlineFeatureKey); 00057 stdair::FacBomManager::setAirlineFeature (*lInventory_ptr, 00058 lAirlineFeature); 00059 stdair::FacBomManager::linkWithParent (*lInventory_ptr, lAirlineFeature); 00060 // Link the airline feature object with the top of the BOM tree 00061 stdair::FacBomManager::addToListAndMap (ioBomRoot, lAirlineFeature); 00062 } 00063 assert (lInventory_ptr != NULL); 00064 00065 // Generate all the dates corresponding to the period 00066 // and create the corresponding flight-dates. 00067 const stdair::DatePeriod_T lDateRange = iFlightPeriod._dateRange; 00068 00069 for (boost::gregorian::day_iterator itDate = lDateRange.begin(); 00070 itDate != lDateRange.end(); ++itDate) { 00071 const stdair::Date_T& currentDate = *itDate; 00072 00073 // Retrieve, for the current day, the Day-Of-the-Week (thanks to Boost) 00074 const unsigned short currentDoW = currentDate.day_of_week().as_number(); 00075 00076 // The FlightPeriod structure stores which Days (-Of-the-Week) are 00077 // active within the week. For each day (Mon., Tue., etc.), a boolean 00078 // states whether the Flight is active for that day. 00079 const stdair::DoWStruct& lDoWList = iFlightPeriod._dow; 00080 const bool isDoWActive = lDoWList.getStandardDayOfWeek (currentDoW); 00081 00082 if (isDoWActive == true) { 00083 createFlightDate (ioBomRoot, *lInventory_ptr, currentDate, 00084 iFlightPeriod); 00085 } 00086 } 00087 } 00088 00089 // //////////////////////////////////////////////////////////////////// 00090 void InventoryGenerator:: 00091 createFlightDate (stdair::BomRoot& ioBomRoot, 00092 stdair::Inventory& ioInventory, 00093 const stdair::Date_T& iFlightDate, 00094 const FlightPeriodStruct& iFlightPeriod) { 00095 // Create the FlightDateKey 00096 const stdair::FlightNumber_T& lFlightNumber = iFlightPeriod._flightNumber; 00097 stdair::FlightDateKey lFlightDateKey (lFlightNumber, iFlightDate); 00098 00099 // DEBUG 00100 // STDAIR_LOG_DEBUG ("Creating flight-date: " << lFlightDateKey.toString()); 00101 00102 // Check that the flight-date object is not already existing. If a 00103 // FlightDate object with the same key has already been created, 00104 // it means that the schedule input file is invalid (two flight-periods 00105 // are overlapping). 00106 stdair::FlightDate* lFlightDate_ptr = stdair::BomManager:: 00107 getObjectPtr<stdair::FlightDate> (ioInventory, lFlightDateKey.toString()); 00108 if (lFlightDate_ptr != NULL) { 00109 std::ostringstream oMessage; 00110 oMessage << ioInventory.describeKey() << ", " 00111 << lFlightDate_ptr->describeKey(); 00112 throw FlightDateDuplicationException (oMessage.str()); 00113 } 00114 00115 // Instantiate a fligh-date object with the given key (flight number and 00116 // flight date) 00117 lFlightDate_ptr = 00118 &stdair::FacBom<stdair::FlightDate>::instance().create (lFlightDateKey); 00119 stdair::FacBomManager::addToListAndMap (ioInventory, *lFlightDate_ptr); 00120 stdair::FacBomManager::linkWithParent (ioInventory, *lFlightDate_ptr); 00121 00122 // Iterate on the leg-dates 00123 stdair::Duration_T currentOffTime (0, 0, 0); 00124 stdair::AirportCode_T previousOffPoint; 00125 const LegStructList_T& lLegList = iFlightPeriod._legList; 00126 for (LegStructList_T::const_iterator itLeg = lLegList.begin(); 00127 itLeg != lLegList.end(); ++itLeg) { 00128 const LegStruct& lLeg = *itLeg; 00129 00130 // Create the leg-branch of the flight-date BOM 00131 stdair::LegDate& lLegDate = 00132 createLegDate (*lFlightDate_ptr, iFlightDate, lLeg); 00133 00134 // TODO: Check that the boarding date/time of the next leg is greated 00135 // than the off date/time of the current leg. Throw an exception 00136 // otherwise. 00137 00138 // TODO: specify, in the schedule input file specifications, that the 00139 // legs should be given in their natural order. 00140 // Then, replace the assertion by a thrown exception. 00141 // 00142 // Check that the legs are given in their natural order. If the schedule 00143 // input does not respect that assumption, the following assertion will 00144 // fail. 00145 if (itLeg != lLegList.begin()) { 00146 const stdair::AirportCode_T& currentBoardingPoint = 00147 lLegDate.getBoardingPoint(); 00148 assert (currentBoardingPoint == previousOffPoint); 00149 } 00150 00151 // Set the local variable for the next iteration 00152 previousOffPoint = lLegDate.getOffPoint(); 00153 } 00154 00155 // Iterate on the segment structures 00156 const SegmentStructList_T& lSegmentList = iFlightPeriod._segmentList; 00157 for (SegmentStructList_T::const_iterator itSegment = lSegmentList.begin(); 00158 itSegment != lSegmentList.end(); ++itSegment) { 00159 const SegmentStruct& lSegment = *itSegment; 00160 00161 createSegmentDate (ioBomRoot, *lFlightDate_ptr, lSegment); 00162 } 00163 00164 createRoutingLegKey (*lFlightDate_ptr); 00165 } 00166 00167 // //////////////////////////////////////////////////////////////////// 00168 void InventoryGenerator:: 00169 createRoutingLegKey (stdair::FlightDate& ioFlightDate) { 00170 00171 // Browse the list of segment-dates and create direct accesses 00172 // within each segment-date. 00173 const stdair::SegmentDateList_T& lSegmentDateList = 00174 stdair::BomManager::getList<stdair::SegmentDate> (ioFlightDate); 00175 for (stdair::SegmentDateList_T::const_iterator itSegmentDate = 00176 lSegmentDateList.begin(); 00177 itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) { 00178 00179 stdair::SegmentDate* lCurrentSegmentDate_ptr = *itSegmentDate; 00180 assert (lCurrentSegmentDate_ptr != NULL); 00181 00182 const stdair::AirportCode_T& lBoardingPoint = 00183 lCurrentSegmentDate_ptr->getBoardingPoint(); 00184 00185 stdair::AirportCode_T currentBoardingPoint = lBoardingPoint; 00186 const stdair::AirportCode_T& lOffPoint = 00187 lCurrentSegmentDate_ptr->getOffPoint(); 00188 00189 // Add a sanity check so as to ensure that the loop stops. If 00190 // there are more than MAXIMAL_NUMBER_OF_LEGS legs, there is 00191 // an issue somewhere in the code (not in the parser, as the 00192 // segments are derived from the legs thanks to the 00193 // FlightPeriodStruct::buildSegments() method). 00194 unsigned short i = 1; 00195 while (currentBoardingPoint != lOffPoint 00196 && i <= stdair::MAXIMAL_NUMBER_OF_LEGS_IN_FLIGHT) { 00197 // Retrieve the (unique) LegDate getting that Boarding Point 00198 stdair::LegDate& lLegDate = stdair::BomManager:: 00199 getObject<stdair::LegDate> (ioFlightDate, currentBoardingPoint); 00200 00201 // Link the SegmentDate and LegDate together 00202 const std::string& lRoutingKeyStr = lLegDate.describeRoutingKey(); 00203 lCurrentSegmentDate_ptr->addLegKey(lRoutingKeyStr); 00204 00205 // Prepare the next iteration 00206 currentBoardingPoint = lLegDate.getOffPoint(); 00207 ++i; 00208 } 00209 assert (i <= stdair::MAXIMAL_NUMBER_OF_LEGS_IN_FLIGHT); 00210 } 00211 } 00212 00213 // //////////////////////////////////////////////////////////////////// 00214 stdair::LegDate& InventoryGenerator:: 00215 createLegDate (stdair::FlightDate& ioFlightDate, 00216 const stdair::Date_T& iReferenceDate, 00217 const LegStruct& iLeg) { 00218 // Create the leg-date corresponding to the boarding point. 00219 stdair::LegDateKey lKey (iLeg._boardingPoint); 00220 stdair::LegDate& lLegDate = 00221 stdair::FacBom<stdair::LegDate>::instance().create (lKey); 00222 stdair::FacBomManager::addToListAndMap (ioFlightDate, lLegDate); 00223 stdair::FacBomManager::linkWithParent (ioFlightDate, lLegDate); 00224 00225 // Set the leg-date attributes 00226 iLeg.fill (iReferenceDate, lLegDate); 00227 00228 // Iterate on the cabins 00229 const LegCabinStructList_T& lCabinList = iLeg._cabinList; 00230 for (LegCabinStructList_T::const_iterator itCabin = lCabinList.begin(); 00231 itCabin != lCabinList.end(); ++itCabin) { 00232 const LegCabinStruct& lCabin = *itCabin; 00233 00234 // Create the leg-cabin-branch of the leg-date 00235 createLegCabin (lLegDate, lCabin); 00236 } 00237 00238 return lLegDate; 00239 } 00240 00241 // //////////////////////////////////////////////////////////////////// 00242 void InventoryGenerator:: 00243 createLegCabin (stdair::LegDate& ioLegDate, 00244 const LegCabinStruct& iCabin) { 00245 // Instantiate an leg-cabin object with the corresponding cabin code 00246 const stdair::LegCabinKey lKey (iCabin._cabinCode); 00247 stdair::LegCabin& lLegCabin = 00248 stdair::FacBom<stdair::LegCabin>::instance().create (lKey); 00249 stdair::FacBomManager::addToListAndMap (ioLegDate, lLegCabin); 00250 stdair::FacBomManager::linkWithParent (ioLegDate, lLegCabin); 00251 00252 // Set the Leg-Cabin attributes 00253 iCabin.fill (lLegCabin); 00254 00255 // Iterate on the bucket 00256 const BucketStructList_T& lBucketList = iCabin._bucketList; 00257 for (BucketStructList_T::const_iterator itBucket = lBucketList.begin(); 00258 itBucket != lBucketList.end(); ++itBucket) { 00259 const BucketStruct& lBucket = *itBucket; 00260 00261 // Create the bucket of the leg-cabin 00262 createBucket (lLegCabin, lBucket); 00263 } 00264 } 00265 00266 // //////////////////////////////////////////////////////////////////// 00267 void InventoryGenerator::createBucket (stdair::LegCabin& ioLegCabin, 00268 const BucketStruct& iBucket) { 00269 // Instantiate a bucket object with the corresponding seat index 00270 const stdair::BucketKey lKey (iBucket._seatIndex); 00271 stdair::Bucket& lBucket = 00272 stdair::FacBom<stdair::Bucket>::instance().create (lKey); 00273 stdair::FacBomManager::addToListAndMap (ioLegCabin, lBucket); 00274 stdair::FacBomManager::linkWithParent (ioLegCabin, lBucket); 00275 00276 // Set the Bucket attributes 00277 iBucket.fill (lBucket); 00278 } 00279 00280 // //////////////////////////////////////////////////////////////////// 00281 void InventoryGenerator:: 00282 createSegmentDate (stdair::BomRoot& ioBomRoot, 00283 stdair::FlightDate& ioFlightDate, 00284 const SegmentStruct& iSegment) { 00285 // Set the segment-date primary key 00286 const stdair::AirportCode_T& lBoardingPoint = iSegment._boardingPoint; 00287 const stdair::AirportCode_T& lOffPoint = iSegment._offPoint; 00288 stdair::SegmentDateKey lSegmentDateKey (lBoardingPoint, lOffPoint); 00289 // Instantiate an segment-date object with the key. 00290 stdair::SegmentDate& lSegmentDate = 00291 stdair::FacBom<stdair::SegmentDate>::instance().create (lSegmentDateKey); 00292 stdair::FacBomManager::addToListAndMap (ioFlightDate, lSegmentDate); 00293 stdair::FacBomManager::linkWithParent (ioFlightDate, lSegmentDate); 00294 00295 // Set the segment-date attributes 00296 iSegment.fill (lSegmentDate); 00297 00298 // Iterate on the Cabins 00299 const SegmentCabinStructList_T& lCabinList = iSegment._cabinList; 00300 for (SegmentCabinStructList_T::const_iterator itCabin = 00301 lCabinList.begin(); itCabin != lCabinList.end(); ++itCabin) { 00302 const SegmentCabinStruct& lCabin = *itCabin; 00303 00304 // Create the segment-cabin-branch of the segment-date BOM 00305 createSegmentCabin (ioBomRoot, lSegmentDate, lCabin); 00306 } 00307 } 00308 00309 // //////////////////////////////////////////////////////////////////// 00310 void InventoryGenerator:: 00311 createSegmentCabin (stdair::BomRoot& ioBomRoot, 00312 stdair::SegmentDate& ioSegmentDate, 00313 const SegmentCabinStruct& iCabin) { 00314 00315 // Instantiate an segment-cabin object with the corresponding cabin code 00316 stdair::SegmentCabinKey lKey (iCabin._cabinCode); 00317 stdair::SegmentCabin& lSegmentCabin = 00318 stdair::FacBom<stdair::SegmentCabin>::instance().create (lKey); 00319 00320 // Link the segment-cabin to its parent, the segment-date 00321 stdair::FacBomManager::addToListAndMap (ioSegmentDate, lSegmentCabin); 00322 stdair::FacBomManager::linkWithParent (ioSegmentDate, lSegmentCabin); 00323 00324 // Set the segment-cabin attributes 00325 iCabin.fill (lSegmentCabin); 00326 00327 // Create the list of fare families 00328 for (FareFamilyStructList_T::const_iterator itFareFamily = 00329 iCabin._fareFamilies.begin(); 00330 itFareFamily != iCabin._fareFamilies.end(); itFareFamily++) { 00331 const FareFamilyStruct& lFareFamilyStruct = *itFareFamily; 00332 00333 // Create the fare families and the booking classes. 00334 createFareFamily (ioBomRoot, lSegmentCabin, lFareFamilyStruct); 00335 } 00336 00337 const unsigned int lNbOfFareFamilies = iCabin._fareFamilies.size(); 00338 if (lNbOfFareFamilies > 1) { 00339 lSegmentCabin.activateFareFamily(); 00340 } 00341 00342 // Create the display nesting structure. 00343 createDisplayNestingStructure (lSegmentCabin); 00344 } 00345 00346 // //////////////////////////////////////////////////////////////////// 00347 void InventoryGenerator:: 00348 createFareFamily (stdair::BomRoot& ioBomRoot, 00349 stdair::SegmentCabin& ioSegmentCabin, 00350 const FareFamilyStruct& iFF) { 00351 // Instantiate an segment-cabin object with the corresponding cabin code 00352 stdair::FareFamilyKey lKey (iFF._familyCode); 00353 stdair::FareFamily& lFareFamily = 00354 stdair::FacBom<stdair::FareFamily>::instance().create (lKey); 00355 00356 // Link the fare family to its parent, the segment-cabin 00357 stdair::FacBomManager::addToListAndMap (ioSegmentCabin, lFareFamily); 00358 stdair::FacBomManager::linkWithParent (ioSegmentCabin, lFareFamily); 00359 00360 // Set the fare family attributes 00361 iFF.fill (lFareFamily); 00362 const stdair::FRAT5Curve_T& lFRAT5Curve = 00363 ioBomRoot.getFRAT5Curve (iFF._frat5CurveKey); 00364 lFareFamily.setFrat5Curve (lFRAT5Curve); 00365 const stdair::FFDisutilityCurve_T& lDisutilityCurve = 00366 ioBomRoot.getFFDisutilityCurve (iFF._ffDisutilityCurveKey); 00367 lFareFamily.setDisutilityCurve (lDisutilityCurve); 00368 00369 // Iterate on the classes 00370 const stdair::ClassList_String_T& lClassList = iFF._classes; 00371 for (stdair::ClassList_String_T::const_iterator itClass = 00372 lClassList.begin(); itClass != lClassList.end(); ++itClass) { 00373 // Transform the single-character class code into a STL string 00374 std::ostringstream ostr; 00375 ostr << *itClass; 00376 const stdair::ClassCode_T lClassCode (ostr.str()); 00377 00378 // Create the booking class branch of the segment-cabin BOM 00379 createClass (lFareFamily, lClassCode); 00380 } 00381 } 00382 00383 // //////////////////////////////////////////////////////////////////// 00384 void InventoryGenerator::createClass (stdair::FareFamily& ioFareFamily, 00385 const stdair::ClassCode_T& iClassCode) { 00386 00387 // Instantiate a booking class object with the given class code 00388 const stdair::BookingClassKey lClassKey (iClassCode); 00389 stdair::BookingClass& lClass = 00390 stdair::FacBom<stdair::BookingClass>::instance().create (lClassKey); 00391 00392 // Link the booking-class to the fare family 00393 stdair::FacBomManager::addToListAndMap (ioFareFamily, lClass); 00394 stdair::FacBomManager::linkWithParent (ioFareFamily, lClass); 00395 00396 // Link the booking-class to the segment-cabin 00397 stdair::SegmentCabin& lSegmentCabin = 00398 stdair::BomManager::getParent<stdair::SegmentCabin> (ioFareFamily); 00399 stdair::FacBomManager::addToListAndMap (lSegmentCabin, lClass); 00400 00401 // Link the booking-class to the segment-date 00402 stdair::SegmentDate& lSegmentDate = 00403 stdair::BomManager::getParent<stdair::SegmentDate> (lSegmentCabin); 00404 stdair::FacBomManager::addToListAndMap (lSegmentDate, lClass); 00405 } 00406 00407 // //////////////////////////////////////////////////////////////////// 00408 void InventoryGenerator:: 00409 createDisplayNestingStructure (stdair::SegmentCabin& ioSegmentCabin) { 00410 // Create the nesting structure. 00411 stdair::NestingStructureKey lKey (stdair::DISPLAY_NESTING_STRUCTURE_CODE); 00412 stdair::SimpleNestingStructure& lNestingStructure = 00413 stdair::FacBom<stdair::SimpleNestingStructure>::instance().create(lKey); 00414 stdair::FacBomManager::addToListAndMap (ioSegmentCabin, lNestingStructure); 00415 stdair::FacBomManager::linkWithParent (ioSegmentCabin, lNestingStructure); 00416 00417 // Browse the list of booking classes and create the nesting structure 00418 // based on that list. Each nesting node consists of a booking class. 00419 const stdair::BookingClassList_T& lBCList = 00420 stdair::BomManager::getList<stdair::BookingClass>(ioSegmentCabin); 00421 for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin(); 00422 itBC != lBCList.end(); ++itBC) { 00423 stdair::BookingClass* lBC_ptr = *itBC; 00424 assert (lBC_ptr != NULL); 00425 00426 // Create a nesting node 00427 stdair::NestingNodeCode_T lNodeCode (lBC_ptr->describeKey()); 00428 stdair::NestingNodeKey lNodeKey (lNodeCode); 00429 stdair::NestingNode& lNestingNode = 00430 stdair::FacBom<stdair::NestingNode>::instance().create (lNodeKey); 00431 stdair::FacBomManager::addToList (lNestingStructure, lNestingNode); 00432 stdair::FacBomManager::linkWithParent (lNestingStructure, lNestingNode); 00433 00434 // Add the booking class to the node. 00435 stdair::FacBomManager::addToList (lNestingNode, *lBC_ptr); 00436 } 00437 } 00438 }