StdAir Logo  0.44.0
C++ Standard Airline IT Object Library
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 
00023 namespace stdair {
00024   
00032   class BomManager {
00033     friend class FacBomManager;
00034     
00035   public:
00039     template <typename OBJECT2, typename OBJECT1>
00040     static const typename BomHolder<OBJECT2>::BomList_T& getList(const OBJECT1&);
00041 
00045     template <typename OBJECT2, typename OBJECT1>
00046     static const typename BomHolder<OBJECT2>::BomMap_T& getMap (const OBJECT1&);
00047 
00051     template <typename OBJECT2, typename OBJECT1>
00052     static bool hasList (const OBJECT1&);
00053 
00057     template <typename OBJECT2, typename OBJECT1>
00058     static bool hasMap (const OBJECT1&);
00059 
00065     template <typename PARENT, typename CHILD>
00066     static PARENT* getParentPtr (const CHILD&);
00067 
00071     template <typename PARENT, typename CHILD>
00072     static PARENT& getParent (const CHILD&);
00073 
00079     template <typename OBJECT2, typename OBJECT1>
00080     static OBJECT2* getObjectPtr (const OBJECT1&, const MapKey_T&);
00081 
00085     template <typename OBJECT2, typename OBJECT1>
00086     static OBJECT2& getObject (const OBJECT1&, const MapKey_T&);
00087 
00088 
00089   private:
00094     template <typename OBJECT2, typename OBJECT1>
00095     static const BomHolder<OBJECT2>& getBomHolder (const OBJECT1&);
00096   };
00097 
00098   // ////////////////////////////////////////////////////////////////////
00099   // Private method.
00100   template <typename OBJECT2, typename OBJECT1> 
00101   const BomHolder<OBJECT2>& BomManager::getBomHolder (const OBJECT1& iObject1) {
00102 
00103     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00104     
00105     HolderMap_T::const_iterator itHolder = lHolderMap.find (&typeid (OBJECT2));
00106     
00107     if (itHolder == lHolderMap.end()) {
00108       const std::string lName (typeid (OBJECT2).name());
00109       throw NonInitialisedContainerException ("Cannot find the holder of type "
00110                                               + lName + " within: "
00111                                               + iObject1.describeKey());
00112     } 
00113     
00114     const BomHolder<OBJECT2>* lBomHolder_ptr = 
00115       static_cast<const BomHolder<OBJECT2>*> (itHolder->second);
00116     assert (lBomHolder_ptr != NULL);
00117 
00118     return *lBomHolder_ptr;
00119   }
00120   
00121   // ////////////////////////////////////////////////////////////////////
00122   // Public business method.
00123   // This method is specialized for the following couple types:
00124   // <SegmentDate, SegmentDate>
00125   template <typename OBJECT2, typename OBJECT1>
00126   const typename BomHolder<OBJECT2>::BomList_T& BomManager::
00127   getList (const OBJECT1& iObject1) {
00128     
00129   const BomHolder<OBJECT2>& lBomHolder = getBomHolder<OBJECT2> (iObject1);
00130     return lBomHolder._bomList;
00131   }
00132   
00133   // ////////////////////////////////////////////////////////////////////
00134   // Public business method.
00135   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00136   template <typename OBJECT2, typename OBJECT1>
00137   const typename BomHolder<OBJECT2>::BomMap_T& BomManager::
00138   getMap (const OBJECT1& iObject1) {
00139 
00140     //
00141     // Compile time assertation: this function must never be called with the
00142     // following list of couple types:
00143     // <SegmentDate, SegmentDate>
00144     // 
00145     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00146                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00147     
00148     const BomHolder<OBJECT2>& lBomHolder = getBomHolder<OBJECT2> (iObject1);
00149     return lBomHolder._bomMap;
00150   }
00151   
00152   // ////////////////////////////////////////////////////////////////////
00153   // Public business method.
00154   // This method is specialized for the following couple types:
00155   // <SegmentDate, SegmentDate>
00156   template <typename OBJECT2, typename OBJECT1>
00157   bool BomManager::hasList (const OBJECT1& iObject1) {
00158     
00159     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00160     HolderMap_T::const_iterator itHolder = lHolderMap.find (&typeid (OBJECT2));
00161     
00162     if (itHolder == lHolderMap.end()) {
00163       return false;
00164     }
00165     const BomHolder<OBJECT2>* lBomHolder_ptr = 
00166       static_cast<const BomHolder<OBJECT2>*> (itHolder->second);
00167     assert (lBomHolder_ptr != NULL);
00168 
00169     return !lBomHolder_ptr->_bomList.empty();
00170   }
00171   
00172   // ////////////////////////////////////////////////////////////////////
00173   // Public business method.
00174   // This method is specialized for the following couple types:
00175   // <SegmentDate, SegmentDate>
00176   template <typename OBJECT2, typename OBJECT1>
00177   bool BomManager::hasMap (const OBJECT1& iObject1) {
00178     
00179     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00180     HolderMap_T::const_iterator itHolder = lHolderMap.find (&typeid (OBJECT2));
00181     
00182     if (itHolder == lHolderMap.end()) {
00183       return false;
00184     }
00185     const BomHolder<OBJECT2>* lBomHolder_ptr = 
00186       static_cast<const BomHolder<OBJECT2>*> (itHolder->second);
00187     assert (lBomHolder_ptr != NULL);
00188 
00189     return !lBomHolder_ptr->_bomMap.empty();
00190   }
00191   
00192   // ////////////////////////////////////////////////////////////////////
00193   // Public business method valid for all PARENT and CHILD types.
00194   // (No compile time assertation to check PARENT and CHILD types.)
00195   template <typename PARENT, typename CHILD>
00196   PARENT* BomManager::getParentPtr (const CHILD& iChild) {
00197     
00198     PARENT* const lParent_ptr = static_cast<PARENT* const> (iChild.getParent());
00199     return lParent_ptr; 
00200   }
00201   
00202   // ////////////////////////////////////////////////////////////////////
00203   // Public business method valid for all PARENT and CHILD types.
00204   // (No compile time assertation to check PARENT and CHILD types.)
00205   template <typename PARENT, typename CHILD>
00206   PARENT& BomManager::getParent (const CHILD& iChild) {
00207     
00208     PARENT* const lParent_ptr = getParentPtr<PARENT> (iChild);
00209     assert (lParent_ptr != NULL);
00210     return *lParent_ptr; 
00211   }
00212   
00213   // ////////////////////////////////////////////////////////////////////
00214   // Public business method.
00215   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00216   template <typename OBJECT2, typename OBJECT1>
00217   OBJECT2* BomManager::getObjectPtr (const OBJECT1& iObject1,
00218                                      const MapKey_T& iKey) {
00219 
00220     //
00221     // Compile time assertation: this function must never be called with the
00222     // following list of couple types:
00223     // <SegmentDate, SegmentDate>
00224     // 
00225     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00226                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00227     
00228     OBJECT2* oBom_ptr = NULL;
00229     
00230     const HolderMap_T& lHolderMap = iObject1.getHolderMap();
00231 
00232     typename HolderMap_T::const_iterator itHolder = 
00233       lHolderMap.find (&typeid (OBJECT2));
00234     
00235     if (itHolder != lHolderMap.end()) {
00236     
00237       BomHolder<OBJECT2>* const lBomHolder_ptr = 
00238         static_cast<BomHolder<OBJECT2>* const> (itHolder->second);
00239       assert (lBomHolder_ptr != NULL);
00240 
00241       //
00242       typedef typename BomHolder<OBJECT2>::BomMap_T BomMap_T;
00243       BomMap_T& lBomMap =  lBomHolder_ptr->_bomMap;
00244       typename BomMap_T::iterator itBom = lBomMap.find (iKey);
00245 
00246       if (itBom != lBomMap.end()) {
00247         oBom_ptr = itBom->second;
00248         assert (oBom_ptr != NULL);
00249       }
00250     }
00251 
00252     return oBom_ptr;
00253   }
00254 
00255   // ////////////////////////////////////////////////////////////////////
00256   // Public business method.
00257   // Compile time assertation to check OBJECT1 and OBJECT2 types.
00258   template <typename OBJECT2, typename OBJECT1>
00259   OBJECT2& BomManager::getObject (const OBJECT1& iObject1,
00260                                   const MapKey_T& iKey) {
00261     
00262     //
00263     // Compile time assertation: this function must never be called with the
00264     // following list of couple types:
00265     // <SegmentDate, SegmentDate>
00266     // 
00267     BOOST_STATIC_ASSERT ((boost::is_same<OBJECT1, SegmentDate>::value == false
00268                           || boost::is_same<OBJECT2, SegmentDate>::value == false));
00269     
00270     OBJECT2* oBom_ptr = NULL;
00271     
00272     typedef std::map<const MapKey_T, OBJECT2*> BomMap_T;
00273     const BomMap_T& lBomMap = getMap<OBJECT2> (iObject1);
00274     
00275     typename BomMap_T::const_iterator itBom = lBomMap.find (iKey);
00276 
00277     if (itBom == lBomMap.end()) {
00278       const std::string lName (typeid (OBJECT2).name());
00279       
00280       STDAIR_LOG_ERROR ("Cannot find the objet of type " << lName
00281                         << " with key " << iKey << " within: " 
00282                         << iObject1.describeKey());
00283       assert (false);
00284     }
00285     
00286     oBom_ptr = itBom->second;
00287     assert (oBom_ptr != NULL);
00288 
00289     return *oBom_ptr;
00290   }
00291 
00292   // ////////////////////////////////////////////////////////////////////
00293   //
00294   // Specialization of the template methods above for a segment
00295   // date and its corresponding marketing segment dates.
00296   //
00297   // ////////////////////////////////////////////////////////////////////
00298   
00299   // Specialization of the template method hasList above for the types
00300   // <SegmentDate, SegmentDate>.
00301   // Add an element to the marketing segment date list of a segment date.
00302   template<> 
00303   inline bool BomManager::hasList<SegmentDate,SegmentDate>
00304   (const SegmentDate& ioSegmentDate) {
00305     
00306     const SegmentDateList_T& lMarketingSegmentDateList =
00307       ioSegmentDate.getMarketingSegmentDateList ();
00308     const bool isMarketingSegmentDateListEmpty =
00309       lMarketingSegmentDateList.empty();
00310     return isMarketingSegmentDateListEmpty;
00311   }
00312   
00313   // Specialization of the template method hasList above for the types
00314   // <SegmentDate, SegmentDate>.
00315   // Return a boolean saying if the marketing segment date list is empty
00316   // or not. 
00317   template<> 
00318   inline const BomHolder<SegmentDate>::BomList_T&
00319   BomManager::getList<SegmentDate,SegmentDate> (const SegmentDate& ioSegmentDate) {
00320     
00321     const SegmentDateList_T& lMarketingSegmentDateList =
00322       ioSegmentDate.getMarketingSegmentDateList ();
00323     return lMarketingSegmentDateList;
00324   }
00325   
00326   // Specialization of the template method hasMap above for the types
00327   // <SegmentDate, SegmentDate>.
00328   // A segment date does not have a Segment Date Map but it can have a
00329   // Segment Date list (containing its marketing segment dates). 
00330   template<> 
00331   inline bool BomManager::hasMap<SegmentDate,SegmentDate>
00332   (const SegmentDate& ioSegmentDate) {
00333     
00334     const bool hasList = false;
00335     return hasList;
00336   }
00337   
00338 }
00339 #endif // __STDAIR_BOM_BOMMANAGER_HPP