00001
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
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* ) {
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;
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* ) {
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
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
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
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* ) {
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 ,
00321 const 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 ,
00334 const CLID& ,
00335 IConverter* pConverter) {
00336 if ( pConverter ) {
00337 return pConverter->initialize();
00338 }
00339 return NO_CONVERTER;
00340 }
00341
00343 StatusCode ConversionSvc::activateConverter(long ,
00344 const 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& ) {
00365 return connectOutput(outputFile);
00366 }
00367
00369 StatusCode ConversionSvc::connectOutput(const std::string& ) {
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 ,
00380 const CLID& ,
00381 const std::string* ,
00382 const unsigned long* ,
00383 IOpaqueAddress*& refpAddress) {
00384 refpAddress = 0;
00385 return StatusCode::FAILURE;
00386 }
00387
00389 StatusCode ConversionSvc::convertAddress( const IOpaqueAddress* ,
00390 std::string& refAddress)
00391 {
00392 refAddress = "";
00393 return StatusCode::FAILURE;
00394 }
00395
00397 StatusCode ConversionSvc::createAddress( long ,
00398 const CLID& ,
00399 const std::string& ,
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
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 }