| # Gaudi Framework, version v21r11 |

Home |  | Generated: 30 Sep 2010

# 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/TypeNameString.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 extends3<Service,
    00087                                      IDataProviderSvc,
    00088                                      IDataManagerSvc,
    00089                                      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       Gaudi::Utils::TypeNameString item(typ);
    00458       SmartIF<IService>& isvc = serviceLocator()->service(typ);
    00459       if (isvc.isValid())  {
    00460         SmartIF<IDataManagerSvc> dataMgr(isvc);
    00461         SmartIF<IDataProviderSvc> dataProv(isvc);
    00462         if ( dataMgr.isValid() && dataProv.isValid() )  {
    00463           Partition p;
    00464           p.name         = nam;
    00465           p.dataManager  = dataMgr;
    00466           p.dataProvider = dataProv;
    00467           p.dataManager->addRef();
    00468           p.dataProvider->addRef();
    00469           m_partitions.insert(std::make_pair(nam, p));
    00470           return STATUS::SUCCESS;
    00471         }
    00472         else  {
    00473           // Error
    00474           return NO_INTERFACE;
    00475         }
    00476       }
    00477       else {
    00478         // Error
    00479         return NO_INTERFACE;
    00480       }
    00481     }
    00482     return PARTITION_EXISTS;
    00483   }
    00484
    00486   virtual STATUS drop(CSTR& nam)   {
    00487     Partitions::iterator i = m_partitions.find(nam);
    00488     if ( i != m_partitions.end() )  {
    00489       if ( (*i).second.dataManager == m_current.dataManager )  {
    00490         m_current = Partition();
    00491       }
    00492       (*i).second.dataManager->clearStore().ignore();
    00493       (*i).second.dataProvider->release();
    00494       (*i).second.dataManager->release();
    00495       m_partitions.erase(i);
    00496       return STATUS::SUCCESS;
    00497     }
    00498     return PARTITION_NOT_PRESENT;
    00499   }
    00500
    00502   virtual STATUS drop(IInterface* pPartition)  {
    00503     SmartIF<IDataProviderSvc> provider(pPartition);
    00504     if ( provider.isValid() )  {
    00505       Partitions::iterator i;
    00506       for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
    00507         if ( (*i).second.dataProvider == provider )  {
    00508           (*i).second.dataManager->clearStore().ignore();
    00509           (*i).second.dataProvider->release();
    00510           (*i).second.dataManager->release();
    00511           m_partitions.erase(i);
    00512           return STATUS::SUCCESS;
    00513         }
    00514       }
    00515       return PARTITION_NOT_PRESENT;
    00516     }
    00517     return NO_INTERFACE;
    00518   }
    00519
    00521   virtual STATUS activate(CSTR& nam) {
    00522     Partitions::const_iterator i = m_partitions.find(nam);
    00523     if ( i != m_partitions.end() )  {
    00524       m_current = (*i).second;
    00525       return STATUS::SUCCESS;
    00526     }
    00527     m_current = Partition();
    00528     return PARTITION_NOT_PRESENT;
    00529   }
    00530
    00532   virtual STATUS activate(IInterface* pPartition) {
    00533     SmartIF<IDataProviderSvc> provider(pPartition);
    00534     m_current = Partition();
    00535     if ( provider )  {
    00536       Partitions::iterator i;
    00537       for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
    00538         if ( (*i).second.dataProvider == provider )  {
    00539           m_current = (*i).second;
    00540           return STATUS::SUCCESS;
    00541         }
    00542       }
    00543       return PARTITION_NOT_PRESENT;
    00544     }
    00545     return NO_INTERFACE;
    00546   }
    00547
    00549   virtual STATUS get(CSTR& nam, IInterface*& pPartition) const  {
    00550     Partitions::const_iterator i = m_partitions.find(nam);
    00551     if ( i != m_partitions.end() )  {
    00552       pPartition = (*i).second.dataProvider;
    00553       return STATUS::SUCCESS;
    00554     }
    00555     pPartition = 0;
    00556     return PARTITION_NOT_PRESENT;
    00557   }
    00558
    00560   virtual StatusCode activePartition(std::string& nam, IInterface*& pPartition) const  {
    00561     if ( m_current.dataProvider )  {
    00562       nam = m_current.name;
    00563       pPartition = m_current.dataProvider;
    00564       return STATUS::SUCCESS;
    00565     }
    00566     nam = "";
    00567     pPartition = 0;
    00568     return NO_ACTIVE_PARTITION;
    00569   }
    00570
    00571   STATUS attachServices()  {
    00572     MsgStream log(msgSvc(), name());
    00573     // Attach address creator facility
    00574     STATUS sc = service(m_loader, m_addrCreator, true);
    00575     if (!sc.isSuccess()) {
    00576       log << MSG::ERROR
    00577           << "Failed to retrieve data loader "
    00578           << "\"" << m_loader << "\"" << endmsg;
    00579       return sc;
    00580     }
    00581     IConversionSvc* dataLoader = 0;
    00582     // Attach data loader facility
    00583     sc = service(m_loader, dataLoader, true);
    00584     if (!sc.isSuccess()) {
    00585       log << MSG::ERROR << "Failed to retrieve data loader "
    00586           << "\"" << m_loader << "\"" << endmsg;
    00587       return sc;
    00588     }
    00589     sc = setDataLoader(dataLoader);
    00590     dataLoader->release();
    00591     if (!sc.isSuccess()) {
    00592       log << MSG::ERROR << "Failed to set data loader "
    00593           << "\"" << m_loader << "\"" << endmsg;
    00594       return sc;
    00595     }
    00596     return sc;
    00597   }
    00598
    00599   STATUS detachServices()  {
    00600     if ( m_addrCreator )  m_addrCreator->release();
    00601     if ( m_dataLoader )  m_dataLoader->release();
    00602     m_addrCreator = 0;
    00603     m_dataLoader = 0;
    00604     return STATUS::SUCCESS;
    00605   }
    00606
    00608   virtual STATUS initialize()    {
    00609     // Nothing to do: just call base class initialisation
    00610     STATUS sc = Service::initialize();
    00611     if ( !sc.isSuccess() )  {
    00612       return sc;
    00613     }
    00614     sc = makePartitions();
    00615     if (!sc.isSuccess()) {
    00616       MsgStream log(msgSvc(), name());
    00617       log << MSG::ERROR << "Failed to connect to all store partitions." << endmsg;
    00618       return sc;
    00619     }
    00620     return attachServices();
    00621   }
    00622
    00624   virtual STATUS reinitialize()   {
    00625     STATUS sc = Service::reinitialize();
    00626     MsgStream log(msgSvc(), name());
    00627     if (!sc.isSuccess()) {
    00628       log << MSG::ERROR << "Enable to reinitialize base class"
    00629           << endmsg;
    00630       return sc;
    00631     }
    00632     detachServices();
    00633     sc = attachServices();
    00634     if ( !sc.isSuccess() )  {
    00635       log << MSG::ERROR << "Failed to attach necessary services." << endmsg;
    00636       return sc;
    00637     }
    00638     sc = makePartitions();
    00639     if (!sc.isSuccess()) {
    00640       log << MSG::ERROR << "Failed to connect to store partitions." << endmsg;
    00641       return sc;
    00642     }
    00643     // return
    00644     return STATUS::SUCCESS;
    00645   }
    00646
    00648   virtual STATUS finalize()   {
    00649     setDataLoader(0).ignore();
    00650     clearStore().ignore();
    00651     clearPartitions().ignore();
    00652     m_current = Partition();
    00653     detachServices();
    00654     return Service::finalize();
    00655   }
    00656
    00657
    00658 //protected:
    00659
    00661   MultiStoreSvc( CSTR& name, ISvcLocator* svc )
    00662   : base_class(name,svc), m_rootCLID(110), m_rootName("/Event"),
    00663     m_dataLoader(0), m_addrCreator(0)
    00664   {
    00665     m_dataLoader = 0;
    00666     declareProperty("RootCLID",         m_rootCLID);
    00667     declareProperty("RootName",         m_rootName);
    00668     declareProperty("Partitions",       m_partitionDefs);
    00669     declareProperty("DataLoader",       m_loader="EventPersistencySvc");
    00670     declareProperty("DefaultPartition", m_defaultPartition="Default");
    00671   }
    00672
    00674   virtual ~MultiStoreSvc()  {
    00675     setDataLoader(0).ignore();
    00676     resetPreLoad().ignore();
    00677     clearStore().ignore();
    00678     clearPartitions().ignore();
    00679   }
    00680
    00682   STATUS preparePartitions()  {
    00683     STATUS iret = STATUS::SUCCESS;
    00684     for(Partitions::iterator i=m_partitions.begin(); i != m_partitions.end(); ++i) {
    00685       STATUS sc = STATUS::FAILURE;
    00686       switch ( m_root.type )  {
    00687         case address_type:
    00688           if ( m_root.root.address )  {
    00689             ADDRESS* pAdd = 0;
    00690             ADDRESS* p = m_root.root.address;
    00691             sc = m_addrCreator->createAddress(p->svcType(),
    00692                                               p->clID(),
    00693                                               p->par(),
    00694                                               p->ipar(),
    00695                                               pAdd);
    00696             if ( sc.isSuccess() )  {
    00697             sc = (*i).second.dataManager->setRoot(m_root.path, pAdd);
    00698             }
    00699           }
    00700           break;
    00701         case object_type:
    00702           if ( m_root.root.object )  {
    00703             if ( m_root.root.object->clID() == CLID_DataObject )  {
    00704               DataObject* pObj = new DataObject();
    00705               sc = (*i).second.dataManager->setRoot(m_root.path, pObj);
    00706             }
    00707           }
    00708           break;
    00709         default:
    00710           sc = STATUS::FAILURE;
    00711           break;
    00712       }
    00713       if ( !sc.isSuccess() )  {
    00714         iret = sc;
    00715       }
    00716     }
    00717     return iret;
    00718   }
    00719
    00721   STATUS clearPartitions()  {
    00722     Partitions::iterator i;
    00723     for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
    00724       (*i).second.dataManager->clearStore().ignore();
    00725       (*i).second.dataProvider->release();
    00726       (*i).second.dataManager->release();
    00727     }
    00728     m_partitions.clear();
    00729     return STATUS::SUCCESS;
    00730   }
    00731
    00733   STATUS makePartitions()  {
    00734     std::string typ, nam;
    00735     PartitionDefs::iterator j;
    00736     clearPartitions().ignore();
    00737     for(j=m_partitionDefs.begin(); j != m_partitionDefs.end(); ++j)  {
    00738       Tokenizer tok(true);
    00739       Tokenizer::Items::iterator i;
    00740       tok.analyse(*j, " ", "", "", "=", "'", "'");
    00741       for(i = tok.items().begin(); i != tok.items().end(); i++ )   {
    00742         CSTR& t = (*i).tag();
    00743         CSTR& v = (*i).value();
    00744         switch( ::toupper(t[0]) )    {
    00745         case 'N':
    00746           nam = v;
    00747           break;
    00748         case 'T':
    00749           typ = v;
    00750           break;
    00751         }
    00752       }
    00753       STATUS sc = create(nam, typ);
    00754       if ( !sc.isSuccess() )  {
    00755         return sc;
    00756       }
    00757       else if ( !m_defaultPartition.length() )  {
    00758         m_defaultPartition = nam;
    00759       }
    00760     }
    00761     return STATUS::SUCCESS;
    00762   }
    00763 };
    00764
    00765 // Instantiation of a static factory class used by clients to create
    00766 // instances of this service
    00767 DECLARE_SERVICE_FACTORY(MultiStoreSvc)