Gaudi Framework, version v20r4

Generated: 8 Jan 2009

ConversionSvc.cpp

Go to the documentation of this file.
00001 // $Id: ConversionSvc.cpp,v 1.22 2007/09/24 08:58:21 hmd Exp $
00002 #define  GAUDIKERNEL_CONVERSIONSVC_CPP
00003 
00004 #include "GaudiKernel/MsgStream.h"
00005 #include "GaudiKernel/SvcFactory.h"
00006 #include "GaudiKernel/CnvFactory.h"
00007 #include "GaudiKernel/DataObject.h"
00008 #include "GaudiKernel/System.h"
00009 #include "GaudiKernel/IConverter.h"
00010 #include "GaudiKernel/IDataProviderSvc.h"
00011 #include "GaudiKernel/IOpaqueAddress.h"
00012 #include "GaudiKernel/ConversionSvc.h"
00013 
00014 using ROOT::Reflex::PluginService;
00015 
00016 enum CnvSvcAction   {
00017   CREATE_OBJ,
00018   FILL_OBJ_REFS,
00019   UPDATE_OBJ,
00020   UPDATE_OBJ_REFS,
00021   CREATE_REP,
00022   FILL_REP_REFS,
00023   UPDATE_REP,
00024   UPDATE_REP_REFS
00025 };
00026 
00027 StatusCode ConversionSvc::makeCall(int typ,
00028                                    bool ignore_add,
00029                                    bool ignore_obj,
00030                                    bool update,
00031                                    IOpaqueAddress*& pAddress, 
00032                                    DataObject*& pObject)      {
00033   if ( 0 != pAddress || ignore_add )    {
00034     if ( 0 != pObject  || ignore_obj )    {
00035       const CLID&  obj_class =
00036         (0 != pObject && !ignore_obj) ? pObject->clID() 
00037         : (0 != pAddress && !ignore_add)
00038         ? pAddress->clID()                       
00039         : CLID_NULL;
00040       IConverter*  cnv  = converter(obj_class);
00041       if ( !cnv && pObject ) {
00042         //Give it a try to autoload the class (dictionary) for which the converter is needed
00043         loadConverter( pObject);
00044         cnv  = converter(obj_class);
00045       }
00046       
00047       StatusCode status(StatusCode::FAILURE,true);
00048       if ( 0 != cnv )   {
00049         switch(typ)   {
00050         case CREATE_OBJ:
00051           pObject = 0;
00052           status = cnv->createObj(pAddress, pObject);
00053           break;
00054         case FILL_OBJ_REFS:
00055           status = cnv->fillObjRefs(pAddress, pObject);
00056           break;
00057         case UPDATE_OBJ:
00058           status = cnv->updateObj(pAddress, pObject);
00059           break;
00060         case UPDATE_OBJ_REFS:
00061           status = cnv->updateObjRefs(pAddress, pObject);
00062           break;
00063         case CREATE_REP:
00064           pAddress = 0;
00065           status = cnv->createRep(pObject, pAddress);
00066           break;
00067         case FILL_REP_REFS:
00068           status = cnv->fillRepRefs(pAddress, pObject);
00069           break;
00070         case UPDATE_REP:
00071           status = cnv->updateRep(pAddress, pObject);
00072           break;
00073         case UPDATE_REP_REFS:
00074           status = cnv->updateRepRefs(pAddress, pObject);
00075           break;
00076         default:
00077           status = StatusCode::FAILURE;
00078           break;
00079         }
00080         if ( status.isSuccess() && update )   {
00081           status = updateServiceState(pAddress);
00082         }
00083         return status;
00084       }
00085       status.ignore();
00086       MsgStream log(msgSvc(), name());
00087       log << MSG::INFO << "No converter for object ";
00088       if ( pObject != 0 )   {
00089         log << System::typeinfoName(typeid(*pObject));
00090       }
00091       log << "  CLID= " << obj_class << endreq;
00092       return NO_CONVERTER;
00093     }
00094     return INVALID_OBJECT;
00095   }
00096   return INVALID_ADDRESS;
00097 }
00098 
00099 void ConversionSvc::loadConverter(DataObject*) {
00100   
00101 }
00102 
00103 StatusCode ConversionSvc::updateServiceState(IOpaqueAddress* /*pAddress */)   {
00104   return StatusCode::SUCCESS;
00105 }
00106 
00108 StatusCode ConversionSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObj)   {
00109   return makeCall(CREATE_OBJ, false, true, false, pAddress, refpObj);
00110 }
00111 
00113 StatusCode ConversionSvc::fillObjRefs(IOpaqueAddress* pAddress, DataObject* pObj)    {
00114   return makeCall(FILL_OBJ_REFS, false, true, true, pAddress, pObj);
00115 }
00116 
00118 StatusCode ConversionSvc::updateObj(IOpaqueAddress* pAddress, DataObject* pObj)   {
00119   return makeCall(UPDATE_OBJ, false, true, false, pAddress, pObj);
00120 }
00121 
00123 StatusCode ConversionSvc::updateObjRefs(IOpaqueAddress* pAddress, DataObject* pObj)  {
00124   return makeCall(UPDATE_OBJ_REFS, false, true, true, pAddress, pObj);
00125 }
00126 
00128 StatusCode ConversionSvc::createRep(DataObject* pObj, IOpaqueAddress*& refpAddress)  {
00129   return makeCall(CREATE_REP, true, false, false, refpAddress, pObj);
00130 }
00131 
00133 StatusCode ConversionSvc::fillRepRefs(IOpaqueAddress* pAddress, DataObject* pObj)  {
00134   return makeCall(FILL_REP_REFS, true, false, false, pAddress, pObj);
00135 }
00136 
00138 StatusCode ConversionSvc::updateRep(IOpaqueAddress* pAddress, DataObject* pObj)  {
00139   return makeCall(UPDATE_REP, true, false, false, pAddress, pObj);
00140 }
00141 
00143 StatusCode ConversionSvc::updateRepRefs(IOpaqueAddress* pAddress, DataObject* pObj)    {
00144   return makeCall(UPDATE_REP_REFS, true, false, false, pAddress, pObj);
00145 }
00146 
00148 IConverter* ConversionSvc::converter(const CLID& clid)     {
00149   IConverter* cnv = 0;
00150   Workers::iterator i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(clid));
00151   if ( i != m_workers->end() )      {
00152     cnv = (*i).converter();
00153   }
00154   if ( 0 == cnv )     {
00155     StatusCode status = addConverter(clid);
00156     if ( status.isSuccess() )   {
00157       i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(clid));
00158       if ( i != m_workers->end() )      {
00159         cnv = (*i).converter();
00160       }
00161     }
00162   }
00163   return cnv;
00164 }
00165 
00167 StatusCode ConversionSvc::setDataProvider(IDataProviderSvc* pDataSvc)    {
00168   if ( !pDataSvc ) return StatusCode::SUCCESS; //Atlas does not use DataSvc
00169   if ( m_dataSvc ) m_dataSvc->release();
00170   m_dataSvc = pDataSvc;
00171   m_dataSvc->addRef();
00172   Workers::iterator stop  = m_workers->end();
00173   Workers::iterator start = m_workers->begin();
00174   for(Workers::iterator i=start; i != stop; i++ )    {
00175     IConverter* cnv = (*i).converter();
00176     if ( 0 != cnv )   {
00177       if (cnv->setDataProvider(m_dataSvc).isFailure()) {
00178         MsgStream log(msgSvc(), name());
00179         log << MSG::ERROR << "setting Data Provider" << endreq;
00180       }
00181     }
00182   }
00183   return StatusCode::SUCCESS;
00184 }
00185 
00187 IDataProviderSvc* ConversionSvc::dataProvider()  const   {
00188   return m_dataSvc;
00189 }
00190 
00192 StatusCode ConversionSvc::setAddressCreator(IAddressCreator* creator)   {
00193   m_addressCreator = creator;
00194   Workers::iterator stop  = m_workers->end();
00195   Workers::iterator start = m_workers->begin();
00196   for(Workers::iterator i=start; i != stop; i++ )    {
00197     IConverter* cnv = (*i).converter();
00198     if ( 0 != cnv )   {
00199       if (cnv->setAddressCreator(m_addressCreator).isFailure()) {
00200         MsgStream log(msgSvc(), name());
00201         log << MSG::ERROR << "setting Address Creator"  << endreq;
00202       }
00203     }
00204   }
00205   return StatusCode::SUCCESS;
00206 }
00207 
00209 IAddressCreator* ConversionSvc::addressCreator()  const   {
00210   return m_addressCreator;
00211 }
00212 
00214 StatusCode ConversionSvc::setConversionSvc(IConversionSvc* /* svc */)   {
00215   return StatusCode::FAILURE;
00216 }
00217 
00219 IConversionSvc* ConversionSvc::conversionSvc()    const   {
00220   return (IConversionSvc*)this;
00221 }
00222 
00224 StatusCode ConversionSvc::addConverter(const CLID& clid)  {
00225   // First look for the more specific converter
00226   long typ = repSvcType();
00227   IConverter* pConverter = createConverter(typ, clid, 0);
00228   if ( 0 != pConverter )    {
00229     StatusCode status = configureConverter( typ, clid, pConverter );
00230     if ( status.isSuccess() )   {
00231       status = initializeConverter( typ, clid, pConverter );
00232       if ( status.isSuccess() )   {
00233         status = activateConverter( typ, clid, pConverter );
00234         if ( status.isSuccess() )   {
00235           long conv_typ  = pConverter->repSvcType();
00236           const CLID&   conv_clid = pConverter->objType();
00237           typ      = (typ<0xFF) ? typ : typ&0xFFFFFF00;
00238           conv_typ = (conv_typ<0xFF) ? conv_typ : conv_typ&0xFFFFFF00;
00239           if ( conv_typ == typ && conv_clid == clid )   {
00240             return addConverter(pConverter);
00241           }
00242         }
00243       }
00244     }
00245     pConverter->release();
00246   }
00247   return NO_CONVERTER;
00248 }
00249 
00251 StatusCode ConversionSvc::addConverter(IConverter* pConverter)    {
00252   if ( 0 != pConverter )    {
00253     const CLID& clid = pConverter->objType();
00254     removeConverter(clid).ignore();
00255     m_workers->push_back(WorkerEntry(clid, pConverter));
00256     pConverter->addRef();
00257     return StatusCode::SUCCESS;
00258   }
00259   return NO_CONVERTER;
00260 }
00261 
00263 StatusCode ConversionSvc::removeConverter(const CLID& clid)  {
00264   CnvTest test(clid);
00265   Workers::iterator stop  = m_workers->end();
00266   Workers::iterator start = m_workers->begin();
00267   for(Workers::iterator i=start; i != stop; i++ )    {
00268     if ( test( *i ) )   {
00269       (*i).converter()->finalize().ignore();
00270       (*i).converter()->release();
00271     }
00272   }
00273   Workers::iterator j = std::remove_if(start, stop, test);
00274   if ( j != stop )  {
00275     m_workers->erase(j, stop);
00276     return StatusCode::SUCCESS;
00277   }
00278   return NO_CONVERTER;  
00279 }
00280 
00282 StatusCode ConversionSvc::initialize()     {
00283   StatusCode status = Service::initialize();
00284   return status;
00285 }
00286 
00288 StatusCode ConversionSvc::finalize()      {
00289   // Release all workers.
00290   MsgStream log(msgSvc(), name());
00291   for ( Workers::iterator i = m_workers->begin(); i != m_workers->end(); i++ )    {
00292     if ( (*i).converter()->finalize().isFailure() ) {
00293       log << MSG::ERROR << "finalizing worker" << endreq;
00294     }
00295     (*i).converter()->release();
00296   }
00297   m_workers->erase(m_workers->begin(), m_workers->end() );
00298   if ( m_dataSvc ) m_dataSvc->release();
00299   m_dataSvc = 0;
00300   return Service::finalize();
00301 }
00302 
00303 
00305 IConverter* ConversionSvc::createConverter(long typ, 
00306                                            const CLID& clid,
00307                                            const ICnvFactory* /*fac*/)   {
00308   IConverter* pConverter;
00309   pConverter = PluginService::CreateWithId<IConverter*>(ConverterID(typ,clid),serviceLocator());
00310   if ( 0 == pConverter )  {
00311     typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
00312     pConverter = PluginService::CreateWithId<IConverter*>(ConverterID(typ,clid),serviceLocator());
00313   }
00314   return pConverter;
00315 }
00316 
00318 StatusCode ConversionSvc::configureConverter(long /* typ */, 
00319                                               const CLID& /* clid */, 
00320                                               IConverter* pConverter)    {
00321   if ( 0 != pConverter )    {
00322     pConverter->setConversionSvc(this).ignore();
00323     pConverter->setAddressCreator(m_addressCreator).ignore();
00324     pConverter->setDataProvider(m_dataSvc).ignore();
00325     return StatusCode::SUCCESS;
00326   }
00327   return NO_CONVERTER;
00328 }
00329 
00331 StatusCode ConversionSvc::initializeConverter(long /* typ */, 
00332                                               const CLID& /* clid */, 
00333                                               IConverter* pConverter)    {
00334   if ( pConverter )    {
00335     return pConverter->initialize();
00336   }
00337   return NO_CONVERTER;
00338 }
00339 
00341 StatusCode ConversionSvc::activateConverter(long /* typ */, 
00342                                             const CLID& /* clid */, 
00343                                             IConverter* pConverter)    {
00344   if ( 0 != pConverter )    {
00345     return StatusCode::SUCCESS;
00346   }
00347   return NO_CONVERTER;
00348 }
00349 
00351 const CLID& ConversionSvc::objType() const    {
00352   return CLID_NULL;
00353 }
00354 
00356 long ConversionSvc::repSvcType() const {
00357   return m_type;
00358 }
00359 
00361 StatusCode ConversionSvc::queryInterface(const InterfaceID& riid, void** ppvInterface)  {
00362   if ( IID_IConversionSvc.versionMatch(riid) )  {
00363     *ppvInterface = (IConversionSvc*)this;
00364   }
00365   else if ( IID_IConverter.versionMatch(riid) )  {
00366     *ppvInterface = (IConverter*)this;
00367   }
00368   else if ( IID_IAddressCreator.versionMatch(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 
00380 StatusCode ConversionSvc::connectOutput(const std::string&    outputFile,
00381                                         const std::string& /* openMode */) {
00382   return connectOutput(outputFile);
00383 }
00384 
00386 StatusCode ConversionSvc::connectOutput(const std::string& /* outputFile */) {
00387   return StatusCode::SUCCESS;
00388 }
00389 
00391 StatusCode ConversionSvc::commitOutput(const std::string& , bool ) {
00392   return StatusCode::SUCCESS;
00393 }
00394 
00396 StatusCode ConversionSvc::createAddress(long                 /* svc_type */,
00397                                         const CLID&          /* clid     */,
00398                                         const std::string*   /* par      */, 
00399                                         const unsigned long* /* ip       */,
00400                                         IOpaqueAddress*& refpAddress)    {
00401   refpAddress = 0;
00402   return StatusCode::FAILURE;
00403 }
00404 
00406 StatusCode ConversionSvc::convertAddress( const IOpaqueAddress* /* pAddress */,
00407                                           std::string& refAddress)
00408 {
00409   refAddress = "";
00410   return StatusCode::FAILURE;
00411 }
00412     
00414 StatusCode ConversionSvc::createAddress( long /* svc_type */, 
00415                                         const CLID& /* clid */, 
00416                                         const std::string& /* refAddress */,
00417                                         IOpaqueAddress*& refpAddress)
00418 {
00419   refpAddress = 0;
00420   return StatusCode::FAILURE;
00421 }
00422 
00424 ConversionSvc::ConversionSvc(const std::string& name, ISvcLocator* svc, long type)
00425  : Service(name, svc)
00426 {
00427   m_type            = type;
00428   m_dataSvc         = 0;
00429   m_workers = new Workers();
00430   setAddressCreator(this).ignore();
00431 }
00432 
00434 ConversionSvc::~ConversionSvc()   {
00435   // Release all workers.
00436   for ( Workers::iterator i = m_workers->begin(); i != m_workers->end(); i++ )    {
00437     (*i).converter()->release();
00438   }
00439   m_workers->erase(m_workers->begin(), m_workers->end() );
00440   delete m_workers;
00441 }

Generated at Thu Jan 8 17:44:21 2009 for Gaudi Framework, version v20r4 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004