openModeller
Version 1.4.0
|
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