$treeview $search $mathjax
StdAir Logo  1.00.2
$projectbrief
$projectbrief
$searchbox

stdair/factory/FacBomManager.hpp

Go to the documentation of this file.
00001 #ifndef __STDAIR_FAC_FACBOMMANAGER_HPP
00002 #define __STDAIR_FAC_FACBOMMANAGER_HPP
00003 
00004 // //////////////////////////////////////////////////////////////////////
00005 // Import section
00006 // //////////////////////////////////////////////////////////////////////
00007 // STL
00008 #include <iosfwd>
00009 #include <list>
00010 #include <map>
00011 // Boost
00012 #include <boost/static_assert.hpp>
00013 #include <boost/type_traits/is_same.hpp>
00014 // StdAir
00015 #include <stdair/bom/BomHolder.hpp>
00016 #include <stdair/bom/BomManager.hpp>
00017 #include <stdair/factory/FacAbstract.hpp>
00018 #include <stdair/factory/FacBom.hpp>
00019 // Stdair BOM Objects
00020 #include <stdair/bom/SegmentDate.hpp>
00021 
00022 
00023 namespace stdair {
00024   // Forward declarations.
00025   class SegmentCabin; 
00026 
00030   class FacBomManager : public FacAbstract {
00031   public:
00032     // ///////////// Business methods. ////////////
00041     template <typename OBJECT2, typename OBJECT1>
00042     static BomHolder<OBJECT2>* getBomHolderPtr (OBJECT1&);
00043 
00053     template <typename OBJECT2, typename OBJECT1> 
00054     static BomHolder<OBJECT2>& addBomHolder (OBJECT1&);
00055 
00067     template <typename OBJECT1, typename OBJECT2>
00068     static void addToList (OBJECT1&, OBJECT2&);
00069 
00082     template <typename OBJECT1, typename OBJECT2>
00083     static void addToMap (OBJECT1&, OBJECT2&, const MapKey_T&);
00084 
00096     template <typename OBJECT1, typename OBJECT2>
00097     static void addToMap (OBJECT1&, OBJECT2&);
00098 
00110     template <typename OBJECT1, typename OBJECT2>
00111     static void addToListAndMap (OBJECT1&, OBJECT2&);
00112 
00125     template <typename OBJECT1, typename OBJECT2>
00126     static void addToListAndMap (OBJECT1&, OBJECT2&, const MapKey_T&);
00127 
00134     template <typename PARENT, typename CHILD>
00135     static void linkWithParent (PARENT&, CHILD&);
00136 
00147     template <typename OBJECT2, typename OBJECT1>
00148     static void cloneHolder (OBJECT1&, const OBJECT1&);
00149 
00150 
00151   private:
00164     template <typename OBJECT1, typename OBJECT2>
00165     static void addToList (BomHolder<OBJECT2>&, OBJECT1&, OBJECT2&);
00166 
00180     template <typename OBJECT1, typename OBJECT2>
00181     static void addToMap (BomHolder<OBJECT2>&, OBJECT1&, OBJECT2&,
00182                           const MapKey_T&);
00183 
00192     template <typename OBJECT2, typename OBJECT1>
00193     static BomHolder<OBJECT2>& getBomHolder (OBJECT1&);
00194 
00195   public:
00200     static void resetYieldBasedNestingStructure (const SegmentCabin&);
00201 
00205     static void setAirlineFeature (Inventory& iInventory,
00206                                    AirlineFeature& iAirlineFeature) {
00207       iInventory.setAirlineFeature (iAirlineFeature);
00208     }
00209 
00213     static void linkWithOperating (SegmentDate& iSegmentDate,
00214                                    SegmentDate& iOperatingSegmentDate) {
00215       iSegmentDate.linkWithOperating (iOperatingSegmentDate);
00216     }
00217 
00218 
00219   protected:
00225     FacBomManager() { }
00226 
00227   public:
00231     ~FacBomManager() { }
00232   };
00233 
00234   // ////////////////////////////////////////////////////////////////////
00235   // Public business method.
00236   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00237   template <typename OBJECT2, typename OBJECT1> 
00238   BomHolder<OBJECT2>& FacBomManager::addBomHolder (OBJECT1& ioObject1) {
00239 
00240     //
00241     // Compile time assertation: this function must never be called with the
00242     // following list of couple types:
00243     // <SegmentDate, SegmentDate>
00244     // <AirlineFeature, Inventory>
00245     //
00246     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00247                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00248     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00249                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));         
00250 
00251 
00252     BomHolder<OBJECT2>* lBomHolder_ptr =
00253       &FacBom<BomHolder<OBJECT2> >::instance().create();
00254 
00255     const bool hasInsertBeenSuccessful =
00256       ioObject1._holderMap.insert (typename HolderMap_T::
00257                                    value_type (&typeid (OBJECT2),
00258                                                lBomHolder_ptr)).second;
00259     assert (hasInsertBeenSuccessful == true);
00260 
00261     return *lBomHolder_ptr;
00262   }
00263   
00264   // ////////////////////////////////////////////////////////////////////
00265   // Public business method.
00266   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00267   template <typename OBJECT2, typename OBJECT1> 
00268   BomHolder<OBJECT2>* FacBomManager::getBomHolderPtr (OBJECT1& ioObject1) {
00269 
00270     //
00271     // Compile time assertation: this function must never be called with the
00272     // following list of couple types:
00273     // <SegmentDate, SegmentDate>
00274     // <AirlineFeature, Inventory>
00275     // 
00276     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00277                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00278     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00279                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));
00280     
00281     BomHolder<OBJECT2>* lBomHolder_ptr = NULL;
00282 
00283     // Find the corresponding BomHolder within the object1, if existing.
00284     HolderMap_T::const_iterator itHolder =
00285       ioObject1._holderMap.find (&typeid (OBJECT2));
00286 
00287     if (itHolder != ioObject1._holderMap.end()) {
00288       lBomHolder_ptr = static_cast<BomHolder<OBJECT2>*> (itHolder->second);
00289     }
00290 
00291     return lBomHolder_ptr;
00292   }
00293 
00294   // ////////////////////////////////////////////////////////////////////
00295   // Private method.
00296   template <typename OBJECT2, typename OBJECT1> 
00297   BomHolder<OBJECT2>& FacBomManager::getBomHolder (OBJECT1& ioObject1) {
00298 
00299     //
00300     // Compile time assertation: this function must never be called with the
00301     // following list of couple types:
00302     // <SegmentDate, SegmentDate>
00303     // <AirlineFeature, Inventory>
00304     // 
00305     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00306                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00307     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00308                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));       
00309 
00310     BomHolder<OBJECT2>* lBomHolder_ptr = NULL;
00311 
00312     // Find the corresponding BomHolder within the object1. If it does
00313     // not exist, then create one.
00314     HolderMap_T::const_iterator itHolder =
00315       ioObject1._holderMap.find (&typeid (OBJECT2));
00316 
00317     if (itHolder == ioObject1._holderMap.end()) {
00318       lBomHolder_ptr = &addBomHolder<OBJECT2, OBJECT1> (ioObject1);
00319 
00320     } else {
00321       lBomHolder_ptr = static_cast<BomHolder<OBJECT2>*> (itHolder->second);
00322     }
00323 
00324     assert (lBomHolder_ptr != NULL);
00325 
00326     return *lBomHolder_ptr;
00327   }
00328   
00329   // ////////////////////////////////////////////////////////////////////
00330   // Private method.
00331   template <typename OBJECT1, typename OBJECT2>
00332   void FacBomManager::addToList (BomHolder<OBJECT2>& ioBomHolder,
00333                                  OBJECT1& ioObject1, OBJECT2& ioObject2) {
00334 
00335     //
00336     // Compile time assertation: this function must never be called with the
00337     // following list of couple types:
00338     // <SegmentDate, SegmentDate>
00339     // <AirlineFeature, Inventory>
00340     // 
00341     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00342                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00343     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00344                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));
00345     
00346     ioBomHolder._bomList.push_back (&ioObject2);
00347   }
00348   
00349   // ////////////////////////////////////////////////////////////////////
00350   // Public business method.
00351   // This method is specialized for the following couple types:
00352   // <SegmentDate, SegmentDate>
00353   template <typename OBJECT1, typename OBJECT2>
00354   void FacBomManager::addToList (OBJECT1& ioObject1, OBJECT2& ioObject2) {
00355 
00356     //
00357     // Compile time assertation: this function must never be called with the
00358     // following list of couple types:
00359     // <SegmentDate, SegmentDate>
00360     // <AirlineFeature, Inventory>
00361     // 
00362     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00363                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00364     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00365                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));
00366 
00367     BomHolder<OBJECT2>& lBomHolder = getBomHolder<OBJECT2> (ioObject1);
00368 
00369     addToList<OBJECT1, OBJECT2> (lBomHolder, ioObject1, ioObject2);
00370   }
00371   
00372   // ////////////////////////////////////////////////////////////////////
00373   // Private method.
00374   template <typename OBJECT1, typename OBJECT2>
00375   void FacBomManager::addToMap (BomHolder<OBJECT2>& ioBomHolder,
00376                                 OBJECT1& ioObject1, OBJECT2& ioObject2,
00377                                 const MapKey_T& iKey) {
00378 
00379     //
00380     // Compile time assertation: this function must never be called with the
00381     // following list of couple types:
00382     // <SegmentDate, SegmentDate>
00383     // <AirlineFeature, Inventory>
00384     // 
00385     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00386                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00387     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00388                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));
00389 
00390     const bool insertionSucceeded =
00391       ioBomHolder._bomMap.insert (typename std::map<const MapKey_T, OBJECT2*>::
00392                                   value_type (iKey, &ioObject2)).second;
00393 
00394     if (insertionSucceeded == false) {
00395       // Build a nice message, so that the error be fully explicit
00396       std::ostringstream oStr;
00397       oStr << "The given object ('" << iKey
00398            << "') can not be added to the map of '" << ioObject1.describeKey()
00399            << "' object. That map already contains: '";
00400 
00401       unsigned int idx = 0;
00402       for (typename std::map<const MapKey_T, OBJECT2*>::const_iterator iter =
00403              ioBomHolder._bomMap.begin(); 
00404            iter != ioBomHolder._bomMap.end(); ++iter, ++idx) {
00405         const OBJECT2* lCurrentObject_ptr = iter->second;
00406         assert (lCurrentObject_ptr != NULL);
00407 
00408         if (idx != 0) {
00409           oStr << "; ";
00410         }
00411         oStr << lCurrentObject_ptr->describeKey();
00412       }
00413       oStr << "'";
00414 
00415       STDAIR_LOG_ERROR (oStr.str());
00416       throw ObjectLinkingException (oStr.str());
00417     }    
00418   }
00419   
00420   // ////////////////////////////////////////////////////////////////////
00421   // Public business method.
00422   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00423   template <typename OBJECT1, typename OBJECT2> void FacBomManager::
00424   addToMap (OBJECT1& ioObject1, OBJECT2& ioObject2, const MapKey_T& iKey) {
00425 
00426     //
00427     // Compile time assertation: this function must never be called with the
00428     // following list of couple types:
00429     // <SegmentDate, SegmentDate>
00430     // <AirlineFeature, Inventory>
00431     // 
00432     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00433                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00434     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00435                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));         
00436 
00437     BomHolder<OBJECT2>& lBomHolder = getBomHolder<OBJECT2> (ioObject1);
00438 
00439     addToMap<OBJECT1, OBJECT2> (lBomHolder, ioObject1, ioObject2, iKey);
00440   }
00441   
00442   // Public business method.
00443   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00444   // ////////////////////////////////////////////////////////////////////
00445   template <typename OBJECT1, typename OBJECT2>
00446   void FacBomManager::addToMap (OBJECT1& ioObject1, OBJECT2& ioObject2) {
00447 
00448     //
00449     // Compile time assertation: this function must never be called with the
00450     // following list of couple types:
00451     // <SegmentDate, SegmentDate>
00452     // <AirlineFeature, Inventory>
00453     // 
00454     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00455                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00456     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00457                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));   
00458     
00459     const MapKey_T& lKey = ioObject2.describeKey();
00460     addToMap (ioObject1, ioObject2, lKey);
00461   }
00462   
00463   // ////////////////////////////////////////////////////////////////////
00464   // Public business method.
00465   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00466   template <typename OBJECT1, typename OBJECT2>
00467   void FacBomManager::addToListAndMap (OBJECT1& ioObject1, OBJECT2& ioObject2,
00468                                        const MapKey_T& iKey) {
00469     //
00470     // Compile time assertation: this function must never be called with the
00471     // following list of couple types:
00472     // <SegmentDate, SegmentDate>
00473     // <AirlineFeature, Inventory>
00474     // 
00475     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00476                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00477     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00478                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));                
00479     
00480     BomHolder<OBJECT2>& lBomHolder = getBomHolder<OBJECT2> (ioObject1);
00481 
00482     addToList<OBJECT1, OBJECT2> (lBomHolder, ioObject1, ioObject2);
00483     addToMap<OBJECT1, OBJECT2> (lBomHolder, ioObject1, ioObject2, iKey);
00484   }
00485   
00486   // ////////////////////////////////////////////////////////////////////
00487   // Public business method.
00488   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00489   template <typename OBJECT1, typename OBJECT2> void FacBomManager::
00490   addToListAndMap (OBJECT1& ioObject1, OBJECT2& ioObject2) {
00491 
00492     //
00493     // Compile time assertation: this function must never be called with the
00494     // following list of couple types:
00495     // <SegmentDate, SegmentDate>
00496     // <AirlineFeature, Inventory>
00497     // 
00498     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00499                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00500     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00501                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));          
00502     
00503     const MapKey_T& lKey = ioObject2.describeKey();
00504     addToListAndMap<OBJECT1, OBJECT2> (ioObject1, ioObject2, lKey);
00505   }
00506 
00507   // Public business method valid for all PARENT and CHILD types.
00508   // (No compile time assertation to check PARENT and CHILD types.)
00509   // ////////////////////////////////////////////////////////////////////
00510   template <typename PARENT, typename CHILD> void FacBomManager::
00511   linkWithParent (PARENT& ioParent,  CHILD& ioChild) {
00512     ioChild._parent = &ioParent;
00513   }
00514   
00515   // ////////////////////////////////////////////////////////////////////
00516   // Public business method valid for all PARENT and CHILD types.
00517   // (No compile time assertation to check PARENT and CHILD types.)
00518   template <typename OBJECT2, typename OBJECT1> void FacBomManager::
00519   cloneHolder (OBJECT1& ioDest, const OBJECT1& iOri) {
00520 
00521     const BomHolder<OBJECT2>& lOriginHolder = 
00522       BomManager::getBomHolder<OBJECT2> (iOri);
00523 
00524     BomHolder<OBJECT2>& lDestHolder = getBomHolder<OBJECT2> (ioDest);
00525     lDestHolder._bomList = lOriginHolder._bomList;
00526     lDestHolder._bomMap = lOriginHolder._bomMap;
00527   }
00528   
00529   // ////////////////////////////////////////////////////////////////////
00530   //
00531   // Specialization of the template method addToList above for the types
00532   // <SegmentDate, SegmentDate>.
00533   // Add an element to the marketing segment date list of a segment date.
00534   //
00535   // ////////////////////////////////////////////////////////////////////
00536 
00537   template<>
00538   inline void FacBomManager::addToList <SegmentDate,SegmentDate>
00539   (SegmentDate& ioSegmentDate,
00540    SegmentDate& ioMarketingSegmentDate) {
00541     
00542     ioSegmentDate._marketingSegmentDateList.push_back(&ioMarketingSegmentDate);
00543   }
00544   
00545   // ////////////////////////////////////////////////////////////////////
00546   //
00547   // TODO:
00548   // This specialization is needed for all the objects in the current
00549   // BOM tree.
00550   // (An inventory is the parent of flight dates, a flight date is the
00551   // parent of segment dates and leg dates, ...)
00552   //
00553   // ////////////////////////////////////////////////////////////////////
00554 
00555 
00556 }
00557 
00558 // ////////////////////////////////////////////////////////////////////
00559 
00560 #endif // __STDAIR_FAC_FACBOMMANAGER_HPP