00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define DATASVC_REGISTRYENTRY_CPP
00021
00022
00023 #include <algorithm>
00024
00025
00026 #include "GaudiKernel/IDataStoreAgent.h"
00027 #include "GaudiKernel/IOpaqueAddress.h"
00028
00029
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
00158 for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ ) {
00159 if ( path == (*i)->name() ) {
00160
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
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
00291 const RegistryEntry *result = dynamic_cast<const RegistryEntry*>(i_find(key->directory()));
00292 if ( 0 != result ) return result;
00293
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
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
00355 const std::string& RegistryEntry::location() const {
00356 static std::string nullLocation("");
00357 return ( 0 == m_parent ) ? nullLocation : m_parent->fullpath();
00358 }
00359
00360
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
00369 const std::string& RegistryEntry::fullpath() const {
00370 std::string& buff = (std::string&)m_fullpath;
00371 buff = "";
00372 assemblePath(buff);
00373 return buff;
00374 }