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

# 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 }