![]() |
|
|
Generated: 8 Jan 2009 |
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 }