![]() |
|
|
Generated: 24 Nov 2008 |
00001 //==================================================================== 00002 // MultiStoreSvc.cpp 00003 //-------------------------------------------------------------------- 00004 // 00005 // Package : System ( The LHCb Offline System) 00006 // 00007 // Description: implementation of the Transient event data service. 00008 // 00009 // Author : M.Frank 00010 // History : 00011 // +---------+----------------------------------------------+--------- 00012 // | Date | Comment | Who 00013 // +---------+----------------------------------------------+--------- 00014 // | 29/10/98| Initial version | MF 00015 // +---------+----------------------------------------------+--------- 00016 // 00017 //==================================================================== 00018 #define DATASVC_MULTISTORESVC_CPP 00019 00020 // Include files 00021 #include "GaudiKernel/Service.h" 00022 #include "GaudiKernel/SmartIF.h" 00023 #include "GaudiKernel/ListItem.h" 00024 #include "GaudiKernel/MsgStream.h" 00025 #include "GaudiKernel/Tokenizer.h" 00026 #include "GaudiKernel/SvcFactory.h" 00027 #include "GaudiKernel/DataObject.h" 00028 #include "GaudiKernel/ISvcLocator.h" 00029 #include "GaudiKernel/ISvcManager.h" 00030 #include "GaudiKernel/IOpaqueAddress.h" 00031 #include "GaudiKernel/IConversionSvc.h" 00032 #include "GaudiKernel/IDataManagerSvc.h" 00033 #include "GaudiKernel/IAddressCreator.h" 00034 #include "GaudiKernel/IDataProviderSvc.h" 00035 #include "GaudiKernel/IPartitionControl.h" 00036 00037 #include <map> 00038 00039 // Forward declarations 00040 // Service factory 00041 template <class TYPE> class SvcFactory; 00042 // This class 00043 class MultiStoreSvc; 00044 00045 typedef const std::string CSTR; 00046 typedef IDataStoreAgent AGENT; 00047 typedef DataObject OBJECT; 00048 typedef IOpaqueAddress ADDRESS; 00049 typedef StatusCode STATUS; 00050 00051 namespace { 00052 00053 struct Partition { 00054 IDataProviderSvc* dataProvider; 00055 IDataManagerSvc* dataManager; 00056 std::string name; 00057 Partition() : dataProvider(0), dataManager(0) 00058 { 00059 } 00060 Partition(const Partition& entry) 00061 : dataProvider(entry.dataProvider), 00062 dataManager(entry.dataManager), 00063 name(entry.name) 00064 { 00065 } 00066 Partition& operator=(const Partition& entry) { 00067 dataProvider = entry.dataProvider; 00068 dataManager = entry.dataManager; 00069 name = entry.name; 00070 return *this; 00071 } 00072 }; 00073 } 00074 00086 class MultiStoreSvc : public Service, 00087 virtual public IDataProviderSvc, 00088 virtual public IDataManagerSvc, 00089 virtual public IPartitionControl 00090 { 00091 protected: 00093 typedef std::vector<std::string> PartitionDefs; 00094 typedef std::map<std::string, Partition> Partitions; 00096 CLID m_rootCLID; 00098 std::string m_rootName; 00100 std::string m_loader; 00102 IConversionSvc* m_dataLoader; 00104 IAddressCreator* m_addrCreator; 00106 enum { no_type = 0, address_type = 1, object_type = 2}; 00107 struct tagROOT { 00108 int type; 00109 std::string path; 00110 union { 00111 ADDRESS* address; 00112 OBJECT* object; 00113 } root; 00114 tagROOT() : type(no_type) { root.address = 0; } 00115 } m_root; 00117 Partition m_current; 00119 Partitions m_partitions; 00121 PartitionDefs m_partitionDefs; 00123 std::string m_defaultPartition; 00124 00125 public: 00127 virtual CLID rootCLID() const { 00128 return (CLID)m_rootCLID; 00129 } 00131 std::string rootName() const { 00132 return m_rootName; 00133 } 00134 00135 // macro to help writing the function calls 00136 #define _CALL(P,F,ARGS) \ 00137 P ? P->F ARGS : IDataProviderSvc::INVALID_ROOT 00138 00140 virtual STATUS registerAddress(CSTR& path, ADDRESS* pAddr) { 00141 return _CALL(m_current.dataManager, registerAddress, (path, pAddr)); 00142 } 00144 virtual STATUS registerAddress(OBJECT* parent, CSTR& path, ADDRESS* pAddr) { 00145 return _CALL(m_current.dataManager, registerAddress, (parent, path, pAddr)); 00146 } 00148 virtual STATUS registerAddress(IRegistry* parent, CSTR& path, ADDRESS* pAdd) { 00149 return _CALL(m_current.dataManager, registerAddress, (parent, path, pAdd)); 00150 } 00152 virtual STATUS unregisterAddress(CSTR& path) { 00153 return _CALL(m_current.dataManager, unregisterAddress, (path)); 00154 } 00156 virtual STATUS unregisterAddress(OBJECT* pParent, CSTR& path) { 00157 return _CALL(m_current.dataManager, unregisterAddress, (pParent, path)); 00158 } 00160 virtual STATUS unregisterAddress(IRegistry* pParent, CSTR& path) { 00161 return _CALL(m_current.dataManager, unregisterAddress, (pParent, path)); 00162 } 00164 virtual STATUS objectLeaves(const OBJECT* pObject, std::vector<IRegistry*>& leaves) { 00165 return _CALL(m_current.dataManager, objectLeaves, (pObject, leaves)); 00166 } 00168 virtual STATUS objectLeaves(const IRegistry* pObject, std::vector<IRegistry*>& leaves) { 00169 return _CALL(m_current.dataManager, objectLeaves, (pObject, leaves)); 00170 } 00172 virtual STATUS objectParent(const OBJECT* pObject, IRegistry*& refpParent) { 00173 return _CALL(m_current.dataManager, objectParent, (pObject, refpParent)); 00174 } 00176 virtual STATUS objectParent(const IRegistry* pObject, IRegistry*& refpParent) { 00177 return _CALL(m_current.dataManager, objectParent, (pObject, refpParent)); 00178 } 00180 virtual STATUS clearSubTree(CSTR& path) { 00181 return _CALL(m_current.dataManager, clearSubTree, (path)); 00182 } 00184 virtual STATUS clearSubTree(OBJECT* pObject) { 00185 return _CALL(m_current.dataManager, clearSubTree, (pObject)); 00186 } 00188 virtual STATUS clearStore() { 00189 Partitions::iterator i; 00190 for(i=m_partitions.begin(); i != m_partitions.end(); ++i) { 00191 (*i).second.dataManager->clearStore().ignore(); 00192 } 00193 if ( m_root.root.object ) { 00194 switch ( m_root.type ) { 00195 case address_type: 00196 m_root.root.address->release(); 00197 break; 00198 case object_type: 00199 m_root.root.object->release(); 00200 break; 00201 } 00202 m_root.root.object = 0; 00203 } 00204 m_root.path = ""; 00205 m_root.type = no_type; 00206 return STATUS::SUCCESS; 00207 } 00209 virtual STATUS traverseSubTree(CSTR& path, AGENT* pAgent) { 00210 return _CALL(m_current.dataManager, traverseSubTree, (path, pAgent)); 00211 } 00213 virtual STATUS traverseSubTree(OBJECT* pObject, AGENT* pAgent) { 00214 return _CALL(m_current.dataManager, traverseSubTree, (pObject, pAgent)); 00215 } 00217 virtual STATUS traverseTree( AGENT* pAgent ) { 00218 return _CALL(m_current.dataManager, traverseTree, (pAgent)); 00219 } 00222 virtual STATUS setRoot( CSTR& path, OBJECT* pObj) { 00223 if ( m_root.root.object ) { 00224 switch ( m_root.type ) { 00225 case address_type: 00226 m_root.root.address->release(); 00227 break; 00228 case object_type: 00229 m_root.root.object->release(); 00230 break; 00231 } 00232 } 00233 m_root.path = path; 00234 m_root.type = object_type; 00235 m_root.root.object = pObj; 00236 preparePartitions(); 00237 return activate(m_defaultPartition); 00238 } 00239 00242 virtual STATUS setRoot (CSTR& path, ADDRESS* pAddr) { 00243 if ( m_root.root.object ) { 00244 switch ( m_root.type ) { 00245 case address_type: 00246 m_root.root.address->release(); 00247 break; 00248 case object_type: 00249 m_root.root.object->release(); 00250 break; 00251 } 00252 } 00253 m_root.path = path; 00254 m_root.type = address_type; 00255 m_root.root.address = pAddr; 00256 if ( m_root.root.address ) { 00257 m_root.root.address->addRef(); 00258 preparePartitions(); 00259 return activate(m_defaultPartition); 00260 } 00261 return STATUS::FAILURE; 00262 } 00264 virtual STATUS setDataLoader(IConversionSvc* pDataLoader) { 00265 Partitions::iterator i; 00266 if ( 0 != pDataLoader ) pDataLoader->addRef(); 00267 if ( 0 != m_dataLoader ) m_dataLoader->release(); 00268 if ( 0 != pDataLoader ) { 00269 pDataLoader->setDataProvider(this); 00270 } 00271 m_dataLoader = pDataLoader; 00272 for(i=m_partitions.begin(); i != m_partitions.end(); ++i) { 00273 (*i).second.dataManager->setDataLoader(m_dataLoader).ignore(); 00274 } 00275 return SUCCESS; 00276 } 00278 virtual STATUS addPreLoadItem(const DataStoreItem& item) { 00279 return _CALL(m_current.dataProvider, addPreLoadItem, (item)); 00280 } 00282 virtual STATUS addPreLoadItem(CSTR& item) { 00283 return _CALL(m_current.dataProvider, addPreLoadItem, (item)); 00284 } 00286 virtual STATUS removePreLoadItem(const DataStoreItem& item) { 00287 return _CALL(m_current.dataProvider, removePreLoadItem, (item)); 00288 } 00290 virtual STATUS removePreLoadItem(CSTR& item) { 00291 return _CALL(m_current.dataProvider, removePreLoadItem, (item)); 00292 } 00294 virtual STATUS resetPreLoad() { 00295 return _CALL(m_current.dataProvider, resetPreLoad, ()); 00296 } 00298 virtual STATUS preLoad() { 00299 return _CALL(m_current.dataProvider, preLoad, ()); 00300 } 00302 virtual STATUS registerObject(CSTR& path, OBJECT* pObj) { 00303 return registerObject(0, path, pObj); 00304 } 00306 virtual STATUS registerObject(CSTR& parent, CSTR& obj, OBJECT* pObj) { 00307 return _CALL(m_current.dataProvider, registerObject, (parent, obj, pObj)); 00308 } 00310 virtual STATUS registerObject(CSTR& parent, int item, OBJECT* pObj) { 00311 return _CALL(m_current.dataProvider, registerObject, (parent, item, pObj)); 00312 } 00314 virtual STATUS registerObject(OBJECT* parent, CSTR& obj, OBJECT* pObj) { 00315 return _CALL(m_current.dataProvider, registerObject, (parent, obj, pObj)); 00316 } 00318 virtual STATUS registerObject(OBJECT* parent, int obj, OBJECT* pObj) { 00319 return _CALL(m_current.dataProvider, registerObject, (parent, obj, pObj)); 00320 } 00322 virtual STATUS unregisterObject(CSTR& path) { 00323 return _CALL(m_current.dataProvider, unregisterObject, (path)); 00324 } 00326 virtual STATUS unregisterObject(CSTR& parent, CSTR& obj) { 00327 return _CALL(m_current.dataProvider, unregisterObject, (parent, obj)); 00328 } 00330 virtual STATUS unregisterObject(CSTR& parent, int obj) { 00331 return _CALL(m_current.dataProvider, unregisterObject, (parent, obj)); 00332 } 00334 virtual STATUS unregisterObject(OBJECT* pObj) { 00335 return _CALL(m_current.dataProvider, unregisterObject, (pObj)); 00336 } 00338 virtual STATUS unregisterObject(OBJECT* pObj, CSTR& path) { 00339 return _CALL(m_current.dataProvider, unregisterObject, (pObj, path)); 00340 } 00342 virtual STATUS unregisterObject(OBJECT* pObj, int item ) { 00343 return _CALL(m_current.dataProvider, unregisterObject, (pObj, item)); 00344 } 00346 virtual STATUS retrieveObject(IRegistry* parent, CSTR& path, OBJECT*& pObj ) { 00347 return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj)); 00348 } 00350 virtual STATUS retrieveObject(CSTR& path, OBJECT*& pObj) { 00351 return _CALL(m_current.dataProvider, retrieveObject, (path, pObj)); 00352 } 00354 virtual STATUS retrieveObject(CSTR& parent, CSTR& path, OBJECT*& pObj ) { 00355 return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj)); 00356 } 00358 virtual STATUS retrieveObject(CSTR& parent, int item, OBJECT*& pObj) { 00359 return _CALL(m_current.dataProvider, retrieveObject, (parent, item, pObj)); 00360 } 00362 virtual STATUS retrieveObject(OBJECT* parent, CSTR& path, OBJECT*& pObj ) { 00363 return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj)); 00364 } 00366 virtual STATUS retrieveObject(OBJECT* parent, int item, OBJECT*& pObj ) { 00367 return _CALL(m_current.dataProvider, retrieveObject, (parent, item, pObj)); 00368 } 00370 virtual STATUS findObject(CSTR& path, OBJECT*& pObj) { 00371 return _CALL(m_current.dataProvider, retrieveObject, (path, pObj)); 00372 } 00374 virtual STATUS findObject(IRegistry* parent, CSTR& path, OBJECT*& pObj) { 00375 return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj)); 00376 } 00378 virtual STATUS findObject(CSTR& parent, CSTR& path, OBJECT*& pObj) { 00379 return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj)); 00380 } 00382 virtual STATUS findObject(CSTR& parent, int item, OBJECT*& pObject ) { 00383 return _CALL(m_current.dataProvider, findObject, (parent, item, pObject)); 00384 } 00386 virtual STATUS findObject(OBJECT* parent, CSTR& path, OBJECT*& pObject) { 00387 return _CALL(m_current.dataProvider, findObject, (parent, path, pObject)); 00388 } 00390 virtual STATUS findObject(OBJECT* parent, int item, OBJECT*& pObject) { 00391 return _CALL(m_current.dataProvider, findObject, (parent, item, pObject)); 00392 } 00394 virtual STATUS linkObject(IRegistry* from, CSTR& objPath, OBJECT* to) { 00395 return _CALL(m_current.dataProvider, linkObject, (from, objPath, to)); 00396 } 00398 virtual STATUS linkObject(CSTR& from, CSTR& objPath, OBJECT* to) { 00399 return _CALL(m_current.dataProvider, linkObject, (from, objPath, to)); 00400 } 00402 virtual STATUS linkObject(OBJECT* from, CSTR& objPath, OBJECT* to) { 00403 return _CALL(m_current.dataProvider, linkObject, (from, objPath, to)); 00404 } 00406 virtual STATUS linkObject(CSTR& fullPath, OBJECT* to) { 00407 return _CALL(m_current.dataProvider, linkObject, (fullPath, to)); 00408 } 00410 virtual STATUS unlinkObject(IRegistry* from, CSTR& objPath) { 00411 return _CALL(m_current.dataProvider, unlinkObject, (from, objPath)); 00412 } 00414 virtual STATUS unlinkObject(CSTR& from, CSTR& objPath) { 00415 return _CALL(m_current.dataProvider, unlinkObject, (from, objPath)); 00416 } 00418 virtual STATUS unlinkObject(OBJECT* from, CSTR& objPath) { 00419 return _CALL(m_current.dataProvider, unlinkObject, (from, objPath)); 00420 } 00422 virtual STATUS unlinkObject(CSTR& path) { 00423 return _CALL(m_current.dataProvider, unlinkObject, (path)); 00424 } 00426 virtual STATUS updateObject(IRegistry* pDirectory ) { 00427 return _CALL(m_current.dataProvider, updateObject, (pDirectory)); 00428 } 00430 virtual STATUS updateObject(CSTR& path) { 00431 return _CALL(m_current.dataProvider, updateObject, (path)); 00432 } 00434 virtual STATUS updateObject(OBJECT* pObj ) { 00435 return _CALL(m_current.dataProvider, updateObject, (pObj)); 00436 } 00438 virtual STATUS updateObject(CSTR& parent, CSTR& updatePath ) { 00439 return _CALL(m_current.dataProvider, updateObject, (parent, updatePath)); 00440 } 00442 virtual STATUS updateObject(OBJECT* parent, CSTR& updatePath) { 00443 return _CALL(m_current.dataProvider, updateObject, (parent, updatePath)); 00444 } 00445 00447 virtual STATUS create(CSTR& nam, CSTR& typ) { 00448 IInterface* pPartition = 0; 00449 return create(nam, typ, pPartition); 00450 } 00451 00453 virtual STATUS create(CSTR& nam, CSTR& typ, IInterface*& pPartition) { 00454 STATUS sc = get(nam, pPartition); 00455 if ( !sc.isSuccess() ) { 00456 ListItem item(typ); 00457 IService* isvc = 0; 00458 STATUS sc = serviceLocator()->getService(item.name(), isvc); 00459 if ( !sc.isSuccess() ) { 00460 SmartIF<ISvcManager> mgr(serviceLocator()); 00461 if ( mgr ) { 00462 sc = mgr->createService(item.type(), item.name(), isvc); 00463 } 00464 } 00465 if ( sc.isSuccess() ) { 00466 SmartIF<IDataManagerSvc> dataMgr(isvc); 00467 SmartIF<IDataProviderSvc> dataProv(isvc); 00468 if ( dataMgr.isValid() && dataProv.isValid() ) { 00469 Partition p; 00470 p.name = nam; 00471 p.dataManager = dataMgr; 00472 p.dataProvider = dataProv; 00473 p.dataManager->addRef(); 00474 p.dataProvider->addRef(); 00475 m_partitions.insert(std::make_pair(nam, p)); 00476 return STATUS::SUCCESS; 00477 } 00478 else { 00479 // Error 00480 return NO_INTERFACE; 00481 } 00482 } 00483 else { 00484 // Error 00485 return NO_INTERFACE; 00486 } 00487 } 00488 return PARTITION_EXISTS; 00489 } 00490 00492 virtual STATUS drop(CSTR& nam) { 00493 Partitions::iterator i = m_partitions.find(nam); 00494 if ( i != m_partitions.end() ) { 00495 if ( (*i).second.dataManager == m_current.dataManager ) { 00496 m_current = Partition(); 00497 } 00498 (*i).second.dataManager->clearStore().ignore(); 00499 (*i).second.dataProvider->release(); 00500 (*i).second.dataManager->release(); 00501 m_partitions.erase(i); 00502 return STATUS::SUCCESS; 00503 } 00504 return PARTITION_NOT_PRESENT; 00505 } 00506 00508 virtual STATUS drop(IInterface* pPartition) { 00509 SmartIF<IDataProviderSvc> provider(pPartition); 00510 if ( provider.isValid() ) { 00511 Partitions::iterator i; 00512 for(i=m_partitions.begin(); i != m_partitions.end(); ++i) { 00513 if ( (*i).second.dataProvider == provider ) { 00514 (*i).second.dataManager->clearStore().ignore(); 00515 (*i).second.dataProvider->release(); 00516 (*i).second.dataManager->release(); 00517 m_partitions.erase(i); 00518 return STATUS::SUCCESS; 00519 } 00520 } 00521 return PARTITION_NOT_PRESENT; 00522 } 00523 return NO_INTERFACE; 00524 } 00525 00527 virtual STATUS activate(CSTR& nam) { 00528 Partitions::const_iterator i = m_partitions.find(nam); 00529 if ( i != m_partitions.end() ) { 00530 m_current = (*i).second; 00531 return STATUS::SUCCESS; 00532 } 00533 m_current = Partition(); 00534 return PARTITION_NOT_PRESENT; 00535 } 00536 00538 virtual STATUS activate(IInterface* pPartition) { 00539 SmartIF<IDataProviderSvc> provider(pPartition); 00540 m_current = Partition(); 00541 if ( provider ) { 00542 Partitions::iterator i; 00543 for(i=m_partitions.begin(); i != m_partitions.end(); ++i) { 00544 if ( (*i).second.dataProvider == provider ) { 00545 m_current = (*i).second; 00546 return STATUS::SUCCESS; 00547 } 00548 } 00549 return PARTITION_NOT_PRESENT; 00550 } 00551 return NO_INTERFACE; 00552 } 00553 00555 virtual STATUS get(CSTR& nam, IInterface*& pPartition) const { 00556 Partitions::const_iterator i = m_partitions.find(nam); 00557 if ( i != m_partitions.end() ) { 00558 pPartition = (*i).second.dataProvider; 00559 return STATUS::SUCCESS; 00560 } 00561 pPartition = 0; 00562 return PARTITION_NOT_PRESENT; 00563 } 00564 00566 virtual StatusCode activePartition(std::string& nam, IInterface*& pPartition) const { 00567 if ( m_current.dataProvider ) { 00568 nam = m_current.name; 00569 pPartition = m_current.dataProvider; 00570 return STATUS::SUCCESS; 00571 } 00572 nam = ""; 00573 pPartition = 0; 00574 return NO_ACTIVE_PARTITION; 00575 } 00576 00578 virtual STATUS queryInterface( const InterfaceID& riid, void** ppvUnknown ) { 00579 if ( IDataProviderSvc::interfaceID().versionMatch(riid) ) 00580 *ppvUnknown = (IDataProviderSvc*)this; 00581 else if ( IDataManagerSvc::interfaceID().versionMatch(riid) ) 00582 *ppvUnknown = (IDataManagerSvc*)this; 00583 else if ( IPartitionControl::interfaceID().versionMatch(riid) ) 00584 *ppvUnknown = (IPartitionControl*)this; 00585 else 00586 return Service::queryInterface(riid, ppvUnknown); 00587 addRef(); 00588 return SUCCESS; 00589 } 00590 00591 STATUS attachServices() { 00592 MsgStream log(msgSvc(), name()); 00593 // Attach address creator facility 00594 STATUS sc = service(m_loader, m_addrCreator, true); 00595 if (!sc.isSuccess()) { 00596 log << MSG::ERROR 00597 << "Failed to retrieve data loader " 00598 << "\"" << m_loader << "\"" << endmsg; 00599 return sc; 00600 } 00601 IConversionSvc* dataLoader = 0; 00602 // Attach data loader facility 00603 sc = service(m_loader, dataLoader, true); 00604 if (!sc.isSuccess()) { 00605 log << MSG::ERROR << "Failed to retrieve data loader " 00606 << "\"" << m_loader << "\"" << endmsg; 00607 return sc; 00608 } 00609 sc = setDataLoader(dataLoader); 00610 dataLoader->release(); 00611 if (!sc.isSuccess()) { 00612 log << MSG::ERROR << "Failed to set data loader " 00613 << "\"" << m_loader << "\"" << endmsg; 00614 return sc; 00615 } 00616 return sc; 00617 } 00618 00619 STATUS detachServices() { 00620 if ( m_addrCreator ) m_addrCreator->release(); 00621 if ( m_dataLoader ) m_dataLoader->release(); 00622 m_addrCreator = 0; 00623 m_dataLoader = 0; 00624 return STATUS::SUCCESS; 00625 } 00626 00628 virtual STATUS initialize() { 00629 // Nothing to do: just call base class initialisation 00630 STATUS sc = Service::initialize(); 00631 if ( !sc.isSuccess() ) { 00632 return sc; 00633 } 00634 sc = makePartitions(); 00635 if (!sc.isSuccess()) { 00636 MsgStream log(msgSvc(), name()); 00637 log << MSG::ERROR << "Failed to connect to all store partitions." << endmsg; 00638 return sc; 00639 } 00640 return attachServices(); 00641 } 00642 00644 virtual STATUS reinitialize() { 00645 STATUS sc = Service::reinitialize(); 00646 MsgStream log(msgSvc(), name()); 00647 if (!sc.isSuccess()) { 00648 log << MSG::ERROR << "Enable to reinitialize base class" 00649 << endmsg; 00650 return sc; 00651 } 00652 detachServices(); 00653 sc = attachServices(); 00654 if ( !sc.isSuccess() ) { 00655 log << MSG::ERROR << "Failed to attach necessary services." << endmsg; 00656 return sc; 00657 } 00658 sc = makePartitions(); 00659 if (!sc.isSuccess()) { 00660 log << MSG::ERROR << "Failed to connect to store partitions." << endmsg; 00661 return sc; 00662 } 00663 // return 00664 return STATUS::SUCCESS; 00665 } 00666 00668 virtual STATUS finalize() { 00669 setDataLoader(0).ignore(); 00670 clearStore().ignore(); 00671 clearPartitions().ignore(); 00672 m_current = Partition(); 00673 detachServices(); 00674 return Service::finalize(); 00675 } 00676 00677 00678 //protected: 00679 00681 MultiStoreSvc( CSTR& name, ISvcLocator* svc ) 00682 : Service(name,svc), m_rootCLID(110), m_rootName("/Event"), 00683 m_dataLoader(0), m_addrCreator(0) 00684 { 00685 m_dataLoader = 0; 00686 declareProperty("RootCLID", m_rootCLID); 00687 declareProperty("RootName", m_rootName); 00688 declareProperty("Partitions", m_partitionDefs); 00689 declareProperty("DataLoader", m_loader="EventPersistencySvc"); 00690 declareProperty("DefaultPartition", m_defaultPartition="Default"); 00691 } 00692 00694 virtual ~MultiStoreSvc() { 00695 setDataLoader(0).ignore(); 00696 resetPreLoad().ignore(); 00697 clearStore().ignore(); 00698 clearPartitions().ignore(); 00699 } 00700 00702 STATUS preparePartitions() { 00703 STATUS iret = STATUS::SUCCESS; 00704 for(Partitions::iterator i=m_partitions.begin(); i != m_partitions.end(); ++i) { 00705 STATUS sc = STATUS::FAILURE; 00706 switch ( m_root.type ) { 00707 case address_type: 00708 if ( m_root.root.address ) { 00709 ADDRESS* pAdd = 0; 00710 ADDRESS* p = m_root.root.address; 00711 sc = m_addrCreator->createAddress(p->svcType(), 00712 p->clID(), 00713 p->par(), 00714 p->ipar(), 00715 pAdd); 00716 if ( sc.isSuccess() ) { 00717 sc = (*i).second.dataManager->setRoot(m_root.path, pAdd); 00718 } 00719 } 00720 break; 00721 case object_type: 00722 if ( m_root.root.object ) { 00723 if ( m_root.root.object->clID() == CLID_DataObject ) { 00724 DataObject* pObj = new DataObject(); 00725 sc = (*i).second.dataManager->setRoot(m_root.path, pObj); 00726 } 00727 } 00728 break; 00729 default: 00730 sc = STATUS::FAILURE; 00731 break; 00732 } 00733 if ( !sc.isSuccess() ) { 00734 iret = sc; 00735 } 00736 } 00737 return iret; 00738 } 00739 00741 STATUS clearPartitions() { 00742 Partitions::iterator i; 00743 for(i=m_partitions.begin(); i != m_partitions.end(); ++i) { 00744 (*i).second.dataManager->clearStore().ignore(); 00745 (*i).second.dataProvider->release(); 00746 (*i).second.dataManager->release(); 00747 } 00748 m_partitions.clear(); 00749 return STATUS::SUCCESS; 00750 } 00751 00753 STATUS makePartitions() { 00754 std::string typ, nam; 00755 PartitionDefs::iterator j; 00756 clearPartitions().ignore(); 00757 for(j=m_partitionDefs.begin(); j != m_partitionDefs.end(); ++j) { 00758 Tokenizer tok(true); 00759 Tokenizer::Items::iterator i; 00760 tok.analyse(*j, " ", "", "", "=", "'", "'"); 00761 for(i = tok.items().begin(); i != tok.items().end(); i++ ) { 00762 CSTR& t = (*i).tag(); 00763 CSTR& v = (*i).value(); 00764 switch( ::toupper(t[0]) ) { 00765 case 'N': 00766 nam = v; 00767 break; 00768 case 'T': 00769 typ = v; 00770 break; 00771 } 00772 } 00773 STATUS sc = create(nam, typ); 00774 if ( !sc.isSuccess() ) { 00775 return sc; 00776 } 00777 else if ( !m_defaultPartition.length() ) { 00778 m_defaultPartition = nam; 00779 } 00780 } 00781 return STATUS::SUCCESS; 00782 } 00783 }; 00784 00785 // Instantiation of a static factory class used by clients to create 00786 // instances of this service 00787 DECLARE_SERVICE_FACTORY(MultiStoreSvc)