| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# MultiStoreSvc.cpp

Go to the documentation of this file.

    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)