Gaudi Framework, version v21r6

Home   Generated: 11 Nov 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 << 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 }

Generated at Wed Nov 11 16:23:05 2009 for Gaudi Framework, version v21r6 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004