Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

RegistryEntry.cpp

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiKernel/src/Lib/RegistryEntry.cpp,v 1.1.1.1 2001/04/18 18:14:18 tlindner Exp $
00002 //====================================================================
00003 //      RegistryEntry.cpp
00004 //--------------------------------------------------------------------
00005 //
00006 //      Package    : DataSvc ( The LHCb Offline System)
00007 //
00008 //  Description: implementation of the Transient data store
00009 //
00010 //      Author     : M.Frank
00011 //  History    :
00012 // +---------+----------------------------------------------+---------
00013 // |    Date |                 Comment                      | Who     
00014 // +---------+----------------------------------------------+---------
00015 // | 29/10/98| Initial version                              | MF
00016 // | 03/02/99| Protect dynamic_cast with try-catch clauses  | MF
00017 // +---------+----------------------------------------------+---------
00018 //
00019 //====================================================================
00020 #define  DATASVC_REGISTRYENTRY_CPP
00021 
00022 // STL include files
00023 #include <algorithm>
00024 
00025 // Interfaces
00026 #include "GaudiKernel/IDataStoreAgent.h"
00027 #include "GaudiKernel/IOpaqueAddress.h"
00028 
00029 // Framework include files
00030 #include "GaudiKernel/DataObject.h"
00031 #include "GaudiKernel/RegistryEntry.h"
00032 
00034 RegistryEntry::RegistryEntry(const std::string& path, RegistryEntry* parent)
00035 : m_refCount(0), 
00036   m_isSoft(false), 
00037   m_path(path),
00038   m_parent(parent),
00039   m_address(0),
00040   m_object(0), 
00041   m_transientStore(0)
00042 {
00043   int sep = m_path.rfind(SEPARATOR);
00044   if ( path[0] != SEPARATOR )   {
00045     m_path = SEPARATOR;
00046     m_path += path;
00047   }
00048   if ( sep > 0 )    {
00049     m_path.erase(0,sep);
00050   }
00051   addRef();
00052 }
00053 
00055 RegistryEntry::~RegistryEntry()  {
00056   deleteElements();
00057   if ( 0 != m_object  )   {
00058     if ( !m_isSoft ) m_object->setDirectory(0);
00059     m_object->release();
00060   }
00061   if ( 0 != m_address )   {
00062     if ( !m_isSoft ) m_address->setDirectory(0);
00063     m_address->release();
00064   }
00065 }
00066 
00068 void RegistryEntry::makeSoft(DataObject* pObject)   {
00069   m_isSoft = true;
00070   setObject(pObject);
00071   if ( 0 != m_object )   {
00072     setAddress(m_object->address());
00073   }
00074 }
00075 
00077 void RegistryEntry::makeSoft(IOpaqueAddress* pAddress)   {
00078   m_isSoft = true;
00079   setAddress(pAddress);
00080 }
00081 
00083 void RegistryEntry::makeHard(DataObject* pObject)   {
00084   makeSoft(pObject);
00085   m_isSoft = false;
00086   if ( 0 != m_object )   {
00087     m_object->setDirectory(this);
00088   }
00089   if ( 0 != m_address )   {
00090     m_address->setDirectory(this);
00091   }
00092 }
00093 
00095 void RegistryEntry::makeHard(IOpaqueAddress* pAddress)   {
00096   makeSoft(pAddress);
00097   m_isSoft = false;
00098   if ( 0 != m_address )   {
00099     m_address->setDirectory(this);
00100   }
00101 }
00102 
00104 void RegistryEntry::setAddress( IOpaqueAddress* pAddress )    {
00105   if ( 0 != pAddress  ) pAddress->addRef();
00106   if ( 0 != m_address ) m_address->release();
00107   m_address = pAddress;
00108 }
00109 
00111 void RegistryEntry::setObject( DataObject* pObject )   {
00112   if ( 0 != pObject  ) pObject->addRef();
00113   if ( 0 != m_object ) m_object->release();
00114   m_object = pObject;
00115 }
00116 
00118 unsigned long RegistryEntry::release()  {
00119   unsigned long cnt = --m_refCount;
00120   if ( 0 == m_refCount )   {
00121     delete this;
00122   }
00123   return cnt;
00124 }
00125 
00127 const CLID& RegistryEntry::clID   ()  const  {
00128   if ( 0 == m_object )   {
00129     return CLID_NULL;
00130   }
00131   else  {
00132     return m_object->clID();
00133   }
00134 }
00135 
00137 long RegistryEntry::remove  ( IDataDirectory* obj )    {
00138   try   {
00139     RegistryEntry* pEntry = dynamic_cast<RegistryEntry*>(obj);
00140     Store::iterator i = std::remove(m_store.begin(), m_store.end(), pEntry);
00141     if (i != m_store.end())   {
00142       pEntry->release();
00143       m_store.erase( i, m_store.end() );
00144     }
00145   }
00146   catch ( ... )   {     }
00147   return m_store.size();
00148 }
00149 
00151 long RegistryEntry::remove ( const std::string& name )  {
00152   std::string path = name;
00153   if ( path[0] != SEPARATOR )   {
00154     path  = SEPARATOR;
00155     path += name;
00156   }
00157   // if this object is already present, this is an error....
00158   for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00159     if ( path == (*i)->name() )   {
00160       //      (*i)->release();
00161       remove(*i);
00162       return StatusCode::SUCCESS;
00163     }
00164   }
00165   return StatusCode::FAILURE;
00166 }
00167 
00169 RegistryEntry* RegistryEntry::i_add(const std::string& name)    {
00170   std::string path = name;
00171   if ( path[0] != SEPARATOR )   {
00172     path  = SEPARATOR;
00173     path += name;
00174   }
00175   // if this object is already present, this is an error....
00176   for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00177     if ( path == (*i)->name() )  {
00178       return 0;
00179     }
00180   }
00181   return new RegistryEntry( path, this );
00182 }
00183 
00185 long RegistryEntry::add( IDataDirectory* obj )    {
00186   try   {
00187     RegistryEntry* pEntry = dynamic_cast<RegistryEntry*>(obj);
00188     pEntry->setStore(m_transientStore);
00189     m_store.push_back(pEntry);
00190     pEntry->m_parent = this;
00191     if ( !pEntry->isSoft() && pEntry->address() != 0 )   {
00192       pEntry->address()->setDirectory(pEntry);
00193     }
00194   }
00195   catch ( ... )   {     }
00196   return m_store.size();
00197 }
00198 
00200 long RegistryEntry::add ( const std::string& name, DataObject* pObject, bool is_soft )  {
00201   RegistryEntry* entry = i_add(name);
00202   if ( 0 != entry )   {
00203     ( is_soft ) ? entry->makeSoft(pObject) : entry->makeHard(pObject);
00204     add( entry );
00205     return StatusCode::SUCCESS;
00206   }
00207   return StatusCode::FAILURE;
00208 }
00209 
00211 long RegistryEntry::add ( const std::string& name, IOpaqueAddress* pAddress, bool is_soft )  {
00212   RegistryEntry* entry = i_add(name);
00213   if ( 0 != entry )   {
00214     ( is_soft ) ? entry->makeSoft(pAddress) : entry->makeHard(pAddress);
00215     add( entry );
00216     return StatusCode::SUCCESS;
00217   }
00218   return StatusCode::FAILURE;
00219 }
00220 
00222 long RegistryEntry::deleteElements()   {
00223   for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00224       (*i)->deleteElements();
00225       (*i)->release();
00226   }
00227   m_store.erase(m_store.begin(), m_store.end());
00228   return 0;
00229 }
00230 
00232 const IDataDirectory* RegistryEntry::i_find( const IDataDirectory* obj )  const  {
00233   Store::const_iterator i = std::find(m_store.begin(),m_store.end(),obj);
00234   return (i==m_store.end()) ? 0 : (*i);
00235 }
00236 
00238 const IDataDirectory* RegistryEntry::i_find ( const std::string& path )  const  {
00239   if ( path[0] == '/' )   {
00240     return i_findLeaf(path);
00241   }
00242   else  {
00243     std::string searchpath(name());
00244     searchpath += SEPARATOR;
00245     searchpath += path;
00246     return i_findLeaf(searchpath);
00247   }
00248 }
00249 
00251 const RegistryEntry* RegistryEntry::i_findLeaf(const std::string& path)   const    {
00252   if ( path == m_path )    {
00253     return this;
00254   }
00255   else  {
00256     int loc1 = path.find(SEPARATOR,1);
00257     std::string obj_path(path, 0, loc1>0 ? loc1 : path.length());
00258     if ( obj_path == m_path )   {
00259       std::string daughter(path, loc1>0 ? loc1 : path.length(), path.length());
00260       return i_findLeaf(daughter);
00261     }
00262     else  {
00263       for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00264         if ( obj_path == (*i)->name() )  {
00265           try   {
00266             const RegistryEntry* result = dynamic_cast<const RegistryEntry*>(*i);
00267             if ( loc1 > 0 )   {
00268               std::string search_path(path, loc1, path.length());
00269               result = result->i_findLeaf(search_path);
00270               if ( 0 != result )  return result;
00271             }
00272             else  {
00273               return result;
00274             }
00275           }
00276           catch (...)   {          }
00277         }
00278       }
00279     }
00280   }
00281   return 0;
00282 }
00283 
00285 const RegistryEntry* RegistryEntry::i_findLeaf(const DataObject* key)  const  {
00286   if ( 0 != key )  {
00287     if ( key == m_object )    {
00288       return this;
00289     }
00290     // Look in the immediate level:
00291     const RegistryEntry *result = dynamic_cast<const RegistryEntry*>(i_find(key->directory()));
00292     if ( 0 != result ) return result;
00293     // Go levels down
00294     for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00295       try   {
00296         const RegistryEntry *entry = dynamic_cast<RegistryEntry*>(*i);
00297         if(NULL != (result = entry->i_findLeaf(key))) 
00298           return result;
00299       }
00300       catch ( ... )   {    }
00301     }
00302   }
00303   return 0;
00304 }
00305 
00307 RegistryEntry* RegistryEntry::findParent(const std::string& path)    {
00308   int len = m_path.length();
00309   int loc = path.rfind(RegistryEntry::SEPARATOR);
00310   if ( strncmp(path.data(), m_path.data(), len) == 0 && loc >= len)   {
00311     std::string p_path(path, len, loc-len);
00312     if ( p_path.length() > 0 )  {
00313        RegistryEntry* entry = findLeaf(p_path);
00314        return entry;
00315     }
00316     return this;
00317   }
00318   return 0;
00319 }
00320 
00322 RegistryEntry* RegistryEntry::findParent(DataObject* pObject)    {
00323   if ( 0 != pObject )   {
00324     try   {
00325       RegistryEntry* entry = dynamic_cast<RegistryEntry*>(pObject->directory());
00326       if ( 0 != entry )   {
00327         RegistryEntry* parent = entry->parentEntry();
00328         return parent;
00329       }
00330     }
00331     catch (...)   {   }
00332   }
00333   return 0;
00334 }
00335 
00336 // Traverse registry tree
00337 StatusCode RegistryEntry::traverseTree(IDataStoreAgent* pAgent, int level)    {
00338   bool go_down = pAgent->analyse(this, level);
00339   StatusCode status = StatusCode::SUCCESS;
00340   if ( go_down )    {
00341     for ( Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00342       try   {
00343         RegistryEntry* entry = dynamic_cast<RegistryEntry*>(*i);
00344         entry->traverseTree(pAgent, level+1);
00345       }
00346       catch (...)   {
00347         status = StatusCode::FAILURE;
00348       }
00349     }
00350   }
00351   return status;
00352 }
00353 
00354 // Retrieve the location of the object (= full path of parent)
00355 const std::string& RegistryEntry::location()    const   {
00356   static std::string nullLocation("");
00357   return ( 0 == m_parent ) ? nullLocation : m_parent->fullpath();
00358 }
00359 
00360 // Recursive helper to assemble the full path name of the entry
00361 void RegistryEntry::assemblePath(std::string& buffer)  const  {
00362   if ( m_parent != 0 )    {
00363     m_parent->assemblePath(buffer);
00364   }
00365   buffer += m_path;
00366 }
00367 
00368 // Retrieve the location of the object (= full path of parent)
00369 const std::string& RegistryEntry::fullpath()    const   {
00370   std::string& buff = (std::string&)m_fullpath;
00371   buff = "";
00372   assemblePath(buff);
00373   return buff;
00374 }

Generated at Wed Nov 21 12:22:05 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000