AirInv Logo  0.1.2
C++ Simulated Airline Inventory Management System library
InventoryGenerator.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/stdair_types.hpp>
00010 #include <stdair/basic/BasConst_Inventory.hpp>
00011 #include <stdair/bom/BomManager.hpp>
00012 #include <stdair/bom/BomRoot.hpp>
00013 #include <stdair/bom/Inventory.hpp>
00014 #include <stdair/bom/FlightDate.hpp>
00015 #include <stdair/bom/SegmentDate.hpp>
00016 #include <stdair/bom/SegmentCabin.hpp>
00017 #include <stdair/bom/FareFamily.hpp>
00018 #include <stdair/bom/BookingClass.hpp>
00019 #include <stdair/bom/LegDate.hpp>
00020 #include <stdair/bom/LegCabin.hpp>
00021 #include <stdair/bom/Bucket.hpp>
00022 #include <stdair/factory/FacBomManager.hpp>
00023 #include <stdair/service/Logger.hpp>
00024 // AirInv
00025 #include <airinv/bom/FlightPeriodStruct.hpp>
00026 #include <airinv/command/InventoryGenerator.hpp>
00027 
00028 namespace AIRINV {
00029 
00030   // ////////////////////////////////////////////////////////////////////
00031   void InventoryGenerator::
00032   createFlightDate (stdair::BomRoot& ioBomRoot,
00033                     const FlightPeriodStruct& iFlightPeriod) {
00034     const stdair::AirlineCode_T& lAirlineCode = iFlightPeriod._airlineCode;
00035  
00036     // Instantiate an inventory object (if not exist)
00037     // for the given key (airline code)
00038     stdair::Inventory* lInventory_ptr = stdair::BomManager::
00039       getObjectPtr<stdair::Inventory> (ioBomRoot, lAirlineCode);
00040     if (lInventory_ptr == NULL) {
00041       stdair::InventoryKey lKey (lAirlineCode);
00042       lInventory_ptr =
00043         &stdair::FacBom<stdair::Inventory>::instance().create (lKey);
00044       stdair::FacBomManager::addToListAndMap (ioBomRoot, *lInventory_ptr);
00045       stdair::FacBomManager::linkWithParent (ioBomRoot, *lInventory_ptr);
00046     }
00047     assert (lInventory_ptr != NULL);
00048     
00049     // Generate all the dates corresponding to the period
00050     // and create the corresponding flight-dates.
00051     const stdair::DatePeriod_T lDateRange = iFlightPeriod._dateRange;
00052 
00053     for (boost::gregorian::day_iterator itDate = lDateRange.begin();
00054          itDate != lDateRange.end(); ++itDate) {
00055       const stdair::Date_T& currentDate = *itDate;
00056 
00057       // Retrieve, for the current day, the Day-Of-the-Week (thanks to Boost)
00058       const unsigned short currentDoW = currentDate.day_of_week().as_number();
00059         
00060       // The FlightPeriod structure stores which Days (-Of-the-Week) are
00061       // active within the week. For each day (Mon., Tue., etc.), a boolean
00062       // states whether the Flight is active for that day.
00063       const stdair::DoWStruct& lDoWList = iFlightPeriod._dow;
00064       const bool isDoWActive = lDoWList.getStandardDayOfWeek (currentDoW);
00065 
00066       if (isDoWActive == true) {
00067         createFlightDate (*lInventory_ptr, currentDate, iFlightPeriod);
00068       }
00069     }
00070   }
00071   
00072   // ////////////////////////////////////////////////////////////////////
00073   void InventoryGenerator::
00074   createFlightDate (stdair::Inventory& ioInventory,
00075                     const stdair::Date_T& iFlightDate,
00076                     const FlightPeriodStruct& iFlightPeriod) {
00077     // Create the FlightDateKey
00078     const stdair::FlightNumber_T& lFlightNumber = iFlightPeriod._flightNumber;
00079     stdair::FlightDateKey lFlightDateKey (lFlightNumber, iFlightDate);
00080 
00081     // DEBUG
00082     // STDAIR_LOG_DEBUG ("Creating flight-date: " << lFlightDateKey.toString());
00083     
00084     // Check that the flight-date object is not already existing. If a
00085     // FlightDate object with the same key has already been created,
00086     // it means that the schedule input file is invalid (two flight-periods
00087     // are overlapping).
00088     stdair::FlightDate* lFlightDate_ptr = stdair::BomManager::
00089       getObjectPtr<stdair::FlightDate> (ioInventory, lFlightDateKey.toString());
00090     if (lFlightDate_ptr != NULL) {
00091       std::ostringstream oMessage;
00092       oMessage << ioInventory.describeKey() << ", "
00093                << lFlightDate_ptr->describeKey();
00094       throw FlightDateDuplicationException (oMessage.str());
00095     }
00096 
00097     // Instantiate a fligh-date object with the given key (flight number and
00098     // flight date)
00099     lFlightDate_ptr =
00100       &stdair::FacBom<stdair::FlightDate>::instance().create (lFlightDateKey);
00101     stdair::FacBomManager::addToListAndMap (ioInventory, *lFlightDate_ptr);
00102     stdair::FacBomManager::linkWithParent (ioInventory, *lFlightDate_ptr);
00103       
00104     // Iterate on the leg-dates
00105     stdair::Duration_T currentOffTime (0, 0, 0);
00106     stdair::AirportCode_T previousOffPoint;
00107     const LegStructList_T& lLegList = iFlightPeriod._legList;
00108     for (LegStructList_T::const_iterator itLeg = lLegList.begin();
00109          itLeg != lLegList.end(); ++itLeg) {
00110       const LegStruct& lLeg = *itLeg;
00111 
00112       // Create the leg-branch of the flight-date BOM
00113       stdair::LegDate& lLegDate =
00114         createLegDate (*lFlightDate_ptr, iFlightDate, lLeg);
00115 
00116       // TODO: Check that the boarding date/time of the next leg is greated
00117       // than the off date/time of the current leg. Throw an exception
00118       // otherwise.
00119 
00120       // TODO: specify, in the schedule input file specifications, that the
00121       // legs should be given in their natural order.
00122       // Then, replace the assertion by a thrown exception.
00123       //
00124       // Check that the legs are given in their natural order. If the schedule
00125       // input does not respect that assumption, the following assertion will
00126       // fail.
00127       if (itLeg != lLegList.begin()) {
00128         const stdair::AirportCode_T& currentBoardingPoint =
00129           lLegDate.getBoardingPoint();
00130         assert (currentBoardingPoint == previousOffPoint);
00131       }
00132         
00133       // Set the local variable for the next iteration
00134       previousOffPoint = lLegDate.getOffPoint();
00135     }
00136 
00137     // Iterate on the segment structures
00138     const SegmentStructList_T& lSegmentList = iFlightPeriod._segmentList;
00139     for (SegmentStructList_T::const_iterator itSegment = lSegmentList.begin();
00140          itSegment != lSegmentList.end(); ++itSegment) {
00141       const SegmentStruct& lSegment = *itSegment;
00142 
00143       createSegmentDate (*lFlightDate_ptr, lSegment);
00144     }
00145   }
00146 
00147   // ////////////////////////////////////////////////////////////////////
00148   stdair::LegDate& InventoryGenerator::
00149   createLegDate (stdair::FlightDate& ioFlightDate,
00150                  const stdair::Date_T& iReferenceDate,
00151                  const LegStruct& iLeg) {
00152     // Create the leg-date corresponding to the boarding point.
00153     stdair::LegDateKey lKey (iLeg._boardingPoint);
00154     stdair::LegDate& lLegDate =
00155       stdair::FacBom<stdair::LegDate>::instance().create (lKey);
00156     stdair::FacBomManager::addToListAndMap (ioFlightDate, lLegDate);
00157     stdair::FacBomManager::linkWithParent (ioFlightDate, lLegDate);
00158 
00159     // Set the leg-date attributes
00160     iLeg.fill (iReferenceDate, lLegDate);
00161     
00162     // Iterate on the cabins
00163     const LegCabinStructList_T& lCabinList = iLeg._cabinList;
00164     for (LegCabinStructList_T::const_iterator itCabin = lCabinList.begin();
00165          itCabin != lCabinList.end(); ++itCabin) {
00166       const LegCabinStruct& lCabin = *itCabin;
00167 
00168       // Create the leg-cabin-branch of the leg-date 
00169       createLegCabin (lLegDate, lCabin);
00170     }
00171 
00172     return lLegDate;
00173   }
00174 
00175   // ////////////////////////////////////////////////////////////////////
00176   void InventoryGenerator::
00177   createLegCabin (stdair::LegDate& ioLegDate,
00178                   const LegCabinStruct& iCabin) {
00179     // Instantiate an leg-cabin object with the corresponding cabin code
00180     const stdair::LegCabinKey lKey (iCabin._cabinCode);
00181     stdair::LegCabin& lLegCabin =
00182       stdair::FacBom<stdair::LegCabin>::instance().create (lKey);
00183     stdair::FacBomManager::addToListAndMap (ioLegDate, lLegCabin);
00184     stdair::FacBomManager::linkWithParent (ioLegDate, lLegCabin);
00185 
00186     // Set the Leg-Cabin attributes
00187     iCabin.fill (lLegCabin);
00188 
00189     // Iterate on the bucket
00190     const BucketStructList_T& lBucketList = iCabin._bucketList;
00191     for (BucketStructList_T::const_iterator itBucket = lBucketList.begin();
00192          itBucket != lBucketList.end(); ++itBucket) {
00193       const BucketStruct& lBucket = *itBucket;
00194 
00195       // Create the bucket of the leg-cabin
00196       createBucket (lLegCabin, lBucket);
00197     }
00198   }
00199     
00200   // ////////////////////////////////////////////////////////////////////
00201   void InventoryGenerator::createBucket (stdair::LegCabin& ioLegCabin,
00202                                          const BucketStruct& iBucket) {
00203     // Instantiate a bucket object with the corresponding seat index
00204     const stdair::BucketKey lKey (iBucket._seatIndex);
00205     stdair::Bucket& lBucket =
00206       stdair::FacBom<stdair::Bucket>::instance().create (lKey);
00207     stdair::FacBomManager::addToListAndMap (ioLegCabin, lBucket);
00208     stdair::FacBomManager::linkWithParent (ioLegCabin, lBucket);
00209 
00210     // Set the Bucket attributes
00211     iBucket.fill (lBucket);
00212   }
00213 
00214   // ////////////////////////////////////////////////////////////////////
00215   void InventoryGenerator::
00216   createSegmentDate (stdair::FlightDate& ioFlightDate,
00217                      const SegmentStruct& iSegment) {
00218     // Set the segment-date primary key
00219     const stdair::AirportCode_T& lBoardingPoint = iSegment._boardingPoint;
00220     const stdair::AirportCode_T& lOffPoint = iSegment._offPoint;
00221     stdair::SegmentDateKey lSegmentDateKey (lBoardingPoint, lOffPoint);
00222     // Instantiate an segment-date object with the key.
00223     stdair::SegmentDate& lSegmentDate =
00224       stdair::FacBom<stdair::SegmentDate>::instance().create (lSegmentDateKey);
00225     stdair::FacBomManager::addToListAndMap (ioFlightDate, lSegmentDate);
00226     stdair::FacBomManager::linkWithParent (ioFlightDate, lSegmentDate);
00227     
00228     // Set the segment-date attributes
00229     iSegment.fill (lSegmentDate);
00230       
00231     // Iterate on the Cabins
00232     const SegmentCabinStructList_T& lCabinList = iSegment._cabinList;
00233     for (SegmentCabinStructList_T::const_iterator itCabin =
00234            lCabinList.begin(); itCabin != lCabinList.end(); ++itCabin) {
00235       const SegmentCabinStruct& lCabin = *itCabin;
00236 
00237       // Create the segment-cabin-branch of the segment-date BOM
00238       createSegmentCabin (lSegmentDate, lCabin);
00239     }
00240   }
00241     
00242   // ////////////////////////////////////////////////////////////////////
00243   void InventoryGenerator::
00244   createSegmentCabin (stdair::SegmentDate& ioSegmentDate,
00245                       const SegmentCabinStruct& iCabin) {
00246 
00247     // Instantiate an segment-cabin object with the corresponding cabin code
00248     stdair::SegmentCabinKey lKey (iCabin._cabinCode);
00249     stdair::SegmentCabin& lSegmentCabin =
00250       stdair::FacBom<stdair::SegmentCabin>::instance().create (lKey);
00251 
00252     // Link the segment-cabin to its parent, the segment-date
00253     stdair::FacBomManager::addToListAndMap (ioSegmentDate, lSegmentCabin);
00254     stdair::FacBomManager::linkWithParent (ioSegmentDate, lSegmentCabin);
00255     
00256     // Set the segment-cabin attributes
00257     iCabin.fill (lSegmentCabin);
00258 
00259     // Create the list of fare families
00260     for (FareFamilyStructList_T::const_iterator itFareFamily =
00261            iCabin._fareFamilies.begin();
00262          itFareFamily != iCabin._fareFamilies.end(); itFareFamily++) {
00263       const FareFamilyStruct& lFareFamilyStruct = *itFareFamily;
00264 
00265       //
00266       createFareFamily (lSegmentCabin, lFareFamilyStruct);
00267     } 
00268   }
00269     
00270   // ////////////////////////////////////////////////////////////////////
00271   void InventoryGenerator::
00272   createFareFamily (stdair::SegmentCabin& ioSegmentCabin,
00273                     const FareFamilyStruct& iFF) {
00274     // Instantiate an segment-cabin object with the corresponding cabin code
00275     stdair::FareFamilyKey lKey (iFF._familyCode);
00276     stdair::FareFamily& lFareFamily =
00277       stdair::FacBom<stdair::FareFamily>::instance().create (lKey);
00278 
00279     // Link the fare family to its parent, the segment-cabin
00280     stdair::FacBomManager::addToListAndMap (ioSegmentCabin,
00281                                                        lFareFamily);
00282     stdair::FacBomManager::linkWithParent (ioSegmentCabin,
00283                                                       lFareFamily);
00284     
00285     // Set the fare family attributes
00286     iFF.fill (lFareFamily);
00287 
00288     // Iterate on the classes
00289     const stdair::ClassList_String_T& lClassList = iFF._classes;
00290     for (stdair::ClassList_String_T::const_iterator itClass =
00291            lClassList.begin(); itClass != lClassList.end(); ++itClass) {
00292       // Transform the single-character class code into a STL string
00293       std::ostringstream ostr;
00294       ostr << *itClass;
00295       const stdair::ClassCode_T lClassCode (ostr.str());
00296       
00297       // Create the booking class branch of the segment-cabin BOM
00298       createClass (lFareFamily, lClassCode);
00299     }
00300   }
00301 
00302   // ////////////////////////////////////////////////////////////////////
00303   void InventoryGenerator::createClass (stdair::FareFamily& ioFareFamily,
00304                                         const stdair::ClassCode_T& iClassCode) {
00305 
00306     // Instantiate a booking class object with the given class code
00307     const stdair::BookingClassKey lClassKey (iClassCode);
00308     stdair::BookingClass& lClass =
00309       stdair::FacBom<stdair::BookingClass>::instance().create (lClassKey);
00310 
00311     // Link the booking-class to the fare family
00312     stdair::FacBomManager::addToListAndMap (ioFareFamily, lClass);
00313     stdair::FacBomManager::linkWithParent (ioFareFamily, lClass);
00314 
00315     // Link the booking-class to the segment-cabin
00316     stdair::SegmentCabin& lSegmentCabin =
00317       stdair::BomManager::getParent<stdair::SegmentCabin> (ioFareFamily);
00318     stdair::FacBomManager::addToListAndMap (lSegmentCabin, lClass);
00319 
00320     // Link the booking-class to the segment-date
00321     stdair::SegmentDate& lSegmentDate =
00322       stdair::BomManager::getParent<stdair::SegmentDate> (lSegmentCabin);
00323     stdair::FacBomManager::addToListAndMap (lSegmentDate, lClass);
00324   }
00325 }