$treeview $search $mathjax
AirInv Logo  1.00.0
$projectbrief
$projectbrief
$searchbox

InventoryBuilder.cpp

Go to the documentation of this file.
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/basic/BasConst_BookingClass.hpp>
00010 #include <stdair/basic/BasConst_Yield.hpp>
00011 #include <stdair/basic/BasConst_Inventory.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/Bucket.hpp>
00024 #include <stdair/bom/BomKeyManager.hpp>
00025 #include <stdair/bom/ParsedKey.hpp>
00026 #include <stdair/bom/BomRetriever.hpp>
00027 #include <stdair/command/CmdCloneBomManager.hpp>
00028 #include <stdair/factory/FacBom.hpp>
00029 #include <stdair/factory/FacBomManager.hpp>
00030 #include <stdair/service/Logger.hpp>
00031 // AirInv
00032 #include <airinv/AIRINV_Types.hpp>
00033 #include <airinv/bom/FlightDateStruct.hpp>
00034 #include <airinv/command/InventoryBuilder.hpp>
00035 
00036 namespace AIRINV {
00037 
00038   // ////////////////////////////////////////////////////////////////////
00039   void InventoryBuilder::
00040   buildInventory (stdair::BomRoot& ioBomRoot,
00041                   const FlightDateStruct& iFlightDateStruct) {
00042     const stdair::AirlineCode_T& lAirlineCode = iFlightDateStruct._airlineCode;
00043  
00044     // Instantiate an inventory object (if not exist)
00045     // for the given key (airline code)
00046     stdair::Inventory* lInventory_ptr = stdair::BomManager::
00047       getObjectPtr<stdair::Inventory> (ioBomRoot, lAirlineCode);
00048     if (lInventory_ptr == NULL) {
00049       stdair::InventoryKey lKey (lAirlineCode);
00050       lInventory_ptr =
00051         &stdair::FacBom<stdair::Inventory>::instance().create (lKey);
00052       stdair::FacBomManager::addToListAndMap (ioBomRoot, *lInventory_ptr);
00053       stdair::FacBomManager::linkWithParent (ioBomRoot, *lInventory_ptr);
00054 
00055       // Add the airline feature object to the inventory
00056       const stdair::AirlineFeatureKey lAirlineFeatureKey (lAirlineCode);
00057       stdair::AirlineFeature& lAirlineFeature =
00058         stdair::FacBom<stdair::AirlineFeature>::instance().create (lAirlineFeatureKey);
00059       stdair::FacBomManager::setAirlineFeature (*lInventory_ptr,
00060                                                 lAirlineFeature);
00061       stdair::FacBomManager::linkWithParent (*lInventory_ptr, lAirlineFeature);
00062       // Link the airline feature object with the top of the BOM tree
00063       stdair::FacBomManager::addToListAndMap (ioBomRoot, lAirlineFeature);
00064     }
00065     assert (lInventory_ptr != NULL);
00066 
00067     // Build the flight-date within the inventory.
00068     buildFlightDate (*lInventory_ptr, iFlightDateStruct);
00069   }
00070 
00071   // ////////////////////////////////////////////////////////////////////
00072   void InventoryBuilder::
00073   buildFlightDate (stdair::Inventory& ioInventory,
00074                    const FlightDateStruct& iFlightDateStruct) {
00075     // Create the FlightDateKey
00076     const stdair::FlightDateKey lFlightDateKey (iFlightDateStruct._flightNumber,
00077                                                 iFlightDateStruct._flightDate);
00078 
00079     // Check that the flight-date object is not already existing. If a
00080     // flight-date object with the same key has already been created,
00081     // then just update it, ifnot, create a flight-date and update it.
00082     stdair::FlightDate* lFlightDate_ptr = stdair::BomManager::
00083       getObjectPtr<stdair::FlightDate> (ioInventory, lFlightDateKey.toString());
00084     if (lFlightDate_ptr == NULL) {
00085       // Instantiate a flighy-date object for the given key (flight number and
00086       // flight date)
00087       lFlightDate_ptr =
00088         &stdair::FacBom<stdair::FlightDate>::instance().create (lFlightDateKey);
00089       stdair::FacBomManager::addToListAndMap (ioInventory, *lFlightDate_ptr);
00090       stdair::FacBomManager::linkWithParent (ioInventory, *lFlightDate_ptr);
00091     }
00092     assert (lFlightDate_ptr != NULL);
00093 
00094     // Update the BOM flight-date with the attributes of the flight-date struct.
00095     
00096     // Browse the list of leg-date struct and segment-date struct and
00097     // create the corresponding BOM.
00098     for (LegStructList_T::const_iterator itLegDate =
00099            iFlightDateStruct._legList.begin();
00100          itLegDate != iFlightDateStruct._legList.end(); ++itLegDate) {
00101       const LegStruct& lCurrentLegDateStruct = *itLegDate;
00102       buildLegDate (*lFlightDate_ptr, lCurrentLegDateStruct);
00103     }
00104 
00105     for (SegmentStructList_T::const_iterator itSegmentDate =
00106            iFlightDateStruct._segmentList.begin();
00107          itSegmentDate != iFlightDateStruct._segmentList.end();
00108          ++itSegmentDate) {
00109       const SegmentStruct& lCurrentSegmentDateStruct = *itSegmentDate;
00110       buildSegmentDate (*lFlightDate_ptr, lCurrentSegmentDateStruct);
00111     } 
00112 
00113     buildRoutingLegKey (*lFlightDate_ptr);
00114   }
00115 
00116   // ////////////////////////////////////////////////////////////////////
00117   void InventoryBuilder::
00118   buildLegDate (stdair::FlightDate& ioFlightDate,
00119                 const LegStruct& iLegDateStruct) {
00120     // Check that the leg-date object is not already existing. If a
00121     // leg-date object with the same key has already been created,
00122     // then just update it, ifnot, create a leg-date and update it.
00123     stdair::LegDate* lLegDate_ptr = stdair::BomManager::
00124       getObjectPtr<stdair::LegDate>(ioFlightDate, iLegDateStruct._boardingPoint);
00125 
00126     if (lLegDate_ptr == NULL) {
00127       // Instantiate a leg-date object for the given key (boarding point);
00128       stdair::LegDateKey lKey (iLegDateStruct._boardingPoint);
00129       lLegDate_ptr = &stdair::FacBom<stdair::LegDate>::instance().create (lKey);
00130       stdair::FacBomManager::addToListAndMap (ioFlightDate, *lLegDate_ptr);
00131       stdair::FacBomManager::linkWithParent (ioFlightDate, *lLegDate_ptr);
00132     }
00133     assert (lLegDate_ptr != NULL);
00134 
00135     // Update the BOM leg-date with the attributes of the leg-date struct.
00136     iLegDateStruct.fill (*lLegDate_ptr);
00137 
00138     // Browse the list of leg-cabin structs and create the corresponding BOM.
00139     for (LegCabinStructList_T::const_iterator itLegCabin =
00140            iLegDateStruct._cabinList.begin();
00141          itLegCabin != iLegDateStruct._cabinList.end(); ++itLegCabin) {
00142       const LegCabinStruct& lCurrentLegCabinStruct = *itLegCabin;
00143       buildLegCabin (*lLegDate_ptr, lCurrentLegCabinStruct);
00144     }
00145   }  
00146 
00147   // ////////////////////////////////////////////////////////////////////
00148   void InventoryBuilder::
00149   buildRoutingLegKey (stdair::FlightDate& ioFlightDate) {
00150 
00151     // Browse the list of segment-dates and create direct accesses
00152     // within each segment-date.
00153     const stdair::SegmentDateList_T& lSegmentDateList = 
00154       stdair::BomManager::getList<stdair::SegmentDate> (ioFlightDate);
00155     for (stdair::SegmentDateList_T::const_iterator itSegmentDate = 
00156            lSegmentDateList.begin();
00157          itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) {
00158 
00159       stdair::SegmentDate* lCurrentSegmentDate_ptr = *itSegmentDate;
00160       assert (lCurrentSegmentDate_ptr != NULL);
00161 
00162       /*
00163        * If the segment is just marketed by this carrier,
00164        * retrieve the operating segment and call the createDirectAcces
00165        * method on its parent (flight date).
00166        */
00167       const stdair::SegmentDate* lOperatingSegmentDate_ptr =
00168         lCurrentSegmentDate_ptr->getOperatingSegmentDate ();
00169       if (lOperatingSegmentDate_ptr == NULL) {
00170 
00171         const stdair::AirportCode_T& lBoardingPoint =
00172           lCurrentSegmentDate_ptr->getBoardingPoint();
00173         
00174         stdair::AirportCode_T currentBoardingPoint = lBoardingPoint;
00175         const stdair::AirportCode_T& lOffPoint =
00176           lCurrentSegmentDate_ptr->getOffPoint();
00177         
00178         // Add a sanity check so as to ensure that the loop stops. If
00179         // there are more than MAXIMAL_NUMBER_OF_LEGS legs, there is
00180         // an issue somewhere in the code (not in the parser, as the
00181         // segments are derived from the legs thanks to the
00182         // FlightPeriodStruct::buildSegments() method).
00183         unsigned short i = 1;
00184         while (currentBoardingPoint != lOffPoint
00185                && i <= stdair::MAXIMAL_NUMBER_OF_LEGS_IN_FLIGHT) {
00186           // Retrieve the (unique) LegDate getting that Boarding Point
00187           stdair::LegDate& lLegDate = stdair::BomManager::
00188             getObject<stdair::LegDate> (ioFlightDate, currentBoardingPoint);
00189           
00190           // Link the SegmentDate and LegDate together
00191           const std::string& lRoutingKeyStr = lLegDate.describeRoutingKey();
00192           lCurrentSegmentDate_ptr->addLegKey(lRoutingKeyStr);
00193           
00194           // Prepare the next iteration
00195           currentBoardingPoint = lLegDate.getOffPoint();
00196           ++i;
00197         }
00198         assert (i <= stdair::MAXIMAL_NUMBER_OF_LEGS_IN_FLIGHT);
00199       }
00200     }
00201   }
00202 
00203   // ////////////////////////////////////////////////////////////////////
00204   void InventoryBuilder::
00205   buildLegCabin (stdair::LegDate& ioLegDate,
00206                  const LegCabinStruct& iLegCabinStruct) {
00207     // Check that the leg-cabin object is not already existing. If a
00208     // leg-cabin object with the same key has already been created,
00209     // then just update it, ifnot, create a leg-cabin and update it.
00210     stdair::LegCabin* lLegCabin_ptr = stdair::BomManager::
00211       getObjectPtr<stdair::LegCabin> (ioLegDate, iLegCabinStruct._cabinCode);
00212     if (lLegCabin_ptr == NULL) {
00213       // Instantiate a leg-cabin object for the given key (cabin code);
00214       stdair::LegCabinKey lKey (iLegCabinStruct._cabinCode);
00215       lLegCabin_ptr = &stdair::FacBom<stdair::LegCabin>::instance().create(lKey);
00216       stdair::FacBomManager::addToListAndMap (ioLegDate, *lLegCabin_ptr);
00217       stdair::FacBomManager::linkWithParent (ioLegDate, *lLegCabin_ptr);
00218     }
00219     assert (lLegCabin_ptr != NULL);
00220 
00221     // TODO: Update the BOM leg-cabin with the attributes of the
00222     // leg-cabin struct.
00223     iLegCabinStruct.fill (*lLegCabin_ptr);
00224 
00225     // Browse the list of bucket structs and create the corresponding BOM.
00226     for (BucketStructList_T::const_iterator itBucket =
00227            iLegCabinStruct._bucketList.begin();
00228          itBucket != iLegCabinStruct._bucketList.end(); ++itBucket) {
00229       const BucketStruct& lCurrentBucketStruct = *itBucket;
00230       buildBucket (*lLegCabin_ptr, lCurrentBucketStruct);
00231     }
00232   }
00233 
00234   // ////////////////////////////////////////////////////////////////////
00235   void InventoryBuilder::buildBucket (stdair::LegCabin& ioLegCabin,
00236                                       const BucketStruct& iBucketStruct) {
00237     // Create the BucketKey
00238     const stdair::BucketKey lBucketKey (iBucketStruct._seatIndex);
00239 
00240     // Check that the bucket object is not already existing. If a
00241     // bucket object with the same key has already been created,
00242     // then just update it, ifnot, create a bucket and update it.
00243     stdair::Bucket* lBucket_ptr = stdair::BomManager::
00244       getObjectPtr<stdair::Bucket> (ioLegCabin, lBucketKey.toString());
00245     if (lBucket_ptr == NULL) {
00246       // Instantiate a bucket object for the given key (seat index);
00247       stdair::BucketKey lKey (iBucketStruct._seatIndex);
00248       lBucket_ptr = &stdair::FacBom<stdair::Bucket>::instance().create (lKey);
00249       stdair::FacBomManager::addToListAndMap (ioLegCabin, *lBucket_ptr);
00250       stdair::FacBomManager::linkWithParent (ioLegCabin, *lBucket_ptr);
00251     }
00252     assert (lBucket_ptr != NULL);
00253 
00254     //
00255     iBucketStruct.fill (*lBucket_ptr);
00256   }
00257 
00258   // ////////////////////////////////////////////////////////////////////
00259   void InventoryBuilder::
00260   buildSegmentDate (stdair::FlightDate& ioFlightDate,
00261                     const SegmentStruct& iSegmentDateStruct) {
00262     // Check that the segment-date object is not already existing. If a
00263     // segment-date object with the same key has already been created,
00264     // then just update it, ifnot, create a segment-date and update it.
00265     const stdair::SegmentDateKey
00266       lSegmentDateKey (iSegmentDateStruct._boardingPoint,
00267                        iSegmentDateStruct._offPoint);
00268     stdair::SegmentDate* lSegmentDate_ptr = stdair::BomManager::
00269       getObjectPtr<stdair::SegmentDate>(ioFlightDate,lSegmentDateKey.toString());
00270     if (lSegmentDate_ptr == NULL) {
00271       // Instantiate a segment-date object for the given key (boarding
00272       // and off points);
00273       lSegmentDate_ptr =  &stdair::FacBom<stdair::SegmentDate>::
00274         instance().create (lSegmentDateKey);
00275       stdair::FacBomManager::addToListAndMap (ioFlightDate, *lSegmentDate_ptr);
00276       stdair::FacBomManager::linkWithParent (ioFlightDate, *lSegmentDate_ptr);
00277     }
00278     assert (lSegmentDate_ptr != NULL);
00279 
00280     // Update the BOM segment-date with the attributes of the
00281     // segment-date struct.
00282     iSegmentDateStruct.fill (*lSegmentDate_ptr);
00283 
00284     // Browse the list of segment-cabin struct and create the corresponding BOM.
00285     for (SegmentCabinStructList_T::const_iterator itSegmentCabin =
00286            iSegmentDateStruct._cabinList.begin();
00287          itSegmentCabin != iSegmentDateStruct._cabinList.end(); 
00288          ++itSegmentCabin) {
00289       const SegmentCabinStruct& lCurrentSegmentCabinStruct = *itSegmentCabin;
00290       buildSegmentCabin (*lSegmentDate_ptr, lCurrentSegmentCabinStruct);
00291     }
00292   }
00293 
00294   // ////////////////////////////////////////////////////////////////////
00295   void InventoryBuilder::
00296   buildSegmentCabin (stdair::SegmentDate& ioSegmentDate,
00297                      const SegmentCabinStruct& iSegmentCabinStruct) {
00298     // Check that the segment-cabin object is not already existing. If a
00299     // segment-cabin object with the same key has already been created,
00300     // then just update it, ifnot, create a segment-cabin and update it.
00301     stdair::SegmentCabin* lSegmentCabin_ptr = stdair::BomManager::
00302       getObjectPtr<stdair::SegmentCabin> (ioSegmentDate,
00303                                           iSegmentCabinStruct._cabinCode);
00304     if (lSegmentCabin_ptr == NULL) {
00305       // Instantiate a segment-cabin object for the given key (cabin code);
00306       stdair::SegmentCabinKey lKey (iSegmentCabinStruct._cabinCode);
00307       lSegmentCabin_ptr = 
00308         &stdair::FacBom<stdair::SegmentCabin>::instance().create (lKey);
00309 
00310       // Link the segment-cabin to the segment-date
00311       stdair::FacBomManager::addToListAndMap (ioSegmentDate, *lSegmentCabin_ptr);
00312       stdair::FacBomManager::linkWithParent (ioSegmentDate, *lSegmentCabin_ptr);
00313     }
00314     assert (lSegmentCabin_ptr != NULL);
00315 
00316     // TODO: Update the BOM segment-cabin with the attributes of the
00317     // segment-cabin struct.
00318     iSegmentCabinStruct.fill (*lSegmentCabin_ptr);
00319 
00320     // Browse the list of fare family struct and create the corresponding BOM.
00321     for (FareFamilyStructList_T::const_iterator itFareFamily =
00322            iSegmentCabinStruct._fareFamilies.begin();
00323          itFareFamily != iSegmentCabinStruct._fareFamilies.end(); 
00324          ++itFareFamily) {
00325       const FareFamilyStruct& lCurrentFareFamilyStruct = *itFareFamily;
00326       buildFareFamily (*lSegmentCabin_ptr, lCurrentFareFamilyStruct);
00327     }
00328   }
00329 
00330   // ////////////////////////////////////////////////////////////////////
00331   void InventoryBuilder::
00332   buildFareFamily (stdair::SegmentCabin& ioSegmentCabin,
00333                    const FareFamilyStruct& iFareFamilyStruct) {
00334 
00335     // Check that the fare family object is not already existing. If a
00336     // fare family object with the same key has already been created,
00337     // then just update it. If not, create a fare family and update it.
00338     stdair::FareFamily* lFareFamily_ptr = stdair::BomManager::
00339       getObjectPtr<stdair::FareFamily> (ioSegmentCabin,
00340                                         iFareFamilyStruct._familyCode);
00341     if (lFareFamily_ptr == NULL) {
00342       // Instantiate a fare family object for the given key (fare family code);
00343       const stdair::FareFamilyKey lFFKey (iFareFamilyStruct._familyCode);
00344       lFareFamily_ptr = 
00345         &stdair::FacBom<stdair::FareFamily>::instance().create (lFFKey);
00346 
00347       // Link the fare family to the segment-cabin
00348       stdair::FacBomManager::addToListAndMap (ioSegmentCabin, *lFareFamily_ptr);
00349       stdair::FacBomManager::linkWithParent (ioSegmentCabin, *lFareFamily_ptr);
00350     }
00351     assert (lFareFamily_ptr != NULL);
00352 
00353     // TODO: Upcabin the BOM fare family with the attributes of the
00354     // fare family struct.
00355     iFareFamilyStruct.fill (*lFareFamily_ptr);
00356 
00357     // Browse the list of booking-class struct and create the corresponding BOM.
00358     for (BookingClassStructList_T::const_iterator itBookingClass =
00359            iFareFamilyStruct._classList.begin();
00360          itBookingClass != iFareFamilyStruct._classList.end(); 
00361          ++itBookingClass) {
00362       const BookingClassStruct& lCurrentBookingClassStruct = *itBookingClass;
00363       buildBookingClass (*lFareFamily_ptr, lCurrentBookingClassStruct);
00364     }
00365   }
00366 
00367   // ////////////////////////////////////////////////////////////////////
00368   void InventoryBuilder::
00369   buildBookingClass (stdair::FareFamily& ioFareFamily,
00370                      const BookingClassStruct& iBookingClassStruct) {
00371 
00372     // Check that the booking class object is not already existing. If a
00373     // booking-class object with the same key has already been created,
00374     // then just update it. If not, create a booking-class and update it.
00375     stdair::BookingClass* lBookingClass_ptr = stdair::BomManager::
00376       getObjectPtr<stdair::BookingClass> (ioFareFamily,
00377                                           iBookingClassStruct._classCode);
00378     if (lBookingClass_ptr == NULL) {
00379       // Instantiate a booking class object for the given key (class code);
00380       const stdair::BookingClassKey lClassKey (iBookingClassStruct._classCode);
00381       lBookingClass_ptr = 
00382         &stdair::FacBom<stdair::BookingClass>::instance().create (lClassKey);
00383 
00384       // Link the booking-class to the fare family
00385       stdair::FacBomManager::addToListAndMap (ioFareFamily, *lBookingClass_ptr);
00386       stdair::FacBomManager::linkWithParent (ioFareFamily, *lBookingClass_ptr);
00387 
00388       // Link the booking-class to the segment-cabin
00389       stdair::SegmentCabin& lSegmentCabin =
00390         stdair::BomManager::getParent<stdair::SegmentCabin> (ioFareFamily);
00391       stdair::FacBomManager::addToListAndMap (lSegmentCabin, *lBookingClass_ptr);
00392 
00393       // Link the booking-class to the segment-date
00394       stdair::SegmentDate& lSegmentDate =
00395         stdair::BomManager::getParent<stdair::SegmentDate> (lSegmentCabin);
00396       stdair::FacBomManager::addToListAndMap (lSegmentDate, *lBookingClass_ptr);
00397     }
00398     assert (lBookingClass_ptr != NULL);
00399 
00400     // TODO: Upcabin the BOM booking-class with the attributes of the
00401     // booking-class struct.
00402     iBookingClassStruct.fill (*lBookingClass_ptr);
00403   }
00404 
00405   // ////////////////////////////////////////////////////////////////////
00406   void InventoryBuilder::buildPartnerInventories (stdair::BomRoot& ioBomRoot) {
00407 
00408     // Browse the list of inventories to build partner inventories
00409     // within each inventory.
00410     const stdair::InventoryList_T& lInvList =
00411       stdair::BomManager::getList<stdair::Inventory> (ioBomRoot);
00412     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00413          itInv != lInvList.end(); ++itInv) {
00414       stdair::Inventory* lCurrentInv_ptr = *itInv;
00415       assert (lCurrentInv_ptr != NULL);
00416 
00417       buildPartnerInventories (ioBomRoot, *lCurrentInv_ptr);
00418     }
00419   }
00420 
00421   // ////////////////////////////////////////////////////////////////////
00422   void InventoryBuilder::buildPartnerInventories (stdair::BomRoot& ioBomRoot,
00423                                                   stdair::Inventory& ioInventory) {
00424     
00425     // Browse the list of flight-dates to build partner inventories.
00426     const stdair::FlightDateList_T& lFlightDateList = 
00427       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
00428     for (stdair::FlightDateList_T::const_iterator itFlightDate = 
00429            lFlightDateList.begin();
00430          itFlightDate != lFlightDateList.end(); ++itFlightDate) {
00431       stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
00432       assert (lCurrentFlightDate_ptr != NULL);
00433 
00434       buildPartnerInventories (ioBomRoot, ioInventory, *lCurrentFlightDate_ptr);
00435     }
00436     
00437   }
00438 
00439   // ////////////////////////////////////////////////////////////////////
00440   void InventoryBuilder::buildPartnerInventories (stdair::BomRoot& ioBomRoot,
00441                                                   stdair::Inventory& ioInventory,
00442                                                   stdair::FlightDate& iFlightDate) {
00443     
00444     // Browse the list of flight-dates to build partner inventories.
00445     const stdair::SegmentDateList_T& lSegmentDateList = 
00446       stdair::BomManager::getList<stdair::SegmentDate> (iFlightDate);
00447     for (stdair::SegmentDateList_T::const_iterator itSegmentDate = 
00448            lSegmentDateList.begin();
00449          itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) {
00450 
00451       stdair::SegmentDate* lCurrentSegmentDate_ptr = *itSegmentDate;
00452       assert (lCurrentSegmentDate_ptr != NULL); 
00453 
00454       const stdair::RoutingLegKeyList_T& lRoutingLegKeyList = 
00455         lCurrentSegmentDate_ptr->getLegKeyList ();
00456 
00457       // Browse the list of routing leg keys.
00458       for (stdair::RoutingLegKeyList_T::const_iterator itRoutingLegKey = 
00459            lRoutingLegKeyList.begin();
00460          itRoutingLegKey != lRoutingLegKeyList.end(); ++itRoutingLegKey) {
00461 
00462         // Extract the operating airline code
00463         const stdair::ParsedKey& lParsedKey = 
00464           stdair::BomKeyManager::extractKeys (*itRoutingLegKey);
00465         const stdair::InventoryKey& lInventoryKey = 
00466           lParsedKey.getInventoryKey();
00467         const stdair::AirlineCode_T lOperatingAirlineCode = 
00468           lInventoryKey.getAirlineCode();
00469 
00470         // Extract the current airline code
00471         const stdair::AirlineCode_T lAirlineCode = 
00472           iFlightDate.getAirlineCode();
00473 
00474         // If the operating airline is not the current one
00475         if (lOperatingAirlineCode != lAirlineCode) {
00476           
00477           // Look for the inventory of the partner within the Bom root
00478           stdair::Inventory* lInventory_ptr =
00479             stdair::BomRetriever::
00480             retrieveInventoryFromKey (ioBomRoot, lOperatingAirlineCode);
00481 
00482           // Build the current segment full key
00483           std::ostringstream lRoutingSegment;
00484           lRoutingSegment << iFlightDate.getAirlineCode() << ";"
00485                           << iFlightDate.describeKey() << ";"
00486                           << lCurrentSegmentDate_ptr->getBoardingPoint() << ";"
00487                           << lCurrentSegmentDate_ptr->getOffPoint();
00488 
00489           // If such inventory does not exist, throw an exception
00490           if (lInventory_ptr == NULL) {
00491             std::ostringstream oMessage;
00492             oMessage << "The input file does not contain information about "
00493                      << "the '" << *itRoutingLegKey << "' leg date needed by "
00494                      << "the '" << lRoutingSegment.str() << "' segment.";
00495             STDAIR_LOG_ERROR (oMessage.str());
00496             throw MissingPartnerFlightDateWithinScheduleFile (oMessage.str());
00497           }
00498           assert (lInventory_ptr != NULL);
00499 
00500           // Build the partner inventory within the current inventory
00501           buildInventory (ioBomRoot, ioInventory, *itRoutingLegKey);
00502 
00503           // Build the current inventory as a partner of the partner inventory
00504           buildInventory (ioBomRoot, *lInventory_ptr, lRoutingSegment.str());
00505         }
00506       }
00507     }
00508   }
00509 
00510   // ////////////////////////////////////////////////////////////////////
00511   void InventoryBuilder::
00512   buildInventory (stdair::BomRoot& ioBomRoot,
00513                   stdair::Inventory& ioInventory,
00514                   const std::string& iFullKeyStr) {
00515     
00516     // Check that the inventory object is not already existing. If an
00517     // inventory object with the same key has already been created,
00518     // then just update it, ifnot, create an inventory and update it.
00519     // for the given key (iFullKeyStr)
00520     stdair::Inventory* lInventory_ptr =
00521       stdair::BomRetriever::retrieveInventoryFromLongKey (ioInventory,
00522                                                           iFullKeyStr);
00523     if (lInventory_ptr == NULL) {
00524       // Instantiate a flighy-date object for the given key (airline code
00525       // within the iFullKeyStr)
00526       stdair::Inventory* lOperatingInventory_ptr =
00527         stdair::BomRetriever::retrieveInventoryFromLongKey (ioBomRoot,
00528                                                             iFullKeyStr);
00529       assert (lOperatingInventory_ptr != NULL);
00530       lInventory_ptr =
00531         &stdair::FacBom<stdair::Inventory>::instance().create (*lOperatingInventory_ptr);
00532       stdair::FacBomManager::addToListAndMap (ioInventory, *lInventory_ptr);
00533       stdair::FacBomManager::linkWithParent (ioInventory, *lInventory_ptr);
00534     }
00535     assert (lInventory_ptr != NULL);
00536 
00537     // Build the flight-date within the inventory.
00538     buildFlightDate (ioBomRoot, *lInventory_ptr, iFullKeyStr);
00539   }
00540 
00541   // ////////////////////////////////////////////////////////////////////
00542   void InventoryBuilder::
00543   buildFlightDate (stdair::BomRoot& ioBomRoot,
00544                    stdair::Inventory& ioInventory,
00545                    const std::string& iFullKeyStr) {
00546 
00547     // Check that the flight-date object is not already existing. If a
00548     // flight-date object with the same key has already been created,
00549     // then just update it, ifnot, create a flight-date and update it.
00550     stdair::FlightDate* lFlightDate_ptr  =
00551       stdair::BomRetriever::retrieveFlightDateFromLongKey (ioInventory,
00552                                                            iFullKeyStr);
00553     if (lFlightDate_ptr == NULL) {
00554       // Instantiate a flighy-date object for the given key (flight number and
00555       // flight date within the iFullKeyStr)
00556       stdair::FlightDate* lOperatingFlightDate_ptr =
00557         stdair::BomRetriever::retrieveFlightDateFromLongKey (ioBomRoot,
00558                                                              iFullKeyStr);
00559       assert (lOperatingFlightDate_ptr != NULL);
00560       stdair::FlightDate& lFlightDate =
00561         cloneFlightDate (*lOperatingFlightDate_ptr);
00562       stdair::FacBomManager::addToListAndMap (ioInventory, lFlightDate);
00563       stdair::FacBomManager::linkWithParent (ioInventory, lFlightDate);
00564     }
00565   }
00566 
00567   // ////////////////////////////////////////////////////////////////////
00568   stdair::FlightDate& InventoryBuilder::
00569   cloneFlightDate (const stdair::FlightDate& iFlightDate) { 
00570 
00574     stdair::FlightDate& lCloneFlightDate = 
00575       stdair::FacBom<stdair::FlightDate>::instance().create (iFlightDate);   
00576     
00577     // Check whether there are LegDate objects
00578     const bool hasLegDateList = stdair::BomManager::hasList<stdair::LegDate> (iFlightDate);
00579     if (hasLegDateList == true) {
00580 
00581       // Browse the leg-dates
00582       const stdair::LegDateList_T& lLegDateList =
00583         stdair::BomManager::getList<stdair::LegDate> (iFlightDate);
00584       for (stdair::LegDateList_T::const_iterator itLD = lLegDateList.begin();
00585            itLD != lLegDateList.end(); ++itLD) {
00586         const stdair::LegDate* lLD_ptr = *itLD;
00587         assert (lLD_ptr != NULL); 
00588 
00589         // Clone the current leg-date
00590         stdair::LegDate& lCloneLegDate = cloneLegDate (*lLD_ptr);
00591         stdair::FacBomManager::addToListAndMap (lCloneFlightDate, lCloneLegDate);
00592         stdair::FacBomManager::linkWithParent (lCloneFlightDate, lCloneLegDate);
00593       }  
00594     }
00595 
00596     // Check whether there are SegmentDate objects
00597     const bool hasSegmentDateList = 
00598       stdair::BomManager::hasList<stdair::SegmentDate> (iFlightDate);
00599     if (hasSegmentDateList == true) {
00600     
00601       // Browse the segment-dates
00602       const stdair::SegmentDateList_T& lSegmentDateList =
00603         stdair::BomManager::getList<stdair::SegmentDate> (iFlightDate);
00604       for (stdair::SegmentDateList_T::const_iterator itSD = lSegmentDateList.begin();
00605            itSD != lSegmentDateList.end(); ++itSD) {
00606         const stdair::SegmentDate* lSD_ptr = *itSD;
00607         assert (lSD_ptr != NULL);       
00608 
00609         // Clone the current segment-date
00610         stdair::SegmentDate& lCloneSegmentDate = cloneSegmentDate (*lSD_ptr);
00611         stdair::FacBomManager::addToListAndMap (lCloneFlightDate, lCloneSegmentDate);
00612         stdair::FacBomManager::linkWithParent (lCloneFlightDate, lCloneSegmentDate);
00613 
00614       }
00615     }
00616       
00617     return lCloneFlightDate; 
00618   } 
00619 
00620   // ////////////////////////////////////////////////////////////////////
00621   stdair::LegDate& InventoryBuilder::cloneLegDate (const stdair::LegDate& iLegDate) { 
00622 
00626     stdair::LegDate& lCloneLegDate = 
00627       stdair::FacBom<stdair::LegDate>::instance().create (iLegDate);
00628 
00629     // Check whether there are LegCabin objects
00630     const bool hasLegCabinList = stdair::BomManager::hasList<stdair::LegCabin> (iLegDate);
00631     if (hasLegCabinList == true) {
00632       // Browse the leg-cabins
00633       const stdair::LegCabinList_T& lLegCabinList =
00634         stdair::BomManager::getList<stdair::LegCabin> (iLegDate);
00635       for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
00636            itLC != lLegCabinList.end(); ++itLC) {
00637         const stdair::LegCabin* lLC_ptr = *itLC;
00638         assert (lLC_ptr != NULL);
00639 
00640         // Clone the current leg-cabin  
00641         stdair::LegCabin& lCloneLegCabin = cloneLegCabin (*lLC_ptr);
00642         stdair::FacBomManager::addToListAndMap (lCloneLegDate, lCloneLegCabin);
00643         stdair::FacBomManager::linkWithParent (lCloneLegDate, lCloneLegCabin);
00644       }
00645     }
00646 
00647     return lCloneLegDate;
00648   }
00649 
00650   // ////////////////////////////////////////////////////////////////////
00651   stdair::LegCabin& InventoryBuilder::cloneLegCabin (const stdair::LegCabin& iLegCabin) { 
00652 
00656     stdair::LegCabin& lCloneLegCabin = 
00657       stdair::FacBom<stdair::LegCabin>::instance().create (iLegCabin);
00658 
00659     // Check whether there are Bucket objects
00660     const bool hasBucketList = stdair::BomManager::hasList<stdair::Bucket> (iLegCabin);
00661     if (hasBucketList == true) {
00662       // Browse the buckets
00663       const stdair::BucketList_T& lBucketList =
00664         stdair::BomManager::getList<stdair::Bucket> (iLegCabin);
00665       for (stdair::BucketList_T::const_iterator itBucket = lBucketList.begin();
00666            itBucket != lBucketList.end(); ++itBucket) {
00667         const stdair::Bucket* lBucket_ptr = *itBucket;
00668         assert (lBucket_ptr != NULL);
00669 
00670         // Clone the current bucket
00671         stdair::Bucket& lCloneBucket = cloneBucket (*lBucket_ptr);
00672         stdair::FacBomManager::addToListAndMap (lCloneLegCabin, lCloneBucket);
00673         stdair::FacBomManager::linkWithParent (lCloneLegCabin, lCloneBucket);
00674       }  
00675     }
00676 
00677     return lCloneLegCabin;
00678   }
00679 
00680   // ////////////////////////////////////////////////////////////////////
00681   stdair::Bucket& InventoryBuilder::cloneBucket (const stdair::Bucket& iBucket) { 
00682 
00686     stdair::Bucket& lCloneBucket = 
00687       stdair::FacBom<stdair::Bucket>::instance().create (iBucket);  
00688 
00689     return lCloneBucket;
00690   } 
00691 
00692   // ////////////////////////////////////////////////////////////////////
00693   stdair::SegmentDate& InventoryBuilder::
00694   cloneSegmentDate (const stdair::SegmentDate& iSegmentDate) { 
00695 
00699     stdair::SegmentDate& lCloneSegmentDate = 
00700       stdair::FacBom<stdair::SegmentDate>::instance().create (iSegmentDate);
00701 
00702     // Check whether there are SegmentCabin objects
00703     const bool hasSegmentCabinList = 
00704       stdair::BomManager::hasList<stdair::SegmentCabin> (iSegmentDate);
00705     if (hasSegmentCabinList == true) {
00706       // Browse the segment-cabins
00707       const stdair::SegmentCabinList_T& lSegmentCabinList =
00708         stdair::BomManager::getList<stdair::SegmentCabin> (iSegmentDate);
00709       for (stdair::SegmentCabinList_T::const_iterator itSC = lSegmentCabinList.begin();
00710            itSC != lSegmentCabinList.end(); ++itSC) {
00711         const stdair::SegmentCabin* lSC_ptr = *itSC;
00712         assert (lSC_ptr != NULL);
00713 
00714         // Clone the current segment-cabin      
00715         stdair::SegmentCabin& lCloneSegmentCabin = cloneSegmentCabin (*lSC_ptr);
00716         stdair::FacBomManager::addToListAndMap (lCloneSegmentDate, lCloneSegmentCabin);
00717         stdair::FacBomManager::linkWithParent (lCloneSegmentDate, lCloneSegmentCabin);
00718    
00719         linkBookingClassesWithSegment (lCloneSegmentDate,
00720                                        lCloneSegmentCabin);
00721 
00722       }
00723     }
00724     return lCloneSegmentDate;
00725   } 
00726 
00727   // ////////////////////////////////////////////////////////////////////
00728   void InventoryBuilder::
00729   linkBookingClassesWithSegment (stdair::SegmentDate& iCloneSegmentDate,
00730                                  stdair::SegmentCabin& iCloneSegmentCabin) {    
00731 
00732     // Browse the fare families to link the booking-classes to the 
00733     // segment-cabin and to the segment-date 
00734     const bool hasFareFamilyList = 
00735       stdair::BomManager::hasList<stdair::FareFamily> (iCloneSegmentCabin);
00736     if (hasFareFamilyList == true) {
00737       const stdair::FareFamilyList_T& lCloneFFList =
00738         stdair::BomManager::getList<stdair::FareFamily> (iCloneSegmentCabin);
00739       for (stdair::FareFamilyList_T::const_iterator itCloneFF = lCloneFFList.begin();
00740            itCloneFF != lCloneFFList.end(); ++itCloneFF) {
00741         const stdair::FareFamily* lCloneFF_ptr = *itCloneFF;
00742         assert (lCloneFF_ptr != NULL);
00743 
00744         // Browse the list of booking classes 
00745         const bool hasBookingClasslist = 
00746           stdair::BomManager::hasList<stdair::BookingClass> (*lCloneFF_ptr);
00747         if (hasBookingClasslist == true) {
00748           const stdair::BookingClassList_T& lCloneBCList =
00749             stdair::BomManager::getList<stdair::BookingClass> (*lCloneFF_ptr);
00750           for (stdair::BookingClassList_T::const_iterator itCloneBC =
00751                  lCloneBCList.begin();
00752                itCloneBC != lCloneBCList.end(); ++itCloneBC) {
00753             const stdair::BookingClass* lCloneBC_ptr = *itCloneBC;
00754             assert (lCloneBC_ptr != NULL);
00755                 
00756             // Link the booking-class to the segment-cabin
00757             stdair::FacBomManager::addToListAndMap (iCloneSegmentCabin, 
00758                                                     *lCloneBC_ptr);
00759 
00760             // Link the booking-class to the segment-date
00761             stdair::FacBomManager::addToListAndMap (iCloneSegmentDate, 
00762                                                     *lCloneBC_ptr);
00763           }
00764         }
00765       }
00766     }
00767   }
00768 
00769   // ////////////////////////////////////////////////////////////////////
00770   stdair::SegmentCabin& InventoryBuilder::
00771   cloneSegmentCabin (const stdair::SegmentCabin& iSegmentCabin) { 
00772 
00776     stdair::SegmentCabin& lCloneSegmentCabin = 
00777       stdair::FacBom<stdair::SegmentCabin>::instance().create (iSegmentCabin);
00778 
00779     // Check whether there are fare family objects 
00780     const bool hasFareFamilyList = 
00781       stdair::BomManager::hasList<stdair::FareFamily> (iSegmentCabin);
00782     if (hasFareFamilyList == true) {
00783       // Browse the fare families
00784       const stdair::FareFamilyList_T& lFareFamilyList =
00785        stdair::BomManager::getList<stdair::FareFamily> (iSegmentCabin);
00786       for (stdair::FareFamilyList_T::const_iterator itFF = lFareFamilyList.begin();
00787            itFF != lFareFamilyList.end(); ++itFF) {
00788         const stdair::FareFamily* lFF_ptr = *itFF;
00789         assert (lFF_ptr != NULL);
00790 
00791         // Clone the current fare-family        
00792         stdair::FareFamily& lCloneFareFamily = cloneFareFamily (*lFF_ptr);
00793         stdair::FacBomManager::addToListAndMap (lCloneSegmentCabin, lCloneFareFamily);
00794         stdair::FacBomManager::linkWithParent (lCloneSegmentCabin, lCloneFareFamily);
00795       }
00796     }
00797     
00798     return lCloneSegmentCabin;
00799   }
00800 
00801   // ////////////////////////////////////////////////////////////////////
00802   stdair::FareFamily& InventoryBuilder::
00803   cloneFareFamily (const stdair::FareFamily& iFareFamily) {
00807     stdair::FareFamily& lCloneFareFamily = 
00808       stdair::FacBom<stdair::FareFamily>::instance().create (iFareFamily);
00809 
00810     // Check whether there are booking classes objects
00811     const bool hasBookingClassList = 
00812       stdair::BomManager::hasList<stdair::BookingClass> (iFareFamily);
00813     if (hasBookingClassList == true) {
00814       // Browse the list of booking classes
00815       const stdair::BookingClassList_T& lBookingClassList =
00816         stdair::BomManager::getList<stdair::BookingClass> (iFareFamily);
00817       for (stdair::BookingClassList_T::const_iterator itBookingClass =
00818              lBookingClassList.begin();
00819            itBookingClass != lBookingClassList.end(); ++itBookingClass) {
00820         const stdair::BookingClass* lBC_ptr = *itBookingClass;
00821         assert (lBC_ptr != NULL);
00822 
00823         // Clone the current booking class
00824         stdair::BookingClass& lCloneBookingClass = cloneBookingClass (*lBC_ptr);
00825         stdair::FacBomManager::addToListAndMap (lCloneFareFamily, lCloneBookingClass);
00826         stdair::FacBomManager::linkWithParent (lCloneFareFamily, lCloneBookingClass);
00827       }
00828     }
00829 
00830     return lCloneFareFamily;
00831   }
00832 
00833   // ////////////////////////////////////////////////////////////////////
00834   stdair::BookingClass& InventoryBuilder::
00835   cloneBookingClass (const stdair::BookingClass& iBookingClass) {
00836     
00840     stdair::BookingClass& lCloneBookingClass = 
00841        stdair::FacBom<stdair::BookingClass>::instance().create (iBookingClass);
00842 
00843     return lCloneBookingClass;
00844   }
00845 }
00846