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

stdair/bom/BomManager.hpp

Go to the documentation of this file.
00001 #ifndef __STDAIR_BOM_BOMMANAGER_HPP
00002 #define __STDAIR_BOM_BOMMANAGER_HPP
00003 
00004 // //////////////////////////////////////////////////////////////////////
00005 // Import section
00006 // //////////////////////////////////////////////////////////////////////
00007 // STL
00008 #include <iosfwd>
00009 #include <string>
00010 #include <list>
00011 #include <map>
00012 // Boost
00013 #include <boost/static_assert.hpp>
00014 #include <boost/type_traits/is_same.hpp>
00015 // StdAir
00016 #include <stdair/stdair_exceptions.hpp>
00017 #include <stdair/bom/BomAbstract.hpp>
00018 #include <stdair/bom/BomHolder.hpp>
00019 #include <stdair/service/Logger.hpp>
00020 // Stdair BOM Objects
00021 #include <stdair/bom/SegmentDate.hpp>
00022 #include <stdair/bom/Inventory.hpp>
00023 #include <stdair/bom/AirlineFeature.hpp>
00024 
00025 namespace stdair {
00026   
00034   class BomManager {
00035     friend class FacBomManager;
00036     
00037   public:
00041     template <typename OBJECT2, typename OBJECT1>
00042     static const typename BomHolder<OBJECT2>::BomList_T& getList(const OBJECT1&);
00043 
00047     template <typename OBJECT2, typename OBJECT1>
00048     static const typename BomHolder<OBJECT2>::BomMap_T& getMap (const OBJECT1&);
00049 
00053     template <typename OBJECT2, typename OBJECT1>
00054     static bool hasList (const OBJECT1&);
00055 
00059     template <typename OBJECT2, typename OBJECT1>
00060     static bool hasMap (const OBJECT1&);
00061 
00067     template <typename PARENT, typename CHILD>
00068     static PARENT* getParentPtr (const CHILD&);
00069 
00073     template <typename PARENT, typename CHILD>
00074     static PARENT& getParent (const CHILD&);
00075 
00081     template <typename OBJECT2, typename OBJECT1>
00082     static OBJECT2* getObjectPtr (const OBJECT1&, const MapKey_T&);
00083 
00087     template <typename OBJECT2, typename OBJECT1>
00088     static OBJECT2& getObject (const OBJECT1&, const MapKey_T&);
00089 
00090 
00091   private:
00096     template <typename OBJECT2, typename OBJECT1>
00097     static const BomHolder<OBJECT2>& getBomHolder (const OBJECT1&);
00098   };
00099 
00100   // ////////////////////////////////////////////////////////////////////
00101   // Private method.
00102   template <typename OBJECT2, typename OBJECT1> 
00103   const BomHolder<OBJECT2>& BomManager::getBomHolder (const OBJECT1& iObject1) {
00104 
00105     //
00106     // Compile time assertation: this function must never be called with the
00107     // following list of couple types:
00108     // <SegmentDate, SegmentDate>
00109     // <AirlineFeature, Inventory>
00110     // 
00111     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00112                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00113     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00114                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));
00115 
00116     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00117     
00118     HolderMap_T::const_iterator itHolder = lHolderMap.find (&typeid (OBJECT2));
00119     
00120     if (itHolder == lHolderMap.end()) {
00121       const std::string lName (typeid (OBJECT2).name());
00122       throw NonInitialisedContainerException ("Cannot find the holder of type "
00123                                               + lName + " within: "
00124                                               + iObject1.describeKey());
00125     } 
00126     
00127     const BomHolder<OBJECT2>* lBomHolder_ptr = 
00128       static_cast<const BomHolder<OBJECT2>*> (itHolder->second);
00129     assert (lBomHolder_ptr != NULL);
00130 
00131     return *lBomHolder_ptr;
00132   }
00133   
00134   // ////////////////////////////////////////////////////////////////////
00135   // Public business method.
00136   // This method is specialized for the following couple types:
00137   // <SegmentDate, SegmentDate>
00138   template <typename OBJECT2, typename OBJECT1>
00139   const typename BomHolder<OBJECT2>::BomList_T& BomManager::
00140   getList (const OBJECT1& iObject1) {
00141     
00142     //
00143     // Compile time assertation: this function must never be called with the
00144     // following list of couple types:
00145     // <AirlineFeature, Inventory>
00146     //
00147     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00148                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));
00149     
00150   const BomHolder<OBJECT2>& lBomHolder = getBomHolder<OBJECT2> (iObject1);
00151     return lBomHolder._bomList;
00152   }
00153   
00154   // ////////////////////////////////////////////////////////////////////
00155   // Public business method.
00156   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00157   template <typename OBJECT2, typename OBJECT1>
00158   const typename BomHolder<OBJECT2>::BomMap_T& BomManager::
00159   getMap (const OBJECT1& iObject1) {
00160 
00161     //
00162     // Compile time assertation: this function must never be called with the
00163     // following list of couple types:
00164     // <SegmentDate, SegmentDate>
00165     // <AirlineFeature, Inventory>
00166     // 
00167     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00168                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00169     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, Inventory>::value == false
00170                           || boost::is_same<OBJECT2, AirlineFeature>::value == false));
00171     
00172     const BomHolder<OBJECT2>& lBomHolder = getBomHolder<OBJECT2> (iObject1);
00173     return lBomHolder._bomMap;
00174   }
00175   
00176   // ////////////////////////////////////////////////////////////////////
00177   // Public business method.
00178   // This method is specialized for the following couple types:
00179   // <SegmentDate, SegmentDate>
00180   template <typename OBJECT2, typename OBJECT1>
00181   bool BomManager::hasList (const OBJECT1& iObject1) {
00182     
00183     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00184     HolderMap_T::const_iterator itHolder = lHolderMap.find (&typeid (OBJECT2));
00185     
00186     if (itHolder == lHolderMap.end()) {
00187       return false;
00188     }
00189     const BomHolder<OBJECT2>* lBomHolder_ptr = 
00190       static_cast<const BomHolder<OBJECT2>*> (itHolder->second);
00191     assert (lBomHolder_ptr != NULL);
00192 
00193     return !lBomHolder_ptr->_bomList.empty();
00194   }
00195   
00196   // ////////////////////////////////////////////////////////////////////
00197   // Public business method.
00198   // This method is specialized for the following couple types:
00199   // <SegmentDate, SegmentDate>
00200   template <typename OBJECT2, typename OBJECT1>
00201   bool BomManager::hasMap (const OBJECT1& iObject1) {
00202     
00203     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00204     HolderMap_T::const_iterator itHolder = lHolderMap.find (&typeid (OBJECT2));
00205     
00206     if (itHolder == lHolderMap.end()) {
00207       return false;
00208     }
00209     const BomHolder<OBJECT2>* lBomHolder_ptr = 
00210       static_cast<const BomHolder<OBJECT2>*> (itHolder->second);
00211     assert (lBomHolder_ptr != NULL);
00212 
00213     return !lBomHolder_ptr->_bomMap.empty();
00214   }
00215   
00216   // ////////////////////////////////////////////////////////////////////
00217   // Public business method valid for all PARENT and CHILD types.
00218   // (No compile time assertation to check PARENT and CHILD types.)
00219   template <typename PARENT, typename CHILD>
00220   PARENT* BomManager::getParentPtr (const CHILD& iChild) {
00221     
00222     PARENT* const lParent_ptr = static_cast<PARENT* const> (iChild.getParent());
00223     return lParent_ptr; 
00224   }
00225   
00226   // ////////////////////////////////////////////////////////////////////
00227   // Public business method valid for all PARENT and CHILD types.
00228   // (No compile time assertation to check PARENT and CHILD types.)
00229   template <typename PARENT, typename CHILD>
00230   PARENT& BomManager::getParent (const CHILD& iChild) {
00231     
00232     PARENT* const lParent_ptr = getParentPtr<PARENT> (iChild);
00233     assert (lParent_ptr != NULL);
00234     return *lParent_ptr; 
00235   }
00236   
00237   // ////////////////////////////////////////////////////////////////////
00238   // Public business method.
00239   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00240   template <typename OBJECT2, typename OBJECT1>
00241   OBJECT2* BomManager::getObjectPtr (const OBJECT1& iObject1,
00242                                      const MapKey_T& iKey) {
00243 
00244     //
00245     // Compile time assertation: this function must never be called with the
00246     // following list of couple types:
00247     // <SegmentDate, SegmentDate>
00248     // 
00249     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00250                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00251     
00252     OBJECT2* oBom_ptr = NULL;
00253     
00254     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00255 
00256     typename HolderMap_T::const_iterator itHolder = 
00257       lHolderMap.find (&typeid (OBJECT2));
00258     
00259     if (itHolder != lHolderMap.end()) {
00260     
00261       BomHolder<OBJECT2>* const lBomHolder_ptr = 
00262         static_cast<BomHolder<OBJECT2>* const> (itHolder->second);
00263       assert (lBomHolder_ptr != NULL);
00264 
00265       //
00266       typedef typename BomHolder<OBJECT2>::BomMap_T BomMap_T;
00267       BomMap_T& lBomMap =  lBomHolder_ptr->_bomMap;
00268       typename BomMap_T::iterator itBom = lBomMap.find (iKey);
00269 
00270       if (itBom != lBomMap.end()) {
00271         oBom_ptr = itBom->second;
00272         assert (oBom_ptr != NULL);
00273       }
00274     }
00275 
00276     return oBom_ptr;
00277   }
00278 
00279   // ////////////////////////////////////////////////////////////////////
00280   // Public business method.
00281   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00282   template <typename OBJECT2, typename OBJECT1>
00283   OBJECT2& BomManager::getObject (const OBJECT1& iObject1,
00284                                   const MapKey_T& iKey) {
00285     
00286     //
00287     // Compile time assertation: this function must never be called with the
00288     // following list of couple types:
00289     // <SegmentDate, SegmentDate>
00290     // 
00291     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00292                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00293     
00294     OBJECT2* oBom_ptr = NULL;
00295     
00296     typedef std::map<const MapKey_T, OBJECT2*> BomMap_T;
00297     const BomMap_T& lBomMap = getMap<OBJECT2> (iObject1);
00298     
00299     typename BomMap_T::const_iterator itBom = lBomMap.find (iKey);
00300 
00301     if (itBom == lBomMap.end()) {
00302       const std::string lName (typeid (OBJECT2).name());
00303       
00304       STDAIR_LOG_ERROR ("Cannot find the objet of type " << lName
00305                         << " with key " << iKey << " within: " 
00306                         << iObject1.describeKey());
00307       assert (false);
00308     }
00309     
00310     oBom_ptr = itBom->second;
00311     assert (oBom_ptr != NULL);
00312 
00313     return *oBom_ptr;
00314   }
00315 
00316   // ////////////////////////////////////////////////////////////////////
00317   //
00318   // Specialization of the template methods above for a segment
00319   // date and its corresponding marketing segment dates.
00320   //
00321   // ////////////////////////////////////////////////////////////////////
00322   
00323   // Specialization of the template method hasList above for the types
00324   // <SegmentDate, SegmentDate>.
00325   // Return a boolean saying if the marketing segment date list is empty
00326   // or not. 
00327   template<> 
00328   inline bool BomManager::hasList<SegmentDate,SegmentDate>
00329   (const SegmentDate& ioSegmentDate) {
00330     
00331     const SegmentDateList_T& lMarketingSegmentDateList =
00332       ioSegmentDate.getMarketingSegmentDateList ();
00333     const bool isMarketingSegmentDateListEmpty =
00334       lMarketingSegmentDateList.empty();
00335     const bool hasMarketingSegmentDateList = 
00336       !isMarketingSegmentDateListEmpty;
00337     return hasMarketingSegmentDateList;
00338   }
00339   
00340   // Specialization of the template method hasList above for the types
00341   // <SegmentDate, SegmentDate>.
00342   // Return the marketing segment date list.
00343   template<> 
00344   inline const BomHolder<SegmentDate>::BomList_T&
00345   BomManager::getList<SegmentDate,SegmentDate> (const SegmentDate& ioSegmentDate) {
00346     
00347     const SegmentDateList_T& lMarketingSegmentDateList =
00348       ioSegmentDate.getMarketingSegmentDateList ();
00349     return lMarketingSegmentDateList;
00350   }
00351   
00352   // Specialization of the template method hasMap above for the types
00353   // <SegmentDate, SegmentDate>.
00354   // A segment date does not have a Segment Date Map but it can have a
00355   // Segment Date list (containing its marketing segment dates). 
00356   template<> 
00357   inline bool BomManager::hasMap<SegmentDate,SegmentDate>
00358   (const SegmentDate& ioSegmentDate) {
00359     
00360     const bool hasMap = false;
00361     return hasMap;
00362   }
00363 
00364   // ////////////////////////////////////////////////////////////////////
00365   //
00366   // Specialization of the template methods above for an inventory
00367   // and its airline features.
00368   //
00369   // ////////////////////////////////////////////////////////////////////
00370 
00371   // Specialization of the template method hasList above for the types
00372   // <AirlineFeature,Inventory>.
00373   template<> 
00374   inline bool BomManager::hasList<AirlineFeature,Inventory>
00375   (const Inventory& ioInventory) {
00376     
00377     const bool hasList = false;
00378     return hasList;
00379   }
00380   
00381   // Specialization of the template method hasMap above for the types
00382   // <AirlineFeature,Inventory>.
00383   template<> 
00384   inline bool BomManager::hasMap<AirlineFeature,Inventory>
00385   (const Inventory& ioInventory) {
00386     
00387     const bool hasMap = false;
00388     return hasMap;
00389   }
00390 
00391   // Specialization of the template method getObjectPtr above for the types
00392   // <AirlineFeature,Inventory>.
00393   template<> 
00394   inline AirlineFeature* BomManager::getObjectPtr<AirlineFeature,Inventory>
00395   (const Inventory& iInventory, const MapKey_T& iKey) {
00396 
00397     AirlineFeature* lAirlineFeature_ptr = iInventory.getAirlineFeature ();
00398 
00399     return lAirlineFeature_ptr;
00400   }
00401 
00402   // Specialization of the template method getObject above for the types
00403   // <AirlineFeature,Inventory>.
00404   template<> 
00405   inline AirlineFeature& BomManager::getObject<AirlineFeature,Inventory>
00406   (const Inventory& iInventory, const MapKey_T& iKey) {
00407 
00408     AirlineFeature* lAirlineFeature_ptr =
00409       getObjectPtr<AirlineFeature,Inventory> (iInventory, iKey);
00410     assert (lAirlineFeature_ptr != NULL);
00411     
00412     return *lAirlineFeature_ptr;
00413   }
00414 
00415   
00416 }
00417 #endif // __STDAIR_BOM_BOMMANAGER_HPP