Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

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/GenericLink.h"
00026 #include "GaudiKernel/IConverter.h"
00027 #include "GaudiKernel/ISvcLocator.h"
00028 #include "GaudiKernel/IDataSelector.h"
00029 #include "GaudiKernel/IOpaqueAddress.h"
00030 #include "GaudiKernel/IDataProviderSvc.h"
00031 #include "GaudiKernel/MsgStream.h"
00032 
00033 #ifdef WIN32
00034 #  define strncasecmp _strnicmp
00035 #else
00036 #  include <strings.h>
00037 #endif
00038 
00039 // Implementation specific definitions
00040 #include "PersistencySvc.h"
00041 
00042 // Instantiation of a static factory class used by clients to create
00043 // instances of this service
00044 static const SvcFactory<PersistencySvc> s_factory;
00045 const ISvcFactory& PersistencySvcFactory = s_factory;
00046 
00048 StatusCode PersistencySvc::initialize()     {
00049   // Initialize basic service
00050   StatusCode status = Service::initialize();
00051   MsgStream log( msgSvc(), name() ); // Service MUST be initialized BEFORE!
00052   if ( status.isFailure() )   {
00053     log << MSG::ERROR << "Error initializing Service base class." << endreq;
00054     return status;
00055   }
00056   status = setProperties();
00057   if ( status.isFailure() )   {
00058     log << MSG::ERROR << "Error retrieving properties." << endreq;
00059     return status;
00060   }
00061   // Run through the service name list and attach the appropriate services
00062   status = decodeSvcNames( );
00063   return status;
00064 }
00065 
00067 StatusCode PersistencySvc::finalize()      {
00068   m_knownSvc.erase(m_knownSvc.begin(), m_knownSvc.end());
00069   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )    {
00070     (*i).second.service()->release();
00071   }
00072   return StatusCode::SUCCESS;
00073 }
00074 
00076 StatusCode PersistencySvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject)   {
00077   unsigned char svc_type = pAddress->svcType();     // Get proper service type
00078   IConversionSvc* svc    = service(svc_type);       // Find corrponding data service
00079   StatusCode   status    = BAD_STORAGE_TYPE;        // Preset error
00080   if ( 0 != svc )   {
00081     status = svc->createObj(pAddress, refpObject);  // invoke service call
00082     return status;
00083   }
00084   refpObject = 0;                                   // Bad luck: service not availible
00085   // on fatal errors throw exception
00086   return status;
00087 }
00088 
00090 StatusCode PersistencySvc::updateObj(IOpaqueAddress* pAddress, DataObject* pObject)   {
00091   unsigned char svc_type = pAddress->svcType();     // Get proper service type
00092   IConversionSvc* svc    = service(svc_type);       // Find corrponding data service
00093   StatusCode   status    = BAD_STORAGE_TYPE;        // Preset error
00094   if ( 0 != svc )   {
00095     status = svc->updateObj(pAddress, pObject);     // invoke service call
00096     return status;
00097   }
00098   pObject = 0;                                      // Bad luck: service not availible
00099   // on fatal errors throw exception
00100   return status;
00101 }
00102 
00104 StatusCode PersistencySvc::updateReps(IDataSelector* pSelector)     {
00105   StatusCode status = SUCCESS, iret = SUCCESS;
00106   // For updating representation it is not necessary to keep the
00107   // two/three steps: The presentations are already present 
00108   // in the persistent storage.
00109   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )    {
00110     // Each service must pick out his part to be updated....
00111     iret = (*i).second.service()->updateReps(pSelector);
00112     if ( iret.isSuccess() )      {
00113       status = iret;
00114     }
00115   }
00116   return iret;
00117 }
00118 
00120 StatusCode PersistencySvc::createReps(IDataSelector* pSelector)   {
00121   StatusCode status = NO_CONVERTER;
00122   // Simply pass the seelction to the default output stream service
00123   if ( 0 != m_cnvDefault )   {
00124     status = m_cnvDefault->createReps(pSelector);
00125   }
00126   return status;
00127 }
00128 
00130 IConversionSvc* PersistencySvc::service(unsigned char type)     {
00131   Services::iterator it = m_cnvServices.find( type );
00132   if( it != m_cnvServices.end() ) {
00133     return (*it).second.service();
00134   }
00135   for ( std::vector<IConversionSvc*>::iterator ik=m_knownSvc.begin(); ik != m_knownSvc.end(); ik++ )   {
00136     IConversionSvc* cnvSvc = (*ik);
00137     unsigned char svcTyp = cnvSvc->repSvcType();
00138     if ( type == svcTyp )    {
00139       StatusCode iret = addCnvService( cnvSvc );
00140       if ( !iret.isSuccess() )   {
00141         MsgStream log( msgSvc(), name() );
00142         SmartIF<IService> sif(IID_IService, cnvSvc);
00143         if ( sif.isValid( ) )  {
00144           log << MSG::ERROR << "Cannot use Conversion service:" << sif->name() << endreq;
00145         }
00146         else  {
00147           log << MSG::ERROR << "Cannot use Conversion service: Bad interface" << endreq;
00148         }
00149       }
00150       else    {
00151         m_knownSvc.erase(ik);
00152         return cnvSvc;
00153       }
00154     }
00155   }
00156   return 0;
00157 }
00158 
00160 IAddressCreator* PersistencySvc::addressCreator(unsigned char type)     {
00161   Services::iterator it = m_cnvServices.find( type );
00162   if( it == m_cnvServices.end() ) {
00163     IConversionSvc* s = service(type);
00164     if ( s )   {
00165       it = m_cnvServices.find( type );
00166       if ( it != m_cnvServices.end() ) {
00167         return (*it).second.addrCreator();
00168       }
00169     }
00170     return 0;
00171   }
00172   return (*it).second.addrCreator();
00173 }
00174 
00176 StatusCode PersistencySvc::setStore(IDataProviderSvc* pDataSvc)    {
00177   m_dataSvc = pDataSvc;
00178   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )   {
00179     (*i).second.service()->setStore(m_dataSvc);
00180   }
00181   return StatusCode::SUCCESS;
00182 }
00183 
00185 StatusCode PersistencySvc::addConverter(IConverter* pConverter)  {
00186   unsigned char   typ    = pConverter->repSvcType();
00187   IConversionSvc* svc    = service(typ);
00188   StatusCode      status = BAD_STORAGE_TYPE;
00189   if ( 0 != svc )   {
00190     status = svc->addConverter(pConverter);
00191   }
00192   return status;
00193 }
00194 
00196 StatusCode PersistencySvc::addConverter(const ICnvFactory& refFactory)  {
00197   StatusCode      status = NO_CONVERTER;
00198   IConverter* pConverter = refFactory.instantiate(serviceLocator());
00199   if ( 0 != pConverter )    {
00200     unsigned char   typ    = pConverter->repSvcType();
00201     IConversionSvc* svc    = service(typ);
00202     status = BAD_STORAGE_TYPE;
00203     if ( 0 != svc )   {
00204       status = svc->addConverter(pConverter);
00205     }
00206   }
00207   return status;
00208 }
00209 
00211 StatusCode PersistencySvc::removeConverter(const CLID& clid)  {
00212   // Remove converter type from all services
00213   StatusCode status = NO_CONVERTER, iret = StatusCode::SUCCESS;
00214   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )    {
00215     iret = (*i).second.service()->removeConverter(clid);
00216     if ( iret.isSuccess() )    {
00217       status = iret;
00218     }
00219   }
00220   return status;
00221 }
00222 
00224 StatusCode PersistencySvc::addCnvService(IConversionSvc* servc)    {
00225   if ( 0 != servc )   {
00226     IAddressCreator* icr = 0;
00227     StatusCode status  = servc->queryInterface(IID_IAddressCreator, (void**)&icr);
00228     unsigned char type = servc->repSvcType();
00229     if ( status.isSuccess() )   {
00230       Services::iterator it = m_cnvServices.find( type );
00231       IConversionSvc* cnv_svc = 0;
00232       if ( it != m_cnvServices.end() )    {
00233         cnv_svc = (*it).second.service();
00234       }
00235       if ( cnv_svc != servc )   {
00236         if ( 0 != cnv_svc )   {
00237           removeCnvService (type);
00238         }
00239         std::pair<Services::iterator, bool> p =
00240           m_cnvServices.insert( Services::value_type( type, ServiceEntry(type, servc, icr)));
00241         if( p.second == false)    {
00242           return StatusCode::FAILURE;
00243         }
00244         servc->addRef();
00245       }
00246       if ( type == m_cnvDefType )     {
00247         m_cnvDefault = servc;
00248       }
00249       servc->setAddressCreator(this);
00250       return StatusCode::SUCCESS;
00251     }
00252   }
00253   return BAD_STORAGE_TYPE;
00254 }
00255 
00257 StatusCode PersistencySvc::removeCnvService(unsigned char svctype)    {
00258   Services::iterator it = m_cnvServices.find( svctype );
00259   if( it != m_cnvServices.end() ) {
00260     (*it).second.service()->release();
00261     m_cnvServices.erase(it);
00262     return StatusCode::SUCCESS;
00263   }
00264   return BAD_STORAGE_TYPE;
00265 }
00266 
00268 unsigned char PersistencySvc::repSvcType() const {
00269   return m_cnvDefault->repSvcType();
00270 }
00271 
00273 StatusCode PersistencySvc::setDefaultCnvService(unsigned char type)     {
00274   m_cnvDefault = service(type);
00275   return StatusCode::SUCCESS;
00276 }
00277 
00279 StatusCode PersistencySvc::connectOutput(const std::string&) {
00280   return StatusCode::SUCCESS;
00281 }
00282 
00284 StatusCode PersistencySvc::createAddress(const GenericLinkBase& link, 
00285                                         const std::string& dbName, 
00286                                         const std::string& contName, 
00287                                         const std::string& objName, 
00288                                         IOpaqueAddress*& refpAddress)    {
00289   IAddressCreator* svc = addressCreator(link.svcType());
00290   StatusCode   status  = BAD_STORAGE_TYPE;        // Preset error
00291   refpAddress = 0;
00292   if ( 0 != svc )   {
00293     status = svc->createAddress(link, dbName, contName, objName, refpAddress);
00294   }
00295   return status;
00296 }
00297 
00299 StatusCode PersistencySvc::createAddress(unsigned char type, 
00300                                          const CLID& classId,
00301                                          const std::string& dbName, 
00302                                          const std::string& contName, 
00303                                          int seqId,
00304                                          IOpaqueAddress*& refpAddress)    {
00305   IAddressCreator* svc = addressCreator(type);
00306   StatusCode   status  = BAD_STORAGE_TYPE;        // Preset error
00307   refpAddress = 0;
00308   if ( 0 != svc )   {
00309     status = svc->createAddress(type, classId, dbName, contName, seqId, refpAddress);
00310   }
00311   return status;
00312 }
00313 
00315 StatusCode PersistencySvc::setAddressCreator(IAddressCreator*)    {
00316   // The persistency service is a address creation dispatcher istelf.
00317   // The persistency service can NEVER create addresses itself.
00318   // The entry point must only be provided in order to fulfill the needs of the
00319   // implementing interfaces.
00320   return StatusCode::FAILURE;
00321 }
00322 
00324 StatusCode PersistencySvc::getService(unsigned char service_type, IConversionSvc*& refpSvc)     {
00325   refpSvc = service(service_type);
00326   return (0==refpSvc) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00327 }
00328 
00330 StatusCode PersistencySvc::getService(const std::string& service_type, IConversionSvc*& refpSvc)     {
00331   const char* imp = service_type.c_str();
00332   long len = strlen(imp);
00333   if ( ::strncasecmp(imp,"SICB", len) == 0 )
00334     return getService(SICB_StorageType, refpSvc);
00335   else if ( ::strncasecmp(imp,"ZEBRA", len) == 0 )
00336     return getService(SICB_StorageType, refpSvc);
00337   else if ( ::strncasecmp(imp,"MS Access", len) == 0 )
00338     return getService(ACCESS_StorageType, refpSvc);
00339   else if ( ::strncasecmp(imp,"Microsoft Access", strlen("Microsoft Access")) == 0 )
00340     return getService(ACCESS_StorageType, refpSvc);
00341   else if ( ::strncasecmp(imp,"SQL Server", len) == 0 )
00342     return getService(SQLSERVER_StorageType, refpSvc);
00343   else if ( ::strncasecmp(imp,"Microsoft ODBC for Oracle", len) == 0 )
00344     return getService(ORACLE_StorageType, refpSvc);
00345   else if ( ::strncasecmp(imp,"Oracle ODBC", strlen("Oracle ODBC")) == 0 )
00346     return getService(ORACLE_StorageType, refpSvc);
00347   else if ( ::strncasecmp(imp,"Oracle OCI", strlen("Oracle OCI")) == 0 )
00348     return getService(ORACLE_StorageType, refpSvc);
00349   else if ( ::strncasecmp(imp,"MySQL", len) == 0 )
00350     return getService(MYSQL_StorageType, refpSvc);
00351   else if ( ::strncasecmp(imp,"ROOT", len) == 0 )
00352     return getService(ROOT_StorageType, refpSvc);
00353   else if ( ::strncasecmp(imp,"OBJY", len) == 0 )
00354     return getService(OBJY_StorageType, refpSvc);
00355   else if ( ::strncasecmp(imp,"OBJYECTI", 7) == 0 )
00356     return getService(OBJY_StorageType, refpSvc);
00357   return StatusCode::FAILURE;
00358 }
00359 
00361 StatusCode PersistencySvc::queryInterface(const IID& riid, void** ppvInterface)  {
00362   if ( IID_IConversionSvc == riid )  {
00363     *ppvInterface = (IConversionSvc*)this;
00364   }
00365   else if ( IID_IPersistencySvc == riid )  {
00366     *ppvInterface = (IPersistencySvc*)this;
00367   }
00368   else if ( IID_IAddressCreator == riid )  {
00369     *ppvInterface = (IAddressCreator*)this;
00370   }
00371   else  {
00372     // Interface is not directly availible: try out a base class
00373     return Service::queryInterface(riid, ppvInterface);
00374   }
00375   addRef();
00376   return StatusCode::SUCCESS;
00377 }
00378 
00379 StatusCode PersistencySvc::decodeSvcNames( )
00380 {
00381   StatusCode result = StatusCode::SUCCESS;
00382   if ( state( ) == INITIALIZED ) {
00383     MsgStream log( msgSvc(), name() );
00384     const std::vector<std::string>& theNames = m_svcNames.value( );
00385     for ( std::vector<std::string>::const_iterator i = theNames.begin(); i != theNames.end(); i++ )   {
00386       IConversionSvc* svc = 0;
00387       StatusCode iret = serviceLocator()->getService(*i, IID_IConversionSvc,(IInterface*&)svc);
00388       if ( iret.isSuccess() )   {
00389         m_knownSvc.push_back(svc);
00390         log << MSG::INFO << "Added successfully Conversion service:" << *i << endreq;
00391       }
00392       else  {
00393         log << MSG::INFO << "Cannot add Conversion service:" << *i << " (Bad Interface)" << endreq;
00394       }
00395     }
00396   }
00397   return result;
00398 }
00399 
00400 void PersistencySvc::svcNamesHandler( Property& /* theProp */ )
00401 {
00402     decodeSvcNames( );
00403 }
00404 
00406 PersistencySvc::PersistencySvc(const std::string& name, ISvcLocator* svc)
00407  :  Service(name, svc), 
00408     m_cnvDefType(TEST_StorageType), 
00409     m_dataSvc(0),
00410     m_cnvDefault(0)
00411 {
00412         declareProperty("CnvServices", m_svcNames);
00413     m_svcNames.declareUpdateHandler( &PersistencySvc::svcNamesHandler, this );
00414 }
00415 
00417 PersistencySvc::~PersistencySvc()   {
00418   // Release all workers
00419   for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ )    {
00420     (*i).second.service()->release();
00421   }
00422   m_cnvServices.erase(m_cnvServices.begin(), m_cnvServices.end());
00423   m_knownSvc.erase(m_knownSvc.begin(), m_knownSvc.end());
00424 }

Generated at Wed Nov 21 12:22:30 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000