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