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