openModeller  Version 1.4.0
PreMultiContainer.hh
Go to the documentation of this file.
00001 
00027 #ifndef PRE_MULTICONTAINER_HH
00028   #define PRE_MULTICONTAINER_HH
00029 
00030   #include <openmodeller/Log.hh>
00031   #include <openmodeller/Exceptions.hh>
00032   
00033   #include <time.h>
00034   
00035   #include <vector>
00036   #include <map>
00037   #include <typeinfo>
00038 
00039   //adapted from Terralib PDI (Digital Image Processing) to OM Pre-analysis ( Missae & Emiliano - DPI/INPE )
00040   //Multi-container node interface.
00041   //author Emiliano F. Castejon <castejon@dpi.inpe.br>
00042   template< typename PreMultiContainerKeyT >
00043   class MCNodeInterface {
00044     public :
00045     
00046       //Default Constructor.    
00047       MCNodeInterface() {};
00048       
00049       //Default Destructor.  
00050       virtual ~MCNodeInterface() {};
00051       
00057       virtual MCNodeInterface< PreMultiContainerKeyT >* clone() 
00058         const = 0;
00059         
00064       virtual const std::string& getObjTypeInfo() const = 0;
00065       
00066     private :
00067     
00068       //Alternative constructor.  
00069       MCNodeInterface( 
00070         const MCNodeInterface< PreMultiContainerKeyT >& ) {};    
00071     
00076       const MCNodeInterface< PreMultiContainerKeyT >& operator=( 
00077         const MCNodeInterface< PreMultiContainerKeyT >& ) {};        
00078   };
00079 
00080   //adapted from Terralib PDI (Digital Image Processing) to OM Pre-analysis ( Missae & Emiliano - DPI/INPE )
00081   // Multi-container node class.
00082   //author Emiliano F. Castejon <castejon@dpi.inpe.br>
00083   template< typename ObjectT, typename PreMultiContainerKeyT >
00084   class MCNode : public MCNodeInterface< PreMultiContainerKeyT > {
00085     public :
00086     
00087       //Default Constructor.
00088       MCNode() 
00089       {
00090         obj_ptr_ = 0;
00091       };
00092       
00093       //Default Destructor.
00094       ~MCNode()
00095       {
00096         if( obj_ptr_ ) {
00097           delete obj_ptr_;
00098         }
00099       };
00100       
00106       MCNodeInterface< PreMultiContainerKeyT >* clone() const
00107       {
00108         MCNode< ObjectT, PreMultiContainerKeyT >* new_node_ptr =
00109           new MCNode< ObjectT, PreMultiContainerKeyT >;
00110           
00111         if( obj_ptr_ ) {
00112           new_node_ptr->obj_ptr_ = new ObjectT;
00113           ( *( new_node_ptr->obj_ptr_ ) ) = ( *obj_ptr_ );
00114           
00115           new_node_ptr->obj_type_str_ = obj_type_str_;
00116         }
00117         
00118         return new_node_ptr;
00119       };
00120       
00125       void setObjPtr( ObjectT* ptr ) 
00126       { 
00127     if( !ptr ) {
00128       std::string msg = "MCNode::setObjPtr: Invalid pointer.\n";
00129       Log::instance()->error( msg.c_str() );
00130       throw InvalidParameterException( msg );
00131     }
00132         
00133         if( obj_ptr_ ) {
00134           delete obj_ptr_;
00135         }      
00136       
00137         obj_ptr_ = ptr;
00138         obj_type_str_ = std::string( typeid( *ptr ).name() );
00139       };
00140       
00145       ObjectT* getObjPtr() const
00146       { 
00147         return obj_ptr_; 
00148       };
00149       
00154       const std::string& getObjTypeInfo() const
00155       { 
00156         return obj_type_str_; 
00157       };      
00158       
00159     protected :
00160       
00161  
00162       //The internal object pointer.
00163       ObjectT* obj_ptr_;
00164       
00165       //The internal object type.
00166       std::string obj_type_str_;      
00167       
00168   }; 
00169 
00170   //adapted from Terralib PDI (Digital Image Processing) to OM Pre-analysis ( Missae & Emiliano - DPI/INPE )
00171   //A container class to store multiple types os object copies.
00172   //author Emiliano F. Castejon <castejon@dpi.inpe.br>
00173   //note: This is a thread-safe class.
00174   //note: Do not use this class with polymorphic types !!
00175   template< typename PreMultiContainerKeyT >
00176   class PreMultiContainer {
00177   
00178     public :
00179     
00180       //brief Default Constructor
00181       PreMultiContainer();
00182       
00183       //Alternative Constructor
00184       //external: External reference.
00185       PreMultiContainer( 
00186         const PreMultiContainer< PreMultiContainerKeyT >& external );      
00187 
00188       //Default Destructor
00189       ~PreMultiContainer();
00190                            
00198       bool operator==( 
00199         const PreMultiContainer< PreMultiContainerKeyT >& ext_instance ) const;
00200       
00208       bool operator!=( 
00209         const PreMultiContainer< PreMultiContainerKeyT >& ext_instance ) const;
00210       
00217       const PreMultiContainer< PreMultiContainerKeyT >& operator=( 
00218         const PreMultiContainer< PreMultiContainerKeyT >& ext_instance );
00219       
00220       //Clear all contents.
00221       void clear();
00222                          
00229       template< typename ObjectT >
00230       void store( const PreMultiContainerKeyT& obj_key,
00231                          const ObjectT& obj_reference );
00232       
00240       template< typename ObjectT >
00241       bool retrieve( const PreMultiContainerKeyT& obj_key,
00242         ObjectT& obj_reference ) const;
00243         
00250       template< typename ObjectT >
00251       void multiRetrieve( std::vector< std::pair< PreMultiContainerKeyT, 
00252         ObjectT > >& objs_vector ) const;        
00253      
00261       template< typename ObjectT >
00262       bool isStored( const PreMultiContainerKeyT& obj_key ) const;
00263       
00269       void remove( const PreMultiContainerKeyT& obj_key );      
00270       
00271     protected :
00272 
00273       //Internal container type definition. 
00274       typedef typename std::map< PreMultiContainerKeyT,
00275         MCNodeInterface< PreMultiContainerKeyT >* > IntContainerT;
00276       
00277       //The nodes container instance. 
00278       IntContainerT container_instance_;    
00279       
00280       //The last update time.
00281       time_t last_up_time_;
00282 
00288       void update_time();            
00289 
00290 };
00291 
00292 template< typename PreMultiContainerKeyT >
00293 PreMultiContainer< PreMultiContainerKeyT >::PreMultiContainer()
00294 {
00295   last_up_time_ = 0;
00296 }
00297 
00298 template< typename PreMultiContainerKeyT >
00299 PreMultiContainer< PreMultiContainerKeyT >::PreMultiContainer( 
00300   const PreMultiContainer< PreMultiContainerKeyT >& external )
00301 {
00302   last_up_time_ = 0;
00303   
00304   operator=( external );
00305 }
00306 
00307 template< typename PreMultiContainerKeyT >
00308 PreMultiContainer< PreMultiContainerKeyT >::~PreMultiContainer()
00309 {
00310   clear();
00311 }
00312 
00313 template< typename PreMultiContainerKeyT >
00314 void PreMultiContainer< PreMultiContainerKeyT >::clear()
00315 {
00316   
00317   typename IntContainerT::iterator it = container_instance_.begin();
00318   typename IntContainerT::iterator it_end = container_instance_.end();
00319   
00320   while( it != it_end ) {
00321     delete (it->second);
00322     
00323     ++it;
00324   }
00325   
00326   container_instance_.clear();
00327   
00328 }
00329 
00330 template< typename PreMultiContainerKeyT >
00331 bool PreMultiContainer< PreMultiContainerKeyT >::operator==( 
00332   const PreMultiContainer< PreMultiContainerKeyT >& ext_instance ) const
00333 {
00334   if( last_up_time_ == ext_instance.last_up_time_ ) {
00335     return true;
00336   } else {
00337     return false;
00338   }
00339 }
00340 
00341 template< typename PreMultiContainerKeyT >
00342 bool PreMultiContainer< PreMultiContainerKeyT >::operator!=( 
00343   const PreMultiContainer< PreMultiContainerKeyT >& ext_instance ) 
00344   const
00345 {
00346   if( last_up_time_ == ext_instance.last_up_time_ ) {
00347     return false;
00348   } else {
00349     return true;
00350   }
00351 }
00352 
00353 template< typename PreMultiContainerKeyT >
00354 const PreMultiContainer< PreMultiContainerKeyT >& 
00355 PreMultiContainer< PreMultiContainerKeyT >::operator=( 
00356   const PreMultiContainer< PreMultiContainerKeyT >& ext_instance )
00357 {
00358   if( ( &ext_instance ) != this ) {
00359     
00360     //Clearing the current objects 
00361     
00362     typename IntContainerT::iterator my_container_it = 
00363       container_instance_.begin();
00364     typename IntContainerT::iterator my_container_it_end = 
00365       container_instance_.end();
00366     
00367     while( my_container_it != my_container_it_end ) {
00368       delete (my_container_it->second);
00369       
00370       ++my_container_it;
00371     }    
00372     
00373     container_instance_.clear();
00374     
00375     //Cloning external objects 
00376     
00377     typename IntContainerT::const_iterator container_it = 
00378       ext_instance.container_instance_.begin();
00379     typename IntContainerT::const_iterator container_it_end = 
00380       ext_instance.container_instance_.end();
00381           
00382     while( container_it != container_it_end ) {
00383       container_instance_[ container_it->first ] = 
00384         container_it->second->clone();
00385           
00386       ++container_it;
00387     }
00388   
00389     last_up_time_ = ext_instance.last_up_time_;
00390   
00391      
00392   }
00393 
00394   return *this;
00395 }
00396 
00397 template< typename PreMultiContainerKeyT >
00398 void PreMultiContainer< PreMultiContainerKeyT >::update_time()
00399 {
00400   last_up_time_ = time( 0 );
00401 }
00402 
00403 template< typename PreMultiContainerKeyT >
00404 template< typename ObjectT >
00405 void PreMultiContainer< PreMultiContainerKeyT >::store( 
00406   const PreMultiContainerKeyT& obj_key, const ObjectT& obj_reference )
00407 {
00408 
00409   //Creating a new node 
00410   
00411   ObjectT* newobjptr = new ObjectT;
00412   ( *newobjptr ) = obj_reference;
00413   
00414   MCNode< ObjectT, PreMultiContainerKeyT >* newnodeptr =
00415     new MCNode< ObjectT, PreMultiContainerKeyT >;  
00416   newnodeptr->setObjPtr( newobjptr );
00417   
00418   typename IntContainerT::iterator container_it = 
00419     container_instance_.find( obj_key );
00420     
00421   //If a old node with the same key exists, it will be deleted 
00422     
00423   if( container_it == container_instance_.end() ) {
00424     container_instance_[ obj_key ] = newnodeptr;
00425   } else {
00426     delete (container_it->second);
00427     
00428     container_it->second = newnodeptr;
00429   }
00430       
00431   update_time();
00432   
00433 }
00434 
00435 template< typename PreMultiContainerKeyT >
00436 template< typename ObjectT >
00437 bool PreMultiContainer< PreMultiContainerKeyT >::retrieve(
00438   const PreMultiContainerKeyT& obj_key, ObjectT& obj_reference ) const
00439 {
00440   
00441   typename IntContainerT::const_iterator container_it = 
00442     container_instance_.find( obj_key );
00443     
00444   if( container_it == container_instance_.end() ) {
00445     
00446     return false;
00447   } else {
00448     if( typeid( ObjectT ).name() == 
00449       container_it->second->getObjTypeInfo() ) {
00450       
00451       obj_reference = 
00452         ( *( ( (MCNode< ObjectT, PreMultiContainerKeyT >* )
00453         container_it->second )->getObjPtr() ) );
00454     
00455       return true;
00456     } else {
00457    
00458       return false;
00459     }
00460   }
00461 }
00462 
00463 template< typename PreMultiContainerKeyT >
00464 template< typename ObjectT >
00465 void PreMultiContainer< PreMultiContainerKeyT >::multiRetrieve(
00466   std::vector< std::pair< PreMultiContainerKeyT, 
00467   ObjectT > >& objs_vector ) const
00468 {
00469   objs_vector.clear();
00470   
00471   typename IntContainerT::const_iterator container_it = 
00472     container_instance_.begin();
00473   typename IntContainerT::const_iterator container_it_end = 
00474     container_instance_.end();
00475   
00476   std::pair< PreMultiContainerKeyT, ObjectT > temp_pair;
00477   
00478   while( container_it != container_it_end ) {
00479     if( typeid( ObjectT ).name() == 
00480       container_it->second->getObjTypeInfo() ) {  
00481       
00482       temp_pair.first = container_it->first;
00483       temp_pair.second = 
00484         ( *( ( ( MCNode< ObjectT, PreMultiContainerKeyT >* )
00485         container_it->second )->getObjPtr() ) );
00486     
00487       objs_vector.push_back( temp_pair );      
00488     }  
00489   
00490     ++container_it;
00491   }
00492   
00493 }
00494 
00495 template< typename PreMultiContainerKeyT >
00496 template< typename ObjectT >
00497 bool PreMultiContainer< PreMultiContainerKeyT >::isStored( 
00498   const PreMultiContainerKeyT& obj_key ) const
00499 {
00500  
00501   typename IntContainerT::const_iterator container_it = 
00502     container_instance_.find( obj_key );
00503     
00504   if( container_it == container_instance_.end() ) {
00505     
00506     return false;
00507   } else {
00508     if( typeid( ObjectT ).name() == 
00509       container_it->second->getObjTypeInfo() ) {
00510     
00511       return true;
00512     } else {
00513     
00514       return false;
00515     }
00516   }
00517 }
00518 
00519 
00520 template< typename PreMultiContainerKeyT >
00521 void PreMultiContainer< PreMultiContainerKeyT >::remove( 
00522   const PreMultiContainerKeyT& obj_key )
00523 {
00524   
00525   typename IntContainerT::iterator container_it = 
00526     container_instance_.find( obj_key );
00527     
00528   //If a old node with the same key exists, it will be deleted 
00529     
00530   if( container_it != container_instance_.end() ) {
00531     delete (container_it->second);
00532     
00533     container_instance_.erase( container_it );
00534   }
00535       
00536   update_time();
00537   
00538 }
00539 
00540 #endif
00541