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

ConversionSvc.cpp

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiKernel/src/Lib/ConversionSvc.cpp,v 1.1.1.1 2001/04/18 18:14:18 tlindner Exp $
00002 //====================================================================
00003 //      ConversionSvc.cpp
00004 //--------------------------------------------------------------------
00005 //
00006 //      Package    : System ( The LHCb Offline System)
00007 //
00008 //  Description: implementation of the ConversionSvc
00009 //
00010 //      Author     : M.Frank
00011 //  History    :
00012 // +---------+----------------------------------------------+---------
00013 // |    Date |                 Comment                      | Who     
00014 // +---------+----------------------------------------------+---------
00015 // | 29/10/98| Initial version                              | MF
00016 // | 29/09/99| Added access to ICnvManager for missing      | MF
00017 // |         | converters                                   | MF
00018 // +---------+----------------------------------------------+---------
00019 //
00020 //====================================================================
00021 
00022 #define  PERSISTENCYSVC_CONVERSIONSVC_CPP
00023 #include "GaudiKernel/SvcFactory.h"
00024 #include "GaudiKernel/CnvFactory.h"
00025 #include "GaudiKernel/DataObject.h"
00026 #include "GaudiKernel/AddrFactory.h"
00027 #include "GaudiKernel/GenericLink.h"
00028 #include "GaudiKernel/MsgStream.h"
00029 #include "GaudiKernel/IConverter.h"
00030 #include "GaudiKernel/ICnvManager.h"
00031 #include "GaudiKernel/IDataSelector.h"
00032 #include "GaudiKernel/IOpaqueAddress.h"
00033 #include "GaudiKernel/IDataProviderSvc.h"
00034 
00035 #include "GaudiKernel/ConversionSvc.h"
00036 
00038 StatusCode ConversionSvc::initialize()     {
00039   StatusCode status = Service::initialize();
00040   if ( status.isSuccess() )   {
00041     status = serviceLocator()->queryInterface(IID_ICnvManager, (void**)&m_cnvManager);
00042     if ( !status.isSuccess() )    {
00043       return status;
00044     }
00045   }
00046   return status;
00047 }
00048 
00050 StatusCode ConversionSvc::finalize()      {
00051   m_cnvManager = 0;
00052   return Service::finalize();
00053 }
00054 
00056 StatusCode ConversionSvc::updateServiceState(IOpaqueAddress*)    {
00057   return StatusCode::SUCCESS;
00058 }
00059 
00061 StatusCode ConversionSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject)  
00062 {
00063   const CLID&  obj_class = pAddress->clID();
00064   IConverter*  cnv       = converter(obj_class);
00065   StatusCode   status    = NO_CONVERTER;
00066   if ( 0 != cnv )   {
00067     status = updateServiceState(pAddress);
00068     if ( status.isSuccess() )  {
00069       status = cnv->createObj(pAddress, refpObject);
00070       if ( status.isSuccess() )  {
00071         status = m_dataSvc->updateRegistryEntry(pAddress, refpObject);
00072         if ( status.isSuccess() )  {
00073           status = cnv->fillObjRefs(pAddress, refpObject);
00074           if ( status.isSuccess() )  {
00075             status = m_dataSvc->updateRegistryEntry(pAddress, refpObject);
00076             return status;
00077           }
00078         }
00079       }
00080     }
00081   }
00082   refpObject = 0;
00083   // on fatal errors throw exception
00084   return status;
00085 }
00086 
00088 StatusCode ConversionSvc::updateObj(IOpaqueAddress* pAddress, DataObject* pObject)  
00089 {
00090   const CLID&  obj_class = pAddress->clID();
00091   IConverter*  cnv = converter(obj_class);
00092   StatusCode   status    = NO_CONVERTER;
00093   if ( 0 != cnv )   {
00094     status = updateServiceState(pAddress);
00095     if ( status.isSuccess() )  {
00096       status = cnv->updateObj(pAddress, pObject);
00097       if ( status.isSuccess() )  {
00098        status = cnv->updateObjRefs(pAddress, pObject);
00099         if ( status.isSuccess() )  {
00100           status = m_dataSvc->updateRegistryEntry(pAddress, pObject);
00101           return status;
00102         }
00103       }
00104     }
00105   }
00106   // on fatal errors throw exception
00107   return status;
00108 }
00109 
00111 StatusCode ConversionSvc::updateReps(IDataSelector* pSelector)  {
00112   Context::iterator       i;
00113   IDataSelector::iterator j;
00114   Context                 context;
00115   StatusCode              status = NO_CONVERTER;
00116   StatusCode              iret   = StatusCode::SUCCESS;
00117 
00118   // Create context
00119   for ( j = pSelector->begin(); j != pSelector->end(); j++ )   {
00120     IOpaqueAddress* addr = (*j)->address();
00121     if ( 0 != addr )  {
00122       unsigned char type = addr->svcType();
00123       if ( type == repSvcType() )   {            // Yes! I have to do the job!
00124         const CLID& obj_class = (*j)->clID();
00125         IConverter* cnv = converter(obj_class);
00126         // Push pointer independent of actual value!
00127         context.push_back(ContextEntry(cnv, addr, (*j)));
00128         if ( 0 == cnv )   {
00129           iret = NO_CONVERTER;
00130         }
00131       }
00132       else    {
00133         iret = BAD_STORAGE_TYPE;
00134       }
00135     }
00136   }
00137   // Update primitive representation
00138   for ( i = context.begin(); i != context.end(); i++ )   {
00139     ContextEntry& e = (*i);
00140     if ( 0 != e.converter() )  {
00141       status = e.converter()->updateRep(e.address(), e.object());
00142       if ( !status.isSuccess() )    {
00143         iret = status;
00144       }
00145     }
00146   }
00147   // Finally update local representation references which are unknown to the data model
00148   for ( i = context.begin(); i != context.end(); i++ )   {
00149     ContextEntry& e = (*i);
00150     if ( 0 != e.converter() )  {
00151       status = e.converter()->updateRepRefs(e.address(), e.object());
00152       if ( !status.isSuccess() )    {
00153         iret = status;
00154       }
00155     }
00156   }
00157   return iret;
00158 }
00159 
00161 StatusCode ConversionSvc::createReps(IDataSelector* pSelector)  {
00162   MsgStream log(msgSvc(), name());
00163   Context::iterator       i;
00164   IDataSelector::iterator j;
00165   Context                 context;
00166   StatusCode              status = NO_CONVERTER;
00167   StatusCode              iret   = StatusCode::SUCCESS;
00168   // Create context
00169   for ( j = pSelector->begin(); j != pSelector->end(); j++ )   {
00170     const CLID&    obj_class = (*j)->clID();
00171     IConverter*    cnv = converter(obj_class);
00172     if ( 0 == cnv )   {
00173       log << MSG::INFO << "no converter for object "
00174           << System::typeinfoName(typeid(**j)) << "  CLID= " << obj_class
00175           << endreq;
00176       iret = NO_CONVERTER;
00177     } else {
00178       context.push_back(ContextEntry(cnv, (*j)->address(), (*j)));
00179     }
00180   }
00181   // Update primitive representation
00182   for ( i = context.begin(); i != context.end(); i++ )   {
00183     ContextEntry& e = (*i);
00184     if ( 0 != e.converter() )  {
00185       status = e.converter()->createRep(e.object(), e.address());
00186       if ( status.isSuccess() )  {
00187         status = m_dataSvc->updateRegistryEntry(e.address(), e.object());
00188         if ( !status.isSuccess() )  {
00189           iret = status;
00190         }
00191       }
00192       else  {
00193         iret = status;
00194       }
00195     }
00196   }
00197   // Finally update local representation references which are unknown to the data model
00198   for ( i = context.begin(); i != context.end(); i++ )   {
00199     ContextEntry& e = (*i);
00200     // e.address()==0 -> representation was NOT created in the first go!
00201     if ( 0 != e.converter() && 0 != e.address() )  {
00202       status = e.converter()->fillRepRefs(e.address(), e.object());
00203       if ( !status.isSuccess() )  {
00204         iret = status;
00205       }
00206     }
00207   }
00208   return iret;
00209 }
00210 
00212 const ICnvFactory* ConversionSvc::findCnvFactory(const CLID& wanted)  {
00213   return (m_cnvManager) ? m_cnvManager->factory(m_type, wanted) : 0;
00214 }
00215 
00217 IConverter* ConversionSvc::converter(const CLID& wanted)     {
00218   IConverter* cnv = 0;
00219   Workers::iterator i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(wanted));
00220   if ( i != m_workers->end() )      {
00221       cnv = (*i).converter();
00222   }
00223   if ( 0 == cnv )     {
00224     const ICnvFactory* fac = findCnvFactory(wanted);
00225     if ( 0 != fac )   {
00226       addConverter(*fac);
00227       i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(wanted));
00228       if ( i != m_workers->end() )      {
00229           cnv = (*i).converter();
00230       }
00231     }
00232   }
00233   return cnv;
00234 }
00235 
00237 StatusCode ConversionSvc::setStore(IDataProviderSvc* pDataSvc)    {
00238   // if ( 0 != pDataSvc ) pDataSvc->addRef();     // No...cannot be
00239   // if ( 0 != m_dataSvc ) m_dataSvc->release();    // No...cannot be
00240   m_dataSvc = pDataSvc;
00241   return StatusCode::SUCCESS;
00242 }
00243 
00245 StatusCode ConversionSvc::initializeConverter(IConverter* cnv)    {
00246   if ( cnv )    {
00247     return cnv->initialize();
00248   }
00249   return StatusCode::FAILURE;
00250 }
00251 
00253 IConverter* ConversionSvc::createConverter(const ICnvFactory& fac)   {
00254   return fac.instantiate(serviceLocator());
00255 }
00256 
00258 StatusCode ConversionSvc::addConverter(IConverter* pConverter)  {
00259   const CLID& clid = pConverter->objType();
00260   removeConverter(clid);
00261   m_workers->push_back(WorkerEntry(clid, pConverter));
00262   pConverter->addRef();
00263   initializeConverter( pConverter );
00264   return StatusCode::SUCCESS;
00265 }
00266 
00268 StatusCode ConversionSvc::addConverter(const ICnvFactory& refFactory)  {
00269   IConverter* pConverter = createConverter(refFactory);
00270   unsigned char   typ    = pConverter->repSvcType();
00271   if ( typ == repSvcType() )    {
00272     return addConverter(pConverter);
00273   }
00274   pConverter->release();
00275   return StatusCode::FAILURE;
00276 }
00277 
00279 StatusCode ConversionSvc::removeConverter(const CLID& clid)  {
00280   CnvTest test(clid);
00281   Workers::iterator stop  = m_workers->end();
00282   Workers::iterator start = m_workers->begin();
00283   for(Workers::iterator i=start; i != stop; i++ )    {
00284     if ( test( *i ) )   {
00285       (*i).converter()->release();
00286     }
00287   }
00288   Workers::iterator j = std::remove_if(start, stop, test);
00289   if ( j != stop )  {
00290     m_workers->erase(j, stop);
00291     return StatusCode::SUCCESS;
00292   }
00293   return NO_CONVERTER;  
00294 }
00295 
00297 StatusCode ConversionSvc::queryInterface(const IID& riid, void** ppvInterface)  {
00298   if ( IID_IConversionSvc == riid )  {
00299     *ppvInterface = (IConversionSvc*)this;
00300   }
00301   else if ( IID_IAddressCreator == riid )  {
00302     *ppvInterface = (IAddressCreator*)this;
00303   }
00304   else  {
00305     // Interface is not directly availible: try out a base class
00306     return Service::queryInterface(riid, ppvInterface);
00307   }
00308   addRef();
00309   return StatusCode::SUCCESS;
00310 }
00311 
00313 unsigned char ConversionSvc::repSvcType() const {
00314   return m_type;
00315 }
00316 
00318 StatusCode ConversionSvc::connectOutput(const std::string&) {
00319   return StatusCode::SUCCESS;
00320 }
00321 
00323 StatusCode ConversionSvc::setAddressCreator(IAddressCreator* creator)   {
00324   m_addressCreator = creator;
00325   return StatusCode::SUCCESS;
00326 }
00327 
00329 StatusCode ConversionSvc::createAddress(unsigned char type, 
00330                                         const CLID& classId,
00331                                         const std::string& dbName, 
00332                                         const std::string& contName, 
00333                                         int seqId,
00334                                         IOpaqueAddress*& refpAddress)    {
00335   refpAddress = 0;
00336   if ( type == repSvcType() && 0 != m_addressFactory )   {
00337     refpAddress = m_addressFactory->instantiate(classId, dbName, contName, seqId);
00338     return (0==refpAddress) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00339   }
00340   return BAD_STORAGE_TYPE;
00341 }
00342 
00344 StatusCode ConversionSvc::createAddress(const GenericLinkBase& link, 
00345                                         const std::string& dbName, 
00346                                         const std::string& contName, 
00347                                         const std::string& objName, 
00348                                         IOpaqueAddress*& refpAddress)    {
00349   refpAddress = 0;
00350   if ( link.svcType() == repSvcType() && 0 != m_addressFactory )   {
00351     refpAddress = m_addressFactory->instantiate(link, dbName, contName, objName);
00352     return (0==refpAddress) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00353   }
00354   return BAD_STORAGE_TYPE;
00355 }
00356 
00358 ConversionSvc::ConversionSvc(const std::string& name, ISvcLocator* svc, unsigned char type)
00359  : Service(name, svc)
00360 {
00361   m_type            = type;
00362   m_dataSvc         = 0;
00363   m_cnvManager      = 0;
00364   m_addressFactory  = 0;
00365   m_workers = new Workers();
00366 }
00367 
00369 ConversionSvc::~ConversionSvc()   {
00370   // Release all workers.
00371   for ( Workers::iterator i = m_workers->begin(); i != m_workers->end(); i++ )    {
00372     (*i).converter()->release();
00373   }
00374   m_workers->erase(m_workers->begin(), m_workers->end() );
00375   delete m_workers;
00376 }

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