| # Gaudi Framework, version v21r8 |

Home |  | Generated: 17 Mar 2010

# 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 << endmsg;
    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" << endmsg;
    00180       }
    00181     }
    00182   }
    00183   return StatusCode::SUCCESS;
    00184 }
    00185
    00187 SmartIF<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"  << endmsg;
    00202       }
    00203     }
    00204   }
    00205   return StatusCode::SUCCESS;
    00206 }
    00207
    00209 SmartIF<IAddressCreator>& ConversionSvc::addressCreator()  const   {
    00210   return m_addressCreator;
    00211 }
    00212
    00214 StatusCode ConversionSvc::setConversionSvc(IConversionSvc* /* svc */)   {
    00215   return StatusCode::FAILURE;
    00216 }
    00217
    00219 SmartIF<IConversionSvc>& ConversionSvc::conversionSvc()    const   {
    00220   return m_cnvSvc;
    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" << endmsg;
    00294     }
    00295     (*i).converter()->release();
    00296   }
    00297   m_workers->erase(m_workers->begin(), m_workers->end() );
    00298   // release interfaces
    00299   m_addressCreator = 0;
    00300   m_dataSvc = 0;
    00301   m_cnvSvc = 0;
    00302   return Service::finalize();
    00303 }
    00304
    00305
    00307 IConverter* ConversionSvc::createConverter(long typ,
    00308                                            const CLID& clid,
    00309                                            const ICnvFactory* /*fac*/)   {
    00310   IConverter* pConverter;
    00311   pConverter = PluginService::CreateWithId<IConverter*>(ConverterID(typ,clid),serviceLocator().get());
    00312   if ( 0 == pConverter )  {
    00313     typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
    00314     pConverter = PluginService::CreateWithId<IConverter*>(ConverterID(typ,clid),serviceLocator().get());
    00315   }
    00316   return pConverter;
    00317 }
    00318
    00320 StatusCode ConversionSvc::configureConverter(long /* typ */,
    00321                                               const CLID& /* clid */,
    00322                                               IConverter* pConverter)    {
    00323   if ( 0 != pConverter )    {
    00324     pConverter->setConversionSvc(this).ignore();
    00325     pConverter->setAddressCreator(m_addressCreator).ignore();
    00326     pConverter->setDataProvider(m_dataSvc).ignore();
    00327     return StatusCode::SUCCESS;
    00328   }
    00329   return NO_CONVERTER;
    00330 }
    00331
    00333 StatusCode ConversionSvc::initializeConverter(long /* typ */,
    00334                                               const CLID& /* clid */,
    00335                                               IConverter* pConverter)    {
    00336   if ( pConverter )    {
    00337     return pConverter->initialize();
    00338   }
    00339   return NO_CONVERTER;
    00340 }
    00341
    00343 StatusCode ConversionSvc::activateConverter(long /* typ */,
    00344                                             const CLID& /* clid */,
    00345                                             IConverter* pConverter)    {
    00346   if ( 0 != pConverter )    {
    00347     return StatusCode::SUCCESS;
    00348   }
    00349   return NO_CONVERTER;
    00350 }
    00351
    00353 const CLID& ConversionSvc::objType() const    {
    00354   return CLID_NULL;
    00355 }
    00356
    00358 long ConversionSvc::repSvcType() const {
    00359   return m_type;
    00360 }
    00361
    00363 StatusCode ConversionSvc::connectOutput(const std::string&    outputFile,
    00364                                         const std::string& /* openMode */) {
    00365   return connectOutput(outputFile);
    00366 }
    00367
    00369 StatusCode ConversionSvc::connectOutput(const std::string& /* outputFile */) {
    00370   return StatusCode::SUCCESS;
    00371 }
    00372
    00374 StatusCode ConversionSvc::commitOutput(const std::string& , bool ) {
    00375   return StatusCode::SUCCESS;
    00376 }
    00377
    00379 StatusCode ConversionSvc::createAddress(long                 /* svc_type */,
    00380                                         const CLID&          /* clid     */,
    00381                                         const std::string*   /* par      */,
    00382                                         const unsigned long* /* ip       */,
    00383                                         IOpaqueAddress*& refpAddress)    {
    00384   refpAddress = 0;
    00385   return StatusCode::FAILURE;
    00386 }
    00387
    00389 StatusCode ConversionSvc::convertAddress( const IOpaqueAddress* /* pAddress */,
    00390                                           std::string& refAddress)
    00391 {
    00392   refAddress = "";
    00393   return StatusCode::FAILURE;
    00394 }
    00395
    00397 StatusCode ConversionSvc::createAddress( long /* svc_type */,
    00398                                         const CLID& /* clid */,
    00399                                         const std::string& /* refAddress */,
    00400                                         IOpaqueAddress*& refpAddress)
    00401 {
    00402   refpAddress = 0;
    00403   return StatusCode::FAILURE;
    00404 }
    00405
    00407 ConversionSvc::ConversionSvc(const std::string& name, ISvcLocator* svc, long type)
    00408  : base_class(name, svc)
    00409 {
    00410   m_type            = type;
    00411   m_dataSvc         = 0;
    00412   m_cnvSvc          = this;
    00413   m_workers = new Workers();
    00414   setAddressCreator(this).ignore();
    00415 }
    00416
    00418 ConversionSvc::~ConversionSvc()   {
    00419   // Release all workers.
    00420   for ( Workers::iterator i = m_workers->begin(); i != m_workers->end(); i++ )    {
    00421     (*i).converter()->release();
    00422   }
    00423   m_workers->erase(m_workers->begin(), m_workers->end() );
    00424   delete m_workers;
    00425 }