| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# PersistencySvc.cpp

Go to the documentation of this file.

    00001 //====================================================================
    00002 //  PersistencySvc.cpp
    00003 //--------------------------------------------------------------------
    00004 //
    00005 //  Package    : System ( The LHCb Offline System)
    00006 //
    00007 //  Description: implementation of the PersistencySvc
    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  PERSISTENCYSVC_PERSISTENCYSVC_CPP
    00019
    00020 // Interface defintions
    00021 #include "GaudiKernel/SmartIF.h"
    00022 #include "GaudiKernel/SvcFactory.h"
    00023 #include "GaudiKernel/CnvFactory.h"
    00024 #include "GaudiKernel/DataObject.h"
    00025 #include "GaudiKernel/IConverter.h"
    00026 #include "GaudiKernel/ISvcLocator.h"
    00027 #include "GaudiKernel/IDataSelector.h"
    00028 #include "GaudiKernel/IOpaqueAddress.h"
    00029 #include "GaudiKernel/MsgStream.h"
    00030 #include "GaudiKernel/strcasecmp.h"
    00031 #include "GaudiKernel/ListItem.h"
    00032
    00033 // Implementation specific definitions
    00034 #include "PersistencySvc.h"
    00035
    00036 // Instantiation of a static factory class used by clients to create
    00037 // instances of this service
    00038 DECLARE_SERVICE_FACTORY(PersistencySvc)
    00039
    00040 enum CnvSvcAction   {
    00041   CREATE_OBJ,
    00042   FILL_OBJ_REFS,
    00043   UPDATE_OBJ,
    00044   UPDATE_OBJ_REFS,
    00045   CREATE_REP,
    00046   FILL_REP_REFS,
    00047   UPDATE_REP,
    00048   UPDATE_REP_REFS
    00049 };
    00050
    00051 StatusCode PersistencySvc::makeCall(int typ,
    00052                                     IOpaqueAddress*& pAddress,
    00053                                     DataObject*& pObject)      {
    00054   if ( m_enable )    {
    00055     IConversionSvc* svc    = 0;
    00056     switch(typ)   {
    00057     case CREATE_REP:
    00058     case FILL_REP_REFS:
    00059     case UPDATE_REP:
    00060     case UPDATE_REP_REFS:
    00061       svc = m_cnvDefault;
    00062       break;
    00063     default:
    00064       if ( 0 != pAddress )    {
    00065         long svc_type = pAddress->svcType();
    00066         svc = service(svc_type);
    00067         if ( 0 == svc )   {
    00068           return BAD_STORAGE_TYPE;
    00069         }
    00070       }
    00071       else  {
    00072         return INVALID_ADDRESS;
    00073       }
    00074       break;
    00075     }
    00076
    00077     StatusCode status(StatusCode::FAILURE,true);
    00078     switch( typ )     {
    00079     case CREATE_OBJ:
    00080       pObject = 0;
    00081       status = svc->createObj(pAddress, pObject);
    00082       break;
    00083     case FILL_OBJ_REFS:
    00084       status = svc->fillObjRefs(pAddress, pObject);
    00085       break;
    00086     case UPDATE_OBJ:
    00087       status = svc->updateObj(pAddress, pObject);
    00088       break;
    00089     case UPDATE_OBJ_REFS:
    00090       status = svc->updateObjRefs(pAddress, pObject);
    00091       break;
    00092     case CREATE_REP:
    00093       status = svc->createRep(pObject, pAddress);
    00094       break;
    00095     case FILL_REP_REFS:
    00096       status = svc->fillRepRefs(pAddress, pObject);
    00097       break;
    00098     case UPDATE_REP:
    00099       status = svc->updateRep(pAddress, pObject);
    00100       break;
    00101     case UPDATE_REP_REFS:
    00102       status = svc->updateRepRefs(pAddress, pObject);
    00103       break;
    00104     default:
    00105       status = StatusCode::FAILURE;
    00106       break;
    00107     }
    00108     status.ignore();
    00109     return status;
    00110   }
    00111   return StatusCode::SUCCESS;
    00112 }
    00113
    00115 StatusCode PersistencySvc::createObj(IOpaqueAddress* pAddr, DataObject*& refpObj)   {
    00116   return makeCall(CREATE_OBJ, pAddr, refpObj);
    00117 }
    00118
    00120 StatusCode PersistencySvc::fillObjRefs(IOpaqueAddress* pAddr, DataObject* pObj)    {
    00121   return makeCall(FILL_OBJ_REFS, pAddr, pObj);
    00122 }
    00123
    00125 StatusCode PersistencySvc::updateObj(IOpaqueAddress* pAddr, DataObject* pObj)   {
    00126   return makeCall(UPDATE_OBJ, pAddr, pObj);
    00127 }
    00128
    00130 StatusCode PersistencySvc::updateObjRefs(IOpaqueAddress* pAddr, DataObject* pObj)  {
    00131   return makeCall(UPDATE_OBJ_REFS, pAddr, pObj);
    00132 }
    00133
    00135 StatusCode PersistencySvc::createRep(DataObject* pObj, IOpaqueAddress*& refpAddr)  {
    00136   return makeCall(CREATE_REP, refpAddr, pObj);
    00137 }
    00138
    00140 StatusCode PersistencySvc::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj)  {
    00141   return makeCall(FILL_REP_REFS, pAddr, pObj);
    00142 }
    00143
    00145 StatusCode PersistencySvc::updateRep(IOpaqueAddress* pAddr, DataObject* pObj)  {
    00146   return makeCall(UPDATE_REP, pAddr, pObj);
    00147 }
    00148
    00150 StatusCode PersistencySvc::updateRepRefs(IOpaqueAddress* pAddr, DataObject* pObj)    {
    00151   return makeCall(UPDATE_REP_REFS, pAddr, pObj);
    00152 }
    00153
    00155 IAddressCreator* PersistencySvc::addressCreator(long type)     {
    00156   long typ = type;
    00157   Services::iterator it = m_cnvServices.find( typ );
    00158   if( it == m_cnvServices.end() ) {
    00159     IConversionSvc* s = service(type);
    00160     if ( s )   {
    00161       it = m_cnvServices.find( typ );
    00162       if ( it != m_cnvServices.end() ) {
    00163         return (*it).second.addrCreator();
    00164       }
    00165     }
    00166     return 0;
    00167   }
    00168   return (*it).second.addrCreator();
    00169 }
    00170
    00172 StatusCode PersistencySvc::setDataProvider(IDataProviderSvc* pDataSvc)    {
    00173   m_dataSvc = pDataSvc;
    00174   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )   {
    00175     (*i).second.conversionSvc()->setDataProvider(m_dataSvc).ignore();
    00176   }
    00177   return StatusCode(StatusCode::SUCCESS,true);
    00178 }
    00179
    00181 IDataProviderSvc* PersistencySvc::dataProvider()  const  {
    00182   return m_dataSvc;
    00183 }
    00184
    00186 StatusCode PersistencySvc::setConversionSvc(IConversionSvc* svc)   {
    00187   m_cnvDefault = svc;
    00188   return StatusCode(StatusCode::SUCCESS,true);
    00189 }
    00190
    00192 IConversionSvc* PersistencySvc::conversionSvc()    const   {
    00193   return m_cnvDefault;
    00194 }
    00195
    00197 StatusCode PersistencySvc::addConverter(const CLID& /* clid */)  {
    00198   return StatusCode::FAILURE;
    00199 }
    00200
    00202 StatusCode PersistencySvc::addConverter(IConverter* pConverter)    {
    00203   if ( 0 != pConverter )    {
    00204     long typ  = pConverter->repSvcType();
    00205     IConversionSvc* svc = service(typ);
    00206     if ( 0 != svc )   {
    00207       return svc->addConverter(pConverter);
    00208     }
    00209     return BAD_STORAGE_TYPE;
    00210   }
    00211   return NO_CONVERTER;
    00212 }
    00213
    00215 StatusCode PersistencySvc::removeConverter(const CLID& clid)  {
    00216   // Remove converter type from all services
    00217   StatusCode status = NO_CONVERTER, iret = StatusCode::SUCCESS;
    00218   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )    {
    00219     iret = (*i).second.conversionSvc()->removeConverter(clid);
    00220     if ( iret.isSuccess() )    {
    00221       status = iret;
    00222     }
    00223   }
    00224   return status;
    00225 }
    00226
    00228 IConverter* PersistencySvc::converter(const CLID& /*clid*/) {
    00229   return 0;
    00230 }
    00231
    00233 IConversionSvc* PersistencySvc::service(const std::string& nam)     {
    00234   IConversionSvc* svc = 0;
    00235   for ( Services::iterator it = m_cnvServices.begin(); it != m_cnvServices.end(); it++ )    {
    00236     if ( (*it).second.service()->name() == nam )   {
    00237       return (*it).second.conversionSvc();
    00238     }
    00239   }
    00240   StatusCode status = Service::service(nam, svc, true);
    00241   if ( status.isSuccess() )   {
    00242     if ( addCnvService(svc).isSuccess() )   {
    00243       svc->release();       // Do not double-reference count
    00244       return svc;
    00245     }
    00246   }
    00247   MsgStream log( msgSvc(), name() );
    00248   log << MSG::INFO << "Cannot access Conversion service:" << nam << endreq;
    00249   return 0;
    00250 }
    00251
    00253 IConversionSvc* PersistencySvc::service(long type)     {
    00254   typedef std::vector<std::string> SvcNames;
    00255   // Check wether this is already an active service
    00256   Services::iterator it = m_cnvServices.find( type );
    00257   if( it != m_cnvServices.end() ) {
    00258     return (*it).second.conversionSvc();
    00259   }
    00260   // if not, check if the service is in the list and may be requested
    00261   const SvcNames& theNames = m_svcNames.value();
    00262   for ( SvcNames::const_iterator i = theNames.begin(); i != theNames.end(); i++ )   {
    00263     IConversionSvc* svc = service(*i);
    00264     if ( svc != 0 )  {
    00265       long typ = svc->repSvcType();
    00266       if ( typ == type )    {
    00267         return svc;
    00268       }
    00269     }
    00270   }
    00271   return 0;
    00272 }
    00273
    00275 StatusCode PersistencySvc::addCnvService(IConversionSvc* servc)    {
    00276   if ( 0 != servc )   {
    00277     long type = servc->repSvcType();
    00278     long def_typ = (m_cnvDefault) ? m_cnvDefault->repSvcType() : 0;
    00279     Services::iterator it = m_cnvServices.find( type );
    00280     IConversionSvc* cnv_svc = 0;
    00281     if ( it != m_cnvServices.end() )    {
    00282       cnv_svc = (*it).second.conversionSvc();
    00283     }
    00284     if ( type == def_typ )     {
    00285       m_cnvDefault = servc;
    00286     }
    00287     if ( cnv_svc != servc )   {
    00288       MsgStream log( msgSvc(), name() );
    00289       IAddressCreator* icr = 0;
    00290       StatusCode status  = servc->queryInterface(IID_IAddressCreator, pp_cast<void>(&icr));
    00291       if ( status.isSuccess() )   {
    00292         IService* isvc = 0;
    00293         status = servc->queryInterface(IID_IService, pp_cast<void>(&isvc));
    00294         if ( status.isSuccess() )    {
    00295           if ( 0 != cnv_svc )   {
    00296             removeCnvService (type).ignore();
    00297           }
    00298           std::pair<Services::iterator, bool> p =
    00299             m_cnvServices.insert( Services::value_type( type, ServiceEntry(type, isvc, servc, icr)));
    00300           if( p.second )    {
    00301             log << MSG::INFO << "Added successfully Conversion service:" << isvc->name() << endreq;
    00302             servc->addRef();
    00303             servc->setAddressCreator(this).ignore();
    00304             servc->setDataProvider(m_dataSvc).ignore();
    00305             return StatusCode::SUCCESS;
    00306           }
    00307           log << MSG::INFO << "Cannot add Conversion service of type " << isvc->name() << endreq;
    00308           isvc->release();
    00309           icr->release();
    00310           return StatusCode::FAILURE;
    00311         }
    00312         icr->release();
    00313       }
    00314       log << MSG::INFO << "Cannot add Conversion service of type " << type << endreq;
    00315       return StatusCode::FAILURE;
    00316     }
    00317     else    {
    00318       return StatusCode::SUCCESS;
    00319     }
    00320   }
    00321   return BAD_STORAGE_TYPE;
    00322 }
    00323
    00325 StatusCode PersistencySvc::removeCnvService(long svctype)    {
    00326   Services::iterator it = m_cnvServices.find( svctype );
    00327   if( it != m_cnvServices.end() ) {
    00328     (*it).second.service()->release();
    00329     (*it).second.addrCreator()->release();
    00330     m_cnvServices.erase(it);
    00331     return StatusCode::SUCCESS;
    00332   }
    00333   return BAD_STORAGE_TYPE;
    00334 }
    00335
    00337 long PersistencySvc::repSvcType() const {
    00338   long typ = (m_cnvDefault) ? m_cnvDefault->repSvcType() : 0;
    00339   return typ;
    00340 }
    00341
    00343 StatusCode PersistencySvc::setDefaultCnvService(long type)     {
    00344   m_cnvDefault = service(type);
    00345   return StatusCode::SUCCESS;
    00346 }
    00347
    00349 StatusCode PersistencySvc::connectOutput(const std::string&    outputFile,
    00350                                          const std::string& /* openMode */) {
    00351   return connectOutput(outputFile);
    00352 }
    00353
    00355 StatusCode PersistencySvc::connectOutput(const std::string&) {
    00356   return StatusCode::SUCCESS;
    00357 }
    00358
    00360 StatusCode PersistencySvc::commitOutput(const std::string& , bool ) {
    00361   return StatusCode::SUCCESS;
    00362 }
    00363
    00365 StatusCode PersistencySvc::createAddress(long svc_type,
    00366                                          const CLID& clid,
    00367                                          const std::string* pars,
    00368                                          const unsigned long* ipars,
    00369                                          IOpaqueAddress*& refpAddress)    {
    00370   IAddressCreator* svc = addressCreator(svc_type);
    00371   StatusCode   status  = BAD_STORAGE_TYPE;        // Preset error
    00372   refpAddress = 0;
    00373   if ( 0 != svc )   {
    00374     status = svc->createAddress(svc_type, clid, pars, ipars, refpAddress);
    00375   }
    00376   return status;
    00377 }
    00378
    00380 StatusCode PersistencySvc::convertAddress( const IOpaqueAddress* pAddress,
    00381                                            std::string& refAddress)
    00382 {
    00383   // Assumuption is that the Persistency service prepends a header
    00384   // and requests the conversion service refered to by the service
    00385   // type to encode the rest
    00386   long svc_type = 0;
    00387   CLID clid = 0;
    00388   if ( 0 != pAddress ) {
    00389     svc_type = pAddress->svcType();
    00390     clid     = pAddress->clID();
    00391   }
    00392   IAddressCreator* svc = addressCreator(svc_type);
    00393   StatusCode   status  = BAD_STORAGE_TYPE;        // Preset error
    00394   refAddress = "";
    00395
    00396   if ( 0 != svc )   {
    00397     // Found service, set header
    00398     encodeAddrHdr(svc_type, clid, refAddress);
    00399     std::string address;
    00400     // Get rest of address from conversion service
    00401     status = svc->convertAddress(pAddress, address);
    00402     refAddress += address;
    00403   }
    00404   return status;
    00405 }
    00406
    00408 StatusCode PersistencySvc::createAddress( long /* svc_type */,
    00409                                          const CLID& /* clid */,
    00410                                          const std::string& refAddress,
    00411                                          IOpaqueAddress*& refpAddress)
    00412 {
    00413   // Assumuption is that the Persistency service decodes that header
    00414   // and requests the conversion service refered to by the service
    00415   // type to decode the rest
    00416   long new_svc_type = 0;
    00417   CLID new_clid = 0;
    00418   std::string address_trailer;
    00419   decodeAddrHdr(refAddress, new_svc_type, new_clid, address_trailer);
    00420   IAddressCreator* svc = addressCreator(new_svc_type);
    00421   StatusCode   status  = BAD_STORAGE_TYPE;        // Preset error
    00422   if ( 0 != svc )   {
    00423     status = svc->createAddress( new_svc_type, new_clid, address_trailer, refpAddress);
    00424   }
    00425   return status;
    00426 }
    00427
    00429 void PersistencySvc::encodeAddrHdr( long service_type,
    00430                                     const CLID& clid,
    00431                                     std::string& address) const
    00432 {
    00433   // For address header, use xml-style format of
    00434   // <addrhdr service_type="xxx" clid="yyy" />
    00435   std::stringstream stream;
    00436   int svctyp = service_type; // must put int into stream, not char
    00437   stream << "<address_header service_type=\"" << svctyp << "\" clid=\"" << clid << "\" /> ";
    00438   address = stream.str();
    00439 }
    00440
    00442 void PersistencySvc::decodeAddrHdr( const std::string& address,
    00443                                     long& service_type,
    00444                                     CLID& clid,
    00445                                     std::string& address_trailer) const
    00446 {
    00447   // For address header, use xml-style format of
    00448   // <addrhdr service_type="xxx" clid="yyy" />
    00449   service_type = 0;
    00450   clid = 0;
    00451   address_trailer = "";
    00452
    00453   // Check for addrhdr tag
    00454   size_t pos = address.find("<address_header");
    00455   if (std::string::npos != pos) {
    00456     // Get service_type
    00457     pos = address.find("service_type=\"");
    00458     if (std::string::npos != pos) {
    00459       pos += 14;
    00460       size_t end = address.find('\"', pos);
    00461         if (std::string::npos != end) {
    00462           std::string str;
    00463           str.insert(0, address, pos, end-pos);
    00464           int temp;
    00465           sscanf(str.c_str(),"%d",&temp);
    00466           service_type = temp;
    00467           // Get clid
    00468           pos = address.find("clid=\"");
    00469         if (std::string::npos != pos) {
    00470           pos += 6;
    00471           size_t end = address.find('\"', pos);
    00472           if (std::string::npos != end) {
    00473             std::string str1;
    00474             str1.insert(0, address, pos, end-pos);
    00475             sscanf(str1.c_str(),"%d",&temp);
    00476             clid = temp;
    00477             // Get trailer_address
    00478             pos = address.find(">");
    00479             if (std::string::npos != pos) {
    00480               pos += 1;
    00481               address_trailer.insert(0, address, pos, address.size() - pos);
    00482             }
    00483           }
    00484         }
    00485       }
    00486     }
    00487   }
    00488 }
    00489
    00491 StatusCode PersistencySvc::setAddressCreator(IAddressCreator*)    {
    00492   // The persistency service is a address creation dispatcher istelf.
    00493   // The persistency service can NEVER create addresses itself.
    00494   // The entry point must only be provided in order to fulfill the needs of the
    00495   // implementing interfaces.
    00496   return StatusCode::FAILURE;
    00497 }
    00498
    00500 IAddressCreator* PersistencySvc::addressCreator()   const   {
    00501   return (IAddressCreator*)this;
    00502 }
    00503
    00505 StatusCode PersistencySvc::getService(long service_type, IConversionSvc*& refpSvc)     {
    00506   refpSvc = service(service_type);
    00507   return (0==refpSvc) ? StatusCode::FAILURE : StatusCode::SUCCESS;
    00508 }
    00509
    00511 StatusCode PersistencySvc::getService(const std::string& service_type, IConversionSvc*& refpSvc)     {
    00512   const char* imp = service_type.c_str();
    00513   long len = service_type.length();
    00514   if ( ::strncasecmp(imp,"SICB", len) == 0 )
    00515     return getService(SICB_StorageType, refpSvc);
    00516   else if ( ::strncasecmp(imp,"ZEBRA", len) == 0 )
    00517     return getService(SICB_StorageType, refpSvc);
    00518   else if ( ::strncasecmp(imp,"MS Access", len) == 0 )
    00519     return getService(ACCESS_StorageType, refpSvc);
    00520   else if ( ::strncasecmp(imp,"Microsoft Access", strlen("Microsoft Access")) == 0 )
    00521     return getService(ACCESS_StorageType, refpSvc);
    00522   else if ( ::strncasecmp(imp,"SQL Server", len) == 0 )
    00523     return getService(SQLSERVER_StorageType, refpSvc);
    00524   else if ( ::strncasecmp(imp,"Microsoft ODBC for Oracle", len) == 0 )
    00525     return getService(ORACLE_StorageType, refpSvc);
    00526   else if ( ::strncasecmp(imp,"Oracle ODBC", strlen("Oracle ODBC")) == 0 )
    00527     return getService(ORACLE_StorageType, refpSvc);
    00528   else if ( ::strncasecmp(imp,"Oracle OCI", strlen("Oracle OCI")) == 0 )
    00529     return getService(ORACLE_StorageType, refpSvc);
    00530   else if ( ::strncasecmp(imp,"MySQL", len) == 0 )
    00531     return getService(MYSQL_StorageType, refpSvc);
    00532   else if ( ::strncasecmp(imp,"ROOT", len) == 0 )
    00533     return getService(ROOT_StorageType, refpSvc);
    00534   else if ( ::strncasecmp(imp,"OBJY", len) == 0 )
    00535     return getService(OBJY_StorageType, refpSvc);
    00536   else if ( ::strncasecmp(imp,"OBJYECTI", 7) == 0 )
    00537     return getService(OBJY_StorageType, refpSvc);
    00538   else if ( ::strncasecmp(imp,"POOL_ROOTKEY", 12) == 0 )
    00539     return getService(POOL_ROOTKEY_StorageType, refpSvc);
    00540   else if ( ::strncasecmp(imp,"POOL_ROOTTREE", 12) == 0 )
    00541     return getService(POOL_ROOTTREE_StorageType, refpSvc);
    00542   else if ( ::strncasecmp(imp,"POOL_ROOT", 9) == 0 )
    00543     return getService(POOL_ROOT_StorageType, refpSvc);
    00544   else if ( ::strncasecmp(imp,"POOL_MySQL", 8) == 0 )
    00545     return getService(POOL_MYSQL_StorageType, refpSvc);
    00546   else if ( ::strncasecmp(imp,"POOL_ORACLE", 8) == 0 )
    00547     return getService(POOL_ORACLE_StorageType, refpSvc);
    00548   else if ( ::strncasecmp(imp,"POOL_ACCESS", 8) == 0 )
    00549     return getService(POOL_ACCESS_StorageType, refpSvc);
    00550   else if ( ::strncasecmp(imp,"POOL", 4) == 0 )
    00551     return getService(POOL_StorageType, refpSvc);
    00552
    00553   for(Services::const_iterator i=m_cnvServices.begin(); i != m_cnvServices.end();++i)  {
    00554     SmartIF<IService> svc((*i).second.conversionSvc());
    00555     if ( svc )  {
    00556       // Check wether this is already an active service: first check by service name
    00557       if ( svc->name() == service_type )  {
    00558         refpSvc = (*i).second.conversionSvc();
    00559         return StatusCode::SUCCESS;
    00560       }
    00561       // Check wether this is already an active service: now check by service type
    00562       if ( System::typeinfoName(typeid(*(svc.get()))) == service_type )  {
    00563         refpSvc = (*i).second.conversionSvc();
    00564         return StatusCode::SUCCESS;
    00565       }
    00566     }
    00567   }
    00568   const std::vector<std::string>& names = m_svcNames;
    00569   // if not, check if the service is in the list and may be requested
    00570   for(std::vector<std::string>::const_iterator i=names.begin(); i != names.end(); i++) {
    00571     ListItem itm(*i);
    00572     if ( itm.name() == service_type || itm.type() == service_type )  {
    00573       IConversionSvc* svc = service(*i);
    00574       if ( svc )  {
    00575         refpSvc = svc;
    00576         return StatusCode::SUCCESS;
    00577       }
    00578     }
    00579   }
    00580   return StatusCode::FAILURE;
    00581 }
    00582
    00584 const CLID& PersistencySvc::objType() const    {
    00585   return CLID_NULL;
    00586 }
    00587
    00589 StatusCode PersistencySvc::initialize()     {
    00590   // Initialize basic service
    00591   StatusCode status = Service::initialize();
    00592   if ( !status.isSuccess() )   {
    00593     MsgStream log( msgSvc(), name() ); // Service MUST be initialized BEFORE!
    00594     log << MSG::ERROR << "Error initializing Service base class." << endreq;
    00595   }
    00596   return status;
    00597 }
    00598
    00600 StatusCode PersistencySvc::finalize()      {
    00601   // Release all workers
    00602   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )    {
    00603     (*i).second.service()->release();
    00604     (*i).second.conversionSvc()->release();
    00605     (*i).second.addrCreator()->release();
    00606   }
    00607   m_cnvServices.erase(m_cnvServices.begin(), m_cnvServices.end());
    00608   return StatusCode::SUCCESS;
    00609 }
    00610
    00612 StatusCode PersistencySvc::queryInterface(const InterfaceID& riid, void** ppvInterface)  {
    00613   if ( IID_IConverter == riid )  {
    00614     *ppvInterface = (IConverter*)this;
    00615   }
    00616   else if ( IID_IConversionSvc == riid )  {
    00617     *ppvInterface = (IConversionSvc*)this;
    00618   }
    00619   else if ( IID_IPersistencySvc == riid )  {
    00620     *ppvInterface = (IPersistencySvc*)this;
    00621   }
    00622   else if ( IID_IAddressCreator == riid )  {
    00623     *ppvInterface = (IAddressCreator*)this;
    00624   }
    00625   else  {
    00626     // Interface is not directly availible: try out a base class
    00627     return Service::queryInterface(riid, ppvInterface);
    00628   }
    00629   addRef();
    00630   return StatusCode::SUCCESS;
    00631 }
    00632
    00633 void PersistencySvc::svcNamesHandler( Property& p )     {
    00634   MsgStream log( msgSvc(), name() );
    00635   log << MSG::INFO << p << endreq ;
    00636 }
    00637
    00639 bool PersistencySvc::enable(bool value)
    00640 {
    00641   bool old = m_enable;
    00642   m_enable = value;
    00643   return old;
    00644 }
    00645
    00647 PersistencySvc::PersistencySvc(const std::string& name, ISvcLocator* svc)
    00648 :  Service(name, svc),
    00649    m_cnvDefType(TEST_StorageType),
    00650    m_dataSvc(0),
    00651    m_cnvDefault(0),
    00652    m_enable(true)
    00653 {
    00654   declareProperty("CnvServices", m_svcNames);
    00655   m_svcNames.declareUpdateHandler( &PersistencySvc::svcNamesHandler, this );
    00656 }
    00657
    00659 PersistencySvc::~PersistencySvc()   {
    00660 }