00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #define DATASVC_DATASVC_CPP
00020
00021
00022 #include "GaudiKernel/IConverter.h"
00023 #include "GaudiKernel/IOpaqueAddress.h"
00024 #include "GaudiKernel/IConversionSvc.h"
00025
00026 #include "GaudiKernel/xtoa.h"
00027 #include "GaudiKernel/SvcFactory.h"
00028 #include "GaudiKernel/DataObject.h"
00029 #include "GaudiKernel/GaudiException.h"
00030
00031 #include "GaudiKernel/RegistryEntry.h"
00032 #include "GaudiKernel/DataSvc.h"
00033 #include "GaudiKernel/DataIncident.h"
00034 #include "GaudiKernel/IIncidentSvc.h"
00035
00036
00037 #include <cassert>
00038 #include <cstdlib>
00039 #include <vector>
00040 #include <algorithm>
00041 #include <sstream>
00042
00043 namespace {
00046 inline std::string itemToPath(int item) {
00047 std::ostringstream path;
00048 path << '/' << item;
00049 return path.str();
00050 }
00051 }
00052
00053
00054
00055
00056
00057
00058 #define CAST_REGENTRY(x,y) dynamic_cast<x>(y)
00059
00060 typedef DataSvcHelpers::RegistryEntry RegEntry;
00061
00062 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
00063 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
00064
00065 #define DEBMSG ON_DEBUG debug()
00066 #define VERMSG ON_VERBOSE verbose()
00067
00071 StatusCode DataSvc::clearSubTree(const std::string& sub_tree_path) {
00072 DataObject* pObject = 0;
00073 StatusCode status = findObject(sub_tree_path, pObject);
00074 if ( status.isSuccess() ) {
00075 RegEntry* node_entry = CAST_REGENTRY(RegEntry*,pObject->registry());
00076 if ( 0 != node_entry ) {
00077 RegEntry* parent = node_entry->parentEntry();
00078 if ( 0 != parent ) {
00079 parent->remove(node_entry);
00080 return StatusCode::SUCCESS;
00081 }
00082 return INVALID_PARENT;
00083 }
00084 return INVALID_OBJECT;
00085 }
00086 return status;
00087 }
00088
00092 StatusCode DataSvc::clearSubTree(DataObject* pObject) {
00093 if ( checkRoot() ) {
00094 RegEntry* entry = CAST_REGENTRY(RegEntry*,pObject->registry());
00095 if ( 0 != entry ) {
00096 RegEntry* parent = entry->parentEntry();
00097 if ( 0 != parent ) {
00098 parent->remove(entry);
00099 return SUCCESS;
00100 }
00101 return INVALID_PARENT;
00102 }
00103 return INVALID_OBJECT;
00104 }
00105 return INVALID_ROOT;
00106 }
00107
00109 StatusCode DataSvc::clearStore() {
00110 if ( checkRoot() ) {
00111 m_root->release();
00112 m_root = 0;
00113 return SUCCESS;
00114 }
00115 return INVALID_ROOT;
00116 }
00117
00121 StatusCode DataSvc::traverseSubTree (const std::string& sub_tree_path,
00122 IDataStoreAgent* pAgent) {
00123 DataObject* pO = 0;
00124 StatusCode status = findObject(sub_tree_path, pO);
00125 if ( status.isSuccess() ) {
00126 status = traverseSubTree(pO, pAgent);
00127 }
00128 return status;
00129 }
00130
00132 StatusCode DataSvc::traverseSubTree ( DataObject* pObject,
00133 IDataStoreAgent* pAgent ) {
00134 if ( checkRoot() ) {
00135 RegEntry* entry = CAST_REGENTRY(RegEntry*,pObject->registry());
00136 if ( 0 != entry ) {
00137 return entry->traverseTree(pAgent);
00138 }
00139 return INVALID_OBJECT;
00140 }
00141 return INVALID_ROOT;
00142 }
00143
00145 StatusCode DataSvc::traverseTree(IDataStoreAgent* pAgent) {
00146 if ( checkRoot() ) {
00147 return m_root->traverseTree(pAgent);
00148 }
00149 return INVALID_ROOT;
00150 }
00151
00156 StatusCode DataSvc::setRoot(const std::string& root_path,
00157 DataObject* pRootObj) {
00158 clearStore().ignore();
00159 return i_setRoot (root_path, pRootObj);
00160 }
00161
00167 StatusCode DataSvc::i_setRoot(const std::string& root_path,
00168 DataObject* pRootObj) {
00169 if ( 0 != pRootObj ) {
00170 m_root = new RegEntry(root_path);
00171 m_root->makeHard(pRootObj);
00172 m_root->setDataSvc(this);
00173 preLoad().ignore();
00174 }
00175 return SUCCESS;
00176 }
00177
00182 StatusCode DataSvc::setRoot(const std::string& root_path,
00183 IOpaqueAddress* pRootAddr) {
00184 clearStore().ignore();
00185 return i_setRoot (root_path, pRootAddr);
00186 }
00187
00193 StatusCode DataSvc::i_setRoot(const std::string& root_path,
00194 IOpaqueAddress* pRootAddr) {
00195 if ( 0 != pRootAddr ) {
00196 m_root = new RegEntry(root_path);
00197 m_root->makeHard(pRootAddr);
00198 m_root->setDataSvc(this);
00199 preLoad().ignore();
00200 }
00201 return SUCCESS;
00202 }
00203
00205 StatusCode DataSvc::setDataLoader(IConversionSvc* pDataLoader) {
00206 if ( 0 != pDataLoader ) pDataLoader->addRef();
00207 if ( 0 != m_dataLoader ) m_dataLoader->release();
00208 if ( 0 != pDataLoader ) {
00209 pDataLoader->setDataProvider(this).ignore();
00210 }
00211 m_dataLoader = pDataLoader;
00212 return SUCCESS;
00213 }
00214
00216 StatusCode DataSvc::objectParent(const DataObject* pObject,
00217 IRegistry*& refpParent) {
00218 if ( pObject ) {
00219 return objectParent(pObject->registry(), refpParent);
00220 }
00221 return INVALID_OBJECT;
00222 }
00224 StatusCode DataSvc::objectParent(const IRegistry* pRegistry,
00225 IRegistry*& refpParent) {
00226 if ( checkRoot() ) {
00227 const RegEntry* node_entry = CAST_REGENTRY(const RegEntry*,pRegistry);
00228 if ( node_entry ) {
00229 refpParent = node_entry->parent();
00230 return StatusCode::SUCCESS;
00231 }
00232 return INVALID_OBJECT;
00233 }
00234 return INVALID_ROOT;
00235 }
00236
00238 StatusCode DataSvc::objectLeaves( const DataObject* pObject,
00239 std::vector<IRegistry*>& leaves) {
00240 if ( pObject ) {
00241 return objectLeaves(pObject->registry(), leaves);
00242 }
00243 return INVALID_OBJECT;
00244 }
00245
00249 StatusCode DataSvc::objectLeaves( const IRegistry* pRegistry,
00250 std::vector<IRegistry*>& leaves) {
00251 if ( checkRoot() ) {
00252 const RegEntry* node_entry = CAST_REGENTRY(const RegEntry*,pRegistry);
00253 if ( node_entry ) {
00254 leaves = node_entry->leaves();
00255 return StatusCode::SUCCESS;
00256 }
00257 return INVALID_OBJECT;
00258 }
00259 return INVALID_ROOT;
00260 }
00261
00263 StatusCode DataSvc::registerAddress(const std::string& fullPath,
00264 IOpaqueAddress* pAddress) {
00265 if ( fullPath.length() > 0 ) {
00266 if ( fullPath[0] != SEPARATOR ) {
00267 return registerAddress(m_root, fullPath, pAddress);
00268 }
00269 IRegistry* pRegistry = 0;
00270 return registerAddress(pRegistry, fullPath, pAddress);
00271 }
00272 return INVALID_OBJ_PATH;
00273 }
00274
00276 StatusCode DataSvc::registerAddress(DataObject* parentObj,
00277 const std::string& objectPath,
00278 IOpaqueAddress* pAddress) {
00279 IRegistry* pRegistry = (0 == parentObj) ? 0 : parentObj->registry();
00280 return registerAddress(pRegistry, objectPath, pAddress);
00281 }
00282
00284 StatusCode DataSvc::registerAddress(IRegistry* parentObj,
00285 const std::string& objPath,
00286 IOpaqueAddress* pAddress) {
00287 if ( checkRoot() ) {
00288 if ( objPath.length() > 0 ) {
00289 if ( 0 == parentObj ) {
00290 if ( objPath[0] != SEPARATOR ) {
00291 return registerAddress(m_root, objPath, pAddress);
00292 }
00293 std::string::size_type sep = objPath.find(SEPARATOR,1);
00294 if ( sep != std::string::npos ) {
00295 std::string p_path (objPath, 0, sep);
00296 if ( p_path == m_rootName ) {
00297 std::string o_path (objPath, sep, objPath.length());
00298 return registerAddress(m_root, o_path, pAddress);
00299 }
00300 }
00301 return INVALID_PARENT;
00302 }
00303 if ( objPath[0] != SEPARATOR ) {
00304 std::string path;
00305 path = SEPARATOR;
00306 path += objPath;
00307 return registerAddress(parentObj, path, pAddress);
00308 }
00309 RegEntry* par_entry = CAST_REGENTRY(RegEntry*,parentObj);
00310 if ( 0 != par_entry ) {
00311 std::string::size_type sep = objPath.rfind(SEPARATOR);
00312 if ( sep > 0 && sep != std::string::npos ) {
00313 std::string p_path (objPath, 0, sep);
00314 std::string o_path (objPath, sep, objPath.length());
00315 RegEntry* p_entry = par_entry->findLeaf(p_path);
00316
00317
00318 if ( 0 == p_entry && m_forceLeaves ) {
00319 DataObject *pLeaf = createDefaultObject();
00320 StatusCode sc = registerObject(par_entry->identifier(),
00321 p_path,
00322 pLeaf);
00323 if ( ! sc.isSuccess() ) {
00324 delete pLeaf;
00325 }
00326 p_entry = par_entry->findLeaf(p_path);
00327 }
00328 if ( 0 != p_entry ) {
00329 return registerAddress(p_entry, o_path, pAddress);
00330 }
00331 return INVALID_PARENT;
00332 }
00333 StatusCode status = par_entry->add(objPath, pAddress);
00334 if ( status.isSuccess() ) {
00335 return status;
00336 }
00337 return DOUBL_OBJ_PATH;
00338 }
00339 return INVALID_PARENT;
00340 }
00341 return INVALID_OBJ_PATH;
00342 }
00343 return INVALID_ROOT;
00344 }
00345
00347 StatusCode DataSvc::unregisterAddress(const std::string& fullPath) {
00348 if ( fullPath.length() > 0 ) {
00349 IRegistry* pRegistry = 0;
00350 if ( fullPath[0] != SEPARATOR ) {
00351 return unregisterAddress(m_root, fullPath);
00352 }
00353 return unregisterAddress(pRegistry, fullPath);
00354 }
00355 return INVALID_OBJ_PATH;
00356 }
00357
00359 StatusCode DataSvc::unregisterAddress(DataObject* pParent,
00360 const std::string& objPath) {
00361 IRegistry* pRegistry = (0 == pParent) ? 0 : pParent->registry();
00362 return unregisterAddress(pRegistry, objPath);
00363 }
00364
00366 StatusCode DataSvc::unregisterAddress(IRegistry* pParent,
00367 const std::string& objPath) {
00368 if ( checkRoot() ) {
00369 if ( objPath.length() > 0 ) {
00370 if ( 0 == pParent ) {
00371 if ( objPath[0] != SEPARATOR ) {
00372 return unregisterAddress(m_root, objPath);
00373 }
00374 std::string::size_type sep = objPath.find(SEPARATOR,1);
00375 if ( sep != std::string::npos ) {
00376 std::string p_path (objPath, 0, sep);
00377 if ( p_path == m_rootName ) {
00378 std::string o_path (objPath, sep, objPath.length());
00379 return unregisterAddress(m_root, o_path);
00380 }
00381 }
00382 return INVALID_PARENT;
00383 }
00384 if ( objPath[0] != SEPARATOR ) {
00385 std::string path;
00386 path = SEPARATOR;
00387 path += objPath;
00388 return unregisterAddress(pParent, path);
00389 }
00390 RegEntry* node_entry = CAST_REGENTRY(RegEntry*,pParent);
00391 if ( 0 != node_entry ) {
00392 RegEntry* leaf_entry = node_entry->findLeaf(objPath);
00393 if ( 0 != leaf_entry ) {
00394 std::string::size_type sep = objPath.rfind(SEPARATOR);
00395 if ( sep > 0 && sep != std::string::npos ) {
00396 std::string path = objPath.substr(sep);
00397 return unregisterAddress(leaf_entry->parent(), path);
00398 }
00399 StatusCode status = node_entry->remove(objPath);
00400 if ( status.isSuccess() ) {
00401 return status;
00402 }
00403 }
00404 }
00405 return INVALID_PARENT;
00406 }
00407 return INVALID_OBJ_PATH;
00408 }
00409 return INVALID_ROOT;
00410 }
00411
00413 StatusCode DataSvc::registerObject (const std::string& fullPath,
00414 DataObject* pObject) {
00415 return registerObject(0, fullPath, pObject);
00416 }
00417
00418
00420 StatusCode DataSvc::registerObject (const std::string& parentPath,
00421 const std::string& objPath,
00422 DataObject* pObject) {
00423 DataObject* pO = 0;
00424 StatusCode status = retrieveObject(parentPath, pO);
00425 if ( !status.isSuccess() && m_forceLeaves ) {
00426 pO = createDefaultObject();
00427 status = registerObject(parentPath, pO);
00428 if ( !status.isSuccess() ) {
00429 pO->release();
00430 }
00431 }
00432 if ( status.isSuccess() ) {
00433 status = registerObject(pO, objPath, pObject);
00434 }
00435 return status;
00436 }
00437
00439 StatusCode DataSvc::registerObject(const std::string& parentPath,
00440 int item,
00441 DataObject* pObject) {
00442 return registerObject(parentPath, itemToPath(item), pObject);
00443 }
00444
00446 StatusCode DataSvc::registerObject(DataObject* parentObj,
00447 int item,
00448 DataObject* pObject) {
00449 return registerObject(parentObj, itemToPath(item), pObject);
00450 }
00451
00453 StatusCode DataSvc::registerObject(DataObject* parentObj,
00454 const std::string& objPath,
00455 DataObject* pObject) {
00456 if ( checkRoot() ) {
00457 if ( 0 == parentObj ) {
00458 if ( objPath.length() > 0 ) {
00459 if ( objPath[0] == SEPARATOR ) {
00460 std::string::size_type sep = objPath.find(SEPARATOR,1);
00461 if ( sep != std::string::npos ) {
00462 std::string p_path (objPath, 0, sep);
00463 std::string o_path (objPath, sep, objPath.length());
00464 return registerObject(p_path, o_path, pObject);
00465 }
00466 }
00467 else {
00468 return registerObject(m_rootName, objPath, pObject);
00469 }
00470 }
00471 return INVALID_OBJ_PATH;
00472 }
00473 RegEntry* node_entry = CAST_REGENTRY(RegEntry*,parentObj->registry());
00474 if ( 0 != node_entry ) {
00475 StatusCode status = INVALID_PARENT;
00476 std::string::size_type sep = objPath.find(SEPARATOR,1);
00477 if ( sep != std::string::npos ) {
00478 std::string p_path (objPath, 0, sep);
00479 std::string o_path (objPath, sep, objPath.length());
00480 RegEntry* par_entry = node_entry->findLeaf(p_path);
00481
00482
00483 if ( 0 == par_entry && m_forceLeaves ) {
00484 DataObject *pLeaf = createDefaultObject();
00485 StatusCode sc = registerObject(parentObj, p_path, pLeaf);
00486 if ( ! sc.isSuccess() ) {
00487 delete pLeaf;
00488 }
00489 par_entry = node_entry->findLeaf(p_path);
00490 }
00491 else if ( 0 != par_entry && par_entry->object() == 0 ) {
00492 status = retrieveEntry( node_entry, p_path, par_entry);
00493 if ( !status.isSuccess() && !par_entry->address() && m_forceLeaves ) {
00494 DataObject *pLeaf = createDefaultObject();
00495 StatusCode sc = registerObject(parentObj, p_path, pLeaf);
00496 if ( ! sc.isSuccess() ) {
00497 delete pLeaf;
00498 }
00499 par_entry = node_entry->findLeaf(p_path);
00500 }
00501 }
00502 node_entry = par_entry;
00503 if ( 0 != node_entry ) {
00504 DataObject* obj = node_entry->object();
00505 if ( 0 != obj ) {
00506 status = registerObject( obj, o_path, pObject );
00507 }
00508 }
00509 }
00510 else {
00511 RegEntry* leaf = node_entry->findLeaf(objPath);
00512 if ( 0 == leaf ) {
00513 status = node_entry->add( objPath, pObject );
00514 }
00515 else {
00516 DataObject* obj = leaf->object();
00517 if ( 0 == obj ) {
00518 if (0 == pObject) {
00519 error() << "registerObject: trying to register null DataObject" << endmsg;
00520 return StatusCode::FAILURE;
00521 }
00522 else {
00523 pObject->setRegistry(leaf);
00524 }
00525 leaf->setAddress(0);
00526 leaf->setObject(pObject);
00527 status = StatusCode::SUCCESS;
00528 }
00529 else {
00530 status = DOUBL_OBJ_PATH;
00531 }
00532 }
00533 }
00534 return status;
00535 }
00536 return INVALID_PARENT;
00537 }
00538 return INVALID_ROOT;
00539 }
00540
00542 StatusCode DataSvc::unregisterObject(const std::string& fullPath) {
00543 DataObject* pObject = 0;
00544 StatusCode status = findObject(fullPath, pObject);
00545 if ( status.isSuccess() ) {
00546 RegEntry* pEntry = CAST_REGENTRY(RegEntry*,pObject->registry());
00547 if ( 0 != pEntry ) {
00548 if ( pEntry->isEmpty() ) {
00549 RegEntry* pParent = pEntry->parentEntry();
00550 if ( 0 != pParent ) {
00551 if ( 0 != pObject ) {
00552 pObject->addRef();
00553 }
00554 pParent->remove(pEntry);
00555 return StatusCode::SUCCESS;
00556 }
00557 return INVALID_PARENT;
00558 }
00559 return DIR_NOT_EMPTY;
00560 }
00561 return INVALID_ROOT;
00562 }
00563 return status;
00564 }
00565
00567 StatusCode DataSvc::unregisterObject(const std::string& parentPath,
00568 const std::string& objPath) {
00569 DataObject* pO = 0;
00570 StatusCode status = findObject(parentPath, pO);
00571 if ( status.isSuccess() ) {
00572 status = unregisterObject(pO, objPath);
00573 }
00574 return status;
00575 }
00576
00578 StatusCode DataSvc::unregisterObject(const std::string& parentPath, int item) {
00579 return unregisterObject(parentPath, itemToPath(item));
00580 }
00581
00583 StatusCode DataSvc::unregisterObject(DataObject* pObject) {
00584 if ( checkRoot() ) {
00585 RegEntry* entry = m_root->findLeaf(pObject);
00586 if ( 0 != entry ) {
00587 RegEntry* parent = entry->parentEntry();
00588 if ( 0 != parent ) {
00589 if ( entry->isEmpty() ) {
00590 if ( 0 != entry->object() ) {
00591 entry->object()->addRef();
00592 }
00593 if ( 0 != parent ) {
00594 parent->remove(entry);
00595 }
00596 return SUCCESS;
00597 }
00598 return INVALID_PARENT;
00599 }
00600 return DIR_NOT_EMPTY;
00601 }
00602 return INVALID_OBJECT;
00603 }
00604 return INVALID_ROOT;
00605 }
00606
00608 StatusCode DataSvc::unregisterObject (DataObject* pParentObj,
00609 const std::string& objectPath) {
00610 if ( checkRoot() ) {
00611 try {
00612 RegEntry* parent = CAST_REGENTRY(RegEntry*,pParentObj->registry());
00613 if ( 0 != parent ) {
00614 RegEntry* entry = parent->findLeaf(objectPath);
00615 if ( 0 != entry ) {
00616 if ( entry->isEmpty() ) {
00617 if ( 0 != entry->object() ) {
00618 entry->object()->addRef();
00619 }
00620 parent->remove(entry);
00621 return SUCCESS;
00622 }
00623 return DIR_NOT_EMPTY;
00624 }
00625 return INVALID_OBJECT;
00626 }
00627 }
00628 catch(...) {
00629 }
00630 return INVALID_PARENT;
00631 }
00632 return INVALID_ROOT;
00633 }
00634
00636 StatusCode DataSvc::unregisterObject(DataObject* pParentObj, int item) {
00637 return unregisterObject(pParentObj, itemToPath(item));
00638 }
00639
00642 DataObject* DataSvc::handleDataFault(IRegistry* pReg, const std::string& path)
00643 {
00644 if ( m_enableFaultHdlr ) {
00645 IRegistry* pLeaf = 0;
00646 if ( pReg && path.length() == 0 ) {
00647 DataIncident incident(name(), m_faultName, pReg->identifier());
00648 m_incidentSvc->fireIncident(incident);
00649 return pReg->object();
00650 }
00651 else if ( pReg ) {
00652 std::string p = pReg->identifier();
00653 if (path[0] != SEPARATOR ) p += SEPARATOR;
00654 p += path;
00655 DataIncident incident(name(), m_faultName, p);
00656 m_incidentSvc->fireIncident(incident);
00657 pLeaf = m_root->findLeaf(p);
00658 }
00659 else {
00660 std::string p = m_root->identifier();
00661 if (path[0] != SEPARATOR ) p += SEPARATOR;
00662 p += path;
00663 DataIncident incident(name(), m_faultName, p);
00664 m_incidentSvc->fireIncident(incident);
00665 pLeaf = m_root->findLeaf(p);
00666 }
00667 if ( pLeaf ) {
00668 return pLeaf->object();
00669 }
00670 }
00671 return 0;
00672 }
00673
00677 StatusCode DataSvc::loadObject(IRegistry* pRegistry) {
00678 IConversionSvc* pLoader = getDataLoader(pRegistry);
00679 return loadObject(pLoader, pRegistry);
00680 }
00681
00685 StatusCode DataSvc::loadObject(IConversionSvc* pLoader, IRegistry* pRegistry) {
00686 StatusCode status = INVALID_OBJ_ADDR;
00687 DataObject* pObject = 0;
00688 if ( 0 == pLoader ) {
00689 if (handleDataFault(pRegistry) != 0) return SUCCESS;
00690 else return NO_DATA_LOADER;
00691 }
00692 if ( 0 == pRegistry ) {
00693 if (handleDataFault(pRegistry) != 0) return SUCCESS;
00694 else return INVALID_OBJ_ADDR;
00695 }
00696
00697 VERMSG << "Requested object " << pRegistry->identifier() << endmsg;
00698
00699 if ( m_enableAccessHdlr ) {
00700
00701 DataIncident incident(name(), m_accessName, pRegistry->identifier());
00702 m_incidentSvc->fireIncident(incident);
00703 }
00704 if ( m_inhibitPathes.size() > 0 ) {
00705 const std::string& ident = pRegistry->identifier();
00706 std::vector<std::string>::iterator inhibit =
00707 std::find(m_inhibitPathes.begin(), m_inhibitPathes.end(), ident);
00708 if ( inhibit != m_inhibitPathes.end() ) {
00709 return NO_ACCESS;
00710 }
00711 }
00712 IOpaqueAddress* pAddress = pRegistry->address();
00713 if ( 0 == pAddress ) {
00714 return INVALID_OBJ_ADDR;
00715 }
00716 try {
00717 status = pLoader->createObj(pAddress, pObject);
00718 if ( status.isSuccess() ) {
00719
00720 VERMSG << "Object " << pRegistry->identifier() << " created" << endmsg;
00721
00722 RegEntry *pEntry = CAST_REGENTRY(RegEntry*,pRegistry);
00723 pEntry->setObject(pObject);
00724
00725 VERMSG << "Filling object " << pRegistry->identifier() << endmsg;
00726 status = pLoader->fillObjRefs(pAddress, pObject);
00727 }
00728 }
00729 catch( const GaudiException& exc ) {
00730 if ( handleDataFault(pRegistry) != 0 ) {
00731 return SUCCESS;
00732 }
00733 throw GaudiException("GaudiException in loadObject() " + pRegistry->identifier(),
00734 name(), StatusCode::FAILURE, exc);
00735 }
00736 catch( const std::exception& x) {
00737 if ( handleDataFault(pRegistry) != 0 ) {
00738 return SUCCESS;
00739 }
00740 throw GaudiException("std::exception in loadObject() " + pRegistry->identifier() +
00741 ": " + System::typeinfoName(typeid(x)) + ", " + x.what(),
00742 name(), StatusCode::FAILURE);
00743 }
00744 catch(...) {
00745 if ( handleDataFault(pRegistry) != 0 ) {
00746 return SUCCESS;
00747 }
00748 throw GaudiException("UNKN exception in loadObject() " + pRegistry->identifier(),
00749 name(), StatusCode::FAILURE);
00750 }
00751 if ( !status.isSuccess() ) {
00752 if ( handleDataFault(pRegistry) != 0 ) {
00753 return StatusCode::SUCCESS;
00754 }
00755 }
00756 ON_VERBOSE if ( status.isSuccess() ) {
00757 verbose() << "Object " << pRegistry->identifier() << " successfully loaded" << endmsg;
00758 }
00759 return status;
00760 }
00761
00763 StatusCode DataSvc::retrieveEntry(RegEntry* parentObj,
00764 const std::string& path,
00765 RegEntry*& pEntry) {
00766 std::string::size_type sep = path.find(SEPARATOR,1);
00767 StatusCode status = StatusCode(INVALID_ROOT,true);
00768 pEntry = 0;
00769
00770 if ( checkRoot() ) {
00771 if ( 0 == parentObj ) {
00772 if ( path.length() == 0 || path == m_rootName ) {
00773 return retrieveEntry(m_root, "", pEntry);
00774 }
00775 else if ( path[0] != SEPARATOR ) {
00776 return retrieveEntry(m_root, path, pEntry);
00777 }
00778 else if ( sep != std::string::npos ) {
00779 if ( m_root->object() == 0 ) {
00780 RegEntry* r = 0;
00781 status = retrieveEntry(m_root, "", r);
00782 if ( !status.isSuccess() ) {
00783 return status;
00784 }
00785 }
00786 std::string o_path (path, sep, path.length());
00787 return retrieveEntry(m_root, o_path, pEntry);
00788 }
00789 return INVALID_OBJ_PATH;
00790 }
00791 if ( sep != std::string::npos ) {
00792 std::string p_path (path,0,sep);
00793 std::string o_path (path,sep,path.length());
00794 if (!parentObj->object()) {
00795 status = loadObject(parentObj);
00796 if ( !status.isSuccess() ) {
00797 return status;
00798 }
00799 }
00800 RegEntry* root_entry = parentObj->findLeaf(p_path);
00801 if ( !root_entry && m_enableFaultHdlr ) {
00802
00803
00804 handleDataFault(parentObj, p_path);
00805 root_entry = parentObj->findLeaf(p_path);
00806 }
00807 if ( root_entry ) {
00808 DataObject* pO = root_entry->object();
00809 if ( 0 == pO ) {
00810
00811 status = loadObject(root_entry);
00812 if ( !status.isSuccess() ) {
00813 return status;
00814 }
00815 }
00816 if ( root_entry->isSoft() ) {
00817 root_entry = CAST_REGENTRY(RegEntry*,pO->registry());
00818 }
00819 return retrieveEntry (root_entry, o_path, pEntry);
00820 }
00821 return status;
00822 }
00823 else if ( path.length() == 0 ) {
00824 pEntry = parentObj;
00825 }
00826 else {
00827 if (!parentObj->object()) {
00828 status = loadObject(parentObj);
00829 if ( !status.isSuccess() ) {
00830 return status;
00831 }
00832 }
00833
00834 pEntry = parentObj->findLeaf(path);
00835
00836 if ( !pEntry && m_enableFaultHdlr ) {
00837 handleDataFault(parentObj, path);
00838 pEntry = (0==path.length()) ? parentObj : parentObj->findLeaf(path);
00839 }
00840 }
00841
00842 if ( 0 == pEntry ) {
00843 status = INVALID_OBJ_PATH;
00844 }
00845 else if ( 0 == pEntry->object() ) {
00846 status = loadObject(pEntry);
00847 }
00848 else if ( m_enableAccessHdlr ) {
00849
00850
00851
00852
00853
00854
00855 status = SUCCESS;
00856 }
00857 else {
00858 status = SUCCESS;
00859 }
00860 }
00861 return status;
00862 }
00863
00865 StatusCode DataSvc::retrieveObject(IRegistry* pRegistry,
00866 const std::string& path,
00867 DataObject*& pObject) {
00868 pObject = 0;
00869 RegEntry *result = 0, *parent = CAST_REGENTRY(RegEntry*,pRegistry);
00870 StatusCode status = retrieveEntry(parent, path, result);
00871 if ( status.isSuccess() ) {
00872 pObject = result->object();
00873 }
00874 return status;
00875 }
00876
00878 StatusCode DataSvc::retrieveObject(const std::string& fullPath,
00879 DataObject*& pObject) {
00880 IRegistry* nullDir = 0;
00881 return retrieveObject(nullDir, fullPath, pObject);
00882 }
00883
00885 StatusCode DataSvc::retrieveObject(const std::string& parentPath,
00886 const std::string& objectPath,
00887 DataObject*& pObject) {
00888 DataObject* parent = 0;
00889 StatusCode status = retrieveObject(parentPath, parent);
00890 if ( status.isSuccess() ) {
00891 status = retrieveObject (parent, objectPath, pObject);
00892 }
00893 return status;
00894 }
00895
00897 StatusCode DataSvc::retrieveObject(const std::string& parentPath,
00898 int item,
00899 DataObject*& pObject) {
00900 return retrieveObject(parentPath, itemToPath(item), pObject);
00901 }
00902
00904 StatusCode DataSvc::retrieveObject(DataObject* parentObj,
00905 const std::string& path,
00906 DataObject*& pObject) {
00907 IRegistry* pRegistry = (0==parentObj) ? 0 : parentObj->registry();
00908 return retrieveObject(pRegistry, path, pObject);
00909 }
00910
00912 StatusCode DataSvc::retrieveObject(DataObject* parentObj,
00913 int item,
00914 DataObject*& pObject) {
00915 return retrieveObject(parentObj, itemToPath(item), pObject);
00916 }
00917
00919 StatusCode DataSvc::findObject(IRegistry* pRegistry,
00920 const std::string& path,
00921 DataObject*& pObject) {
00922 pObject = 0;
00923 IRegistry* pReg = (0==pRegistry) ? m_root : pRegistry;
00924 RegEntry* root_entry = CAST_REGENTRY(RegEntry*, pReg);
00925 if ( 0 != root_entry ) {
00926 if ( path.length() > 0 ) {
00927 pReg = root_entry->find(path);
00928 }
00929 if ( 0 == pReg ) {
00930 return INVALID_OBJ_PATH;
00931 }
00932 pObject = pReg->object();
00933 }
00934 return (0 == pObject) ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR;
00935 }
00936
00938 StatusCode DataSvc::findObject(const std::string& path,
00939 DataObject*& pObject) {
00940 pObject = 0;
00941 if ( checkRoot() ) {
00942 if ( path.length() == 0 || path == m_rootName ) {
00943 pObject = m_root->object();
00944 return (0 == pObject) ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR;
00945 }
00946 else if ( path[0] != SEPARATOR ) {
00947 return findObject(m_rootName, path, pObject);
00948 }
00949 return findObject((IRegistry*)0, path, pObject);
00950 }
00951 return INVALID_ROOT;
00952 }
00953
00955 StatusCode DataSvc::findObject(const std::string& parentPath,
00956 const std::string& objectPath,
00957 DataObject*& pObject) {
00958 DataObject* parent = 0;
00959 StatusCode status = findObject(parentPath, parent);
00960 if ( status.isSuccess() ) {
00961 status = findObject (parent, objectPath, pObject);
00962 }
00963 return status;
00964 }
00965
00967 StatusCode DataSvc::findObject(const std::string& parentPath,
00968 int item, DataObject*& pObject) {
00969 return findObject(parentPath, itemToPath(item), pObject);
00970 }
00971
00973 StatusCode DataSvc::findObject(DataObject* parentObj,
00974 int item,
00975 DataObject*& pObject) {
00976 return findObject(parentObj, itemToPath(item), pObject);
00977 }
00978
00980 StatusCode DataSvc::findObject(DataObject* parentObj,
00981 const std::string& path,
00982 DataObject*& pObject) {
00983 IRegistry* pDir = (0==parentObj) ? 0 : parentObj->registry();
00984 return findObject(pDir, path, pObject);
00985 }
00986
00988 StatusCode DataSvc::updateObject(const std::string& updatePath) {
00989 DataObject* pO = 0;
00990 StatusCode status = findObject(updatePath, pO);
00991 if ( status.isSuccess() ) {
00992 return updateObject(pO);
00993 }
00994 return retrieveObject(updatePath, pO);
00995 }
00996
00998 StatusCode DataSvc::updateObject(IRegistry* pRegistry) {
00999 if ( 0 == pRegistry ) {
01000 return INVALID_OBJ_ADDR;
01001 }
01002 DataObject* toUpdate = pRegistry->object();
01003 if ( 0 == toUpdate ) {
01004 return loadObject(pRegistry);
01005 }
01006 return updateObject(toUpdate);
01007 }
01008
01010 StatusCode DataSvc::updateObject(DataObject* toUpdate) {
01011 StatusCode status = INVALID_OBJ_ADDR;
01012 if ( 0 == toUpdate ) {
01013 return INVALID_OBJECT;
01014 }
01015 IRegistry* pRegistry = toUpdate->registry();
01016 if ( 0 == pRegistry ) {
01017 return INVALID_OBJECT;
01018 }
01019 IOpaqueAddress* pAddress = pRegistry->address();
01020 if ( 0 == pAddress ) {
01021 return INVALID_OBJ_ADDR;
01022 }
01023 IConversionSvc* pLoader = getDataLoader(pRegistry);
01024 if ( 0 == pLoader ) {
01025 return NO_DATA_LOADER;
01026 }
01027 if ( m_inhibitPathes.size() > 0 ) {
01028 const std::string& ident = pRegistry->identifier();
01029 std::vector<std::string>::iterator inhibit =
01030 std::find(m_inhibitPathes.begin(), m_inhibitPathes.end(), ident);
01031 if ( inhibit != m_inhibitPathes.end() ) {
01032 return NO_ACCESS;
01033 }
01034 }
01035 try {
01036 status = pLoader->updateObj(pAddress, toUpdate);
01037 if ( status.isSuccess() ) {
01038 status = pLoader->updateObjRefs(pAddress, toUpdate);
01039 }
01040 }
01041 catch( const GaudiException& exc ) {
01042 throw GaudiException("GaudiException in updateObject() " +
01043 pRegistry->name(),
01044 name(),
01045 StatusCode::FAILURE, exc);
01046 }
01047 catch( const std::exception& x) {
01048 throw GaudiException("std::exception in updateObject() " +
01049 pRegistry->name() + ": " +
01050 System::typeinfoName(typeid(x)) + ", " +
01051 x.what(),
01052 name(), StatusCode::FAILURE);
01053 }
01054 catch(...) {
01055 throw GaudiException("UNKN exception in updateObject() " +
01056 pRegistry->name(),
01057 name(), StatusCode::FAILURE);
01058 }
01059 return status;
01060 }
01061
01063 StatusCode DataSvc::updateObject(const std::string& parentPath,
01064 const std::string& updatePath) {
01065 DataObject* pParent = 0;
01066 StatusCode status = findObject(parentPath, pParent);
01067 if ( status.isSuccess() ) {
01068 status = updateObject( pParent, updatePath);
01069 }
01070 return status;
01071 }
01072
01074 StatusCode DataSvc::updateObject(DataObject* parent,
01075 const std::string& updatePath) {
01076 DataObject* pObject = 0;
01077 StatusCode status = findObject(parent, updatePath, pObject);
01078 if ( status.isSuccess() ) {
01079 status = updateObject(pObject);
01080 }
01081 return status;
01082 }
01083
01084
01085 StatusCode DataSvc::linkObject(IRegistry* from,
01086 const std::string& objPath, DataObject* to) {
01087 if ( checkRoot() ) {
01088 try {
01089 RegEntry* from_entry = CAST_REGENTRY(RegEntry*,from);
01090 if ( 0 != from_entry ) {
01091
01092 RegEntry* to_entry = m_root->findLeaf(to);
01093 if ( 0 == to_entry ) {
01094 return INVALID_OBJECT;
01095 }
01096 else {
01097 std::string::size_type sep = objPath.rfind(SEPARATOR);
01098 if ( sep > 0 && sep != std::string::npos ) {
01099 DataObject* pO = 0;
01100 std::string fromPath(objPath, 0, sep);
01101 StatusCode sc = retrieveObject(from, fromPath, pO);
01102 if ( sc.isSuccess() ) {
01103 std::string toPath(objPath, sep, objPath.length());
01104 sc = linkObject(pO->registry(), toPath, to);
01105 }
01106 return sc;
01107 }
01108
01109 StatusCode status = from_entry->add( objPath, to, true);
01110 return status.isSuccess() ?
01111 IDataProviderSvc_NO_ERROR : DOUBL_OBJ_PATH;
01112 }
01113 }
01114 }
01115 catch (...) {
01116 }
01117 return INVALID_PARENT;
01118 }
01119 return INVALID_ROOT;
01120 }
01121
01123 StatusCode DataSvc::linkObject(const std::string& fullPath,
01124 DataObject* to) {
01125 if ( fullPath.length() > 0 ) {
01126 if ( fullPath[0] != SEPARATOR ) {
01127 return linkObject(m_rootName, fullPath, to);
01128 }
01129 std::string::size_type sep = fullPath.rfind(SEPARATOR);
01130 std::string objPath(fullPath, sep, fullPath.length());
01131 std::string fromPath(fullPath, 0, sep);
01132 return linkObject( fromPath, objPath, to);
01133 }
01134 return INVALID_OBJ_PATH;
01135 }
01136
01138 StatusCode DataSvc::linkObject(const std::string& from,
01139 const std::string& objPath,
01140 DataObject* to) {
01141 DataObject* pO = 0;
01142 StatusCode status = retrieveObject(from, pO);
01143 if ( status.isSuccess() ) {
01144 return linkObject(pO->registry(), objPath, to);
01145 }
01146 return status;
01147 }
01148
01150 StatusCode DataSvc::linkObject(DataObject* from,
01151 const std::string& objPath,
01152 DataObject* to) {
01153 if ( 0 != from ) {
01154 IRegistry* from_entry = from->registry();
01155 if ( 0 != from_entry ) {
01156 return linkObject( from_entry, objPath, to);
01157 }
01158 }
01159 return INVALID_PARENT;
01160 }
01161
01163 StatusCode DataSvc::unlinkObject(IRegistry* from,
01164 const std::string& objPath) {
01165 if ( checkRoot() ) {
01166 try {
01167 RegEntry* from_entry = CAST_REGENTRY(RegEntry*,from);
01168 if ( 0 != from_entry ) {
01169 std::string::size_type sep = objPath.rfind(SEPARATOR);
01170 if ( sep > 0 && sep != std::string::npos ) {
01171 DataObject* pO = 0;
01172 std::string fromPath(objPath, 0, sep);
01173 StatusCode sc = findObject(from, fromPath, pO);
01174 if ( sc.isSuccess() ) {
01175 std::string toPath(objPath, sep, objPath.length());
01176 sc = unlinkObject(pO->registry(), toPath);
01177 }
01178 return sc;
01179 }
01180 StatusCode status = from_entry->remove( objPath );
01181 if ( status.isSuccess() ) {
01182 return status;
01183 }
01184 return INVALID_OBJ_PATH;
01185 }
01186 }
01187 catch (...) {
01188 }
01189 return INVALID_PARENT;
01190 }
01191 return INVALID_ROOT;
01192 }
01193
01195 StatusCode DataSvc::unlinkObject(const std::string& fullPath) {
01196 if ( fullPath.length() > 0 ) {
01197 if ( fullPath[0] != SEPARATOR ) {
01198 return unlinkObject(m_rootName, fullPath);
01199 }
01200 std::string::size_type sep = fullPath.rfind(SEPARATOR);
01201 std::string objPath(fullPath, sep, fullPath.length());
01202 std::string fromPath(fullPath, 0, sep);
01203 return unlinkObject(fromPath, objPath);
01204 }
01205 return INVALID_OBJ_PATH;
01206 }
01207
01209 StatusCode DataSvc::unlinkObject(const std::string& from,
01210 const std::string& objPath) {
01211 DataObject* pObject = 0;
01212 StatusCode status = findObject(from, pObject);
01213 if ( status.isSuccess() ) {
01214 status = unlinkObject(pObject->registry(), objPath);
01215 }
01216 return status;
01217 }
01218
01220 StatusCode DataSvc::unlinkObject(DataObject* from,
01221 const std::string& objPath) {
01222 if ( checkRoot() ) {
01223 IRegistry* from_entry = m_root->findLeaf(from);
01224 return unlinkObject(from_entry, objPath);
01225 }
01226 return INVALID_ROOT;
01227 }
01228
01230 StatusCode DataSvc::addPreLoadItem(const DataStoreItem& item) {
01231 LoadItems::iterator i = std::find(m_preLoads.begin(), m_preLoads.end(), item);
01232 if ( i == m_preLoads.end() ) {
01233 m_preLoads.push_back(item);
01234 }
01235 return StatusCode::SUCCESS;
01236 }
01237
01239 StatusCode DataSvc::addPreLoadItem(const std::string& itemPath) {
01240 return addPreLoadItem( DataStoreItem(itemPath,1) );
01241 }
01242
01244 StatusCode DataSvc::removePreLoadItem(const DataStoreItem& item) {
01245 LoadItems::iterator i =
01246 std::remove(m_preLoads.begin(), m_preLoads.end(), item);
01247 if ( i != m_preLoads.end() ) {
01248 m_preLoads.erase(i, m_preLoads.end());
01249 }
01250 return StatusCode::SUCCESS;
01251 }
01252
01254 StatusCode DataSvc::removePreLoadItem(const std::string& itemPath) {
01255 return removePreLoadItem( DataStoreItem(itemPath,1) );
01256 }
01257
01259 StatusCode DataSvc::resetPreLoad() {
01260 m_preLoads.erase(m_preLoads.begin(), m_preLoads.end());
01261 return StatusCode::SUCCESS;
01262 }
01263
01265 StatusCode DataSvc::preLoad(int depth, int load_depth, DataObject* pObject) {
01266
01267 if ( 0 != pObject && depth++ < load_depth ) {
01268 RegEntry* dir = CAST_REGENTRY(RegEntry*,pObject->registry());
01269 if ( 0 != dir ) {
01270 for (RegEntry::Iterator i = dir->begin(); i != dir->end(); i++ ) {
01271 DataObject *pObj = 0;
01272 StatusCode status = retrieveObject(pObject, (*i)->name(), pObj);
01273 if ( status.isSuccess() && depth < load_depth ) {
01274 preLoad(depth, load_depth, pObj).ignore();
01275 }
01276 }
01277 }
01278 }
01279 return StatusCode::SUCCESS;
01280 }
01281
01283 StatusCode DataSvc::preLoad() {
01284 DataObject* pObj = 0;
01285 for (LoadItems::iterator i = m_preLoads.begin(); i != m_preLoads.end(); i++) {
01286 StatusCode sc = retrieveObject( (*i).path(), pObj);
01287 int load_depth = (*i).depth();
01288 if ( sc.isSuccess() && load_depth > 1 ) {
01289 preLoad(1, load_depth, pObj).ignore();
01290 }
01291 }
01292 return StatusCode::SUCCESS;
01293 }
01294
01296 StatusCode DataSvc::initialize() {
01297
01298 StatusCode sc = Service::initialize();
01299 if ( !sc.isSuccess() ) {
01300 return sc;
01301 }
01302 sc = service("IncidentSvc", m_incidentSvc, true);
01303 if ( UNLIKELY(!sc.isSuccess()) ) {
01304 error() << "Failed to access incident service." << endmsg;
01305 }
01306 return sc;
01307 }
01308
01310 StatusCode DataSvc::reinitialize() {
01311 StatusCode sc;
01312
01313 setDataLoader(0).ignore();
01314 resetPreLoad().ignore();
01315 clearStore().ignore();
01316 if ( m_incidentSvc ) {
01317 m_incidentSvc->release();
01318 m_incidentSvc = 0;
01319 }
01320
01321 sc = Service::reinitialize();
01322 if ( UNLIKELY(!sc.isSuccess()) ) {
01323 error() << "Unable to reinitialize base class" << endmsg;
01324 return sc;
01325 }
01326
01327 sc = service("IncidentSvc", m_incidentSvc, true);
01328 if ( UNLIKELY(!sc.isSuccess()) ) {
01329 error() << "Failed to access incident service." << endmsg;
01330 return sc;
01331 }
01332
01333 return StatusCode::SUCCESS;
01334 }
01335
01337 StatusCode DataSvc::finalize() {
01338
01339 setDataLoader(0).ignore();
01340 resetPreLoad().ignore();
01341 clearStore().ignore();
01342 if ( m_incidentSvc ) {
01343 m_incidentSvc->release();
01344 m_incidentSvc = 0;
01345 }
01346 return Service::finalize();
01347 }
01348
01350 CLID DataSvc::rootCLID() const {
01351 return( (CLID)m_rootCLID );
01352 }
01353
01355 std::string DataSvc::rootName() const {
01356 return( m_rootName );
01357 }
01358
01360 DataObject* DataSvc::createDefaultObject() const {
01361 return new DataObject();
01362 }
01363
01367 IConversionSvc* DataSvc::getDataLoader(IRegistry* ) {
01368 return m_dataLoader;
01369 }
01370
01372 DataSvc::DataSvc(const std::string& name,ISvcLocator* svc)
01373 : base_class(name,svc), m_rootCLID( 110),
01374 m_rootName( "/Event"), m_root(0)
01375 {
01376 m_dataLoader = 0;
01377 m_inhibitMap = 0;
01378 m_incidentSvc = 0;
01379 m_forceLeaves = false;
01380 m_enableFaultHdlr = false;
01381 m_enableAccessHdlr = false;
01382 m_faultName = "DataFault";
01383 m_accessName = "DataAccess";
01384 declareProperty("RootCLID", m_rootCLID);
01385 declareProperty("RootName", m_rootName);
01386 declareProperty("ForceLeaves", m_forceLeaves);
01387 declareProperty("InhibitPathes", m_inhibitPathes);
01388 declareProperty("DataFaultName", m_faultName);
01389 declareProperty("DataAccessName", m_accessName);
01390 declareProperty("EnableFaultHandler", m_enableFaultHdlr);
01391 declareProperty("EnableAccessHandler", m_enableAccessHdlr);
01392 }
01393
01395 DataSvc::~DataSvc() {
01396 setDataLoader(0).ignore();
01397 resetPreLoad().ignore();
01398 clearStore().ignore();
01399 }