00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #define PERSISTENCYSVC_CONVERSIONSVC_CPP
00023 #include "GaudiKernel/SvcFactory.h"
00024 #include "GaudiKernel/CnvFactory.h"
00025 #include "GaudiKernel/DataObject.h"
00026 #include "GaudiKernel/AddrFactory.h"
00027 #include "GaudiKernel/GenericLink.h"
00028 #include "GaudiKernel/MsgStream.h"
00029 #include "GaudiKernel/IConverter.h"
00030 #include "GaudiKernel/ICnvManager.h"
00031 #include "GaudiKernel/IDataSelector.h"
00032 #include "GaudiKernel/IOpaqueAddress.h"
00033 #include "GaudiKernel/IDataProviderSvc.h"
00034
00035 #include "GaudiKernel/ConversionSvc.h"
00036
00038 StatusCode ConversionSvc::initialize() {
00039 StatusCode status = Service::initialize();
00040 if ( status.isSuccess() ) {
00041 status = serviceLocator()->queryInterface(IID_ICnvManager, (void**)&m_cnvManager);
00042 if ( !status.isSuccess() ) {
00043 return status;
00044 }
00045 }
00046 return status;
00047 }
00048
00050 StatusCode ConversionSvc::finalize() {
00051 m_cnvManager = 0;
00052 return Service::finalize();
00053 }
00054
00056 StatusCode ConversionSvc::updateServiceState(IOpaqueAddress*) {
00057 return StatusCode::SUCCESS;
00058 }
00059
00061 StatusCode ConversionSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject)
00062 {
00063 const CLID& obj_class = pAddress->clID();
00064 IConverter* cnv = converter(obj_class);
00065 StatusCode status = NO_CONVERTER;
00066 if ( 0 != cnv ) {
00067 status = updateServiceState(pAddress);
00068 if ( status.isSuccess() ) {
00069 status = cnv->createObj(pAddress, refpObject);
00070 if ( status.isSuccess() ) {
00071 status = m_dataSvc->updateRegistryEntry(pAddress, refpObject);
00072 if ( status.isSuccess() ) {
00073 status = cnv->fillObjRefs(pAddress, refpObject);
00074 if ( status.isSuccess() ) {
00075 status = m_dataSvc->updateRegistryEntry(pAddress, refpObject);
00076 return status;
00077 }
00078 }
00079 }
00080 }
00081 }
00082 refpObject = 0;
00083
00084 return status;
00085 }
00086
00088 StatusCode ConversionSvc::updateObj(IOpaqueAddress* pAddress, DataObject* pObject)
00089 {
00090 const CLID& obj_class = pAddress->clID();
00091 IConverter* cnv = converter(obj_class);
00092 StatusCode status = NO_CONVERTER;
00093 if ( 0 != cnv ) {
00094 status = updateServiceState(pAddress);
00095 if ( status.isSuccess() ) {
00096 status = cnv->updateObj(pAddress, pObject);
00097 if ( status.isSuccess() ) {
00098 status = cnv->updateObjRefs(pAddress, pObject);
00099 if ( status.isSuccess() ) {
00100 status = m_dataSvc->updateRegistryEntry(pAddress, pObject);
00101 return status;
00102 }
00103 }
00104 }
00105 }
00106
00107 return status;
00108 }
00109
00111 StatusCode ConversionSvc::updateReps(IDataSelector* pSelector) {
00112 Context::iterator i;
00113 IDataSelector::iterator j;
00114 Context context;
00115 StatusCode status = NO_CONVERTER;
00116 StatusCode iret = StatusCode::SUCCESS;
00117
00118
00119 for ( j = pSelector->begin(); j != pSelector->end(); j++ ) {
00120 IOpaqueAddress* addr = (*j)->address();
00121 if ( 0 != addr ) {
00122 unsigned char type = addr->svcType();
00123 if ( type == repSvcType() ) {
00124 const CLID& obj_class = (*j)->clID();
00125 IConverter* cnv = converter(obj_class);
00126
00127 context.push_back(ContextEntry(cnv, addr, (*j)));
00128 if ( 0 == cnv ) {
00129 iret = NO_CONVERTER;
00130 }
00131 }
00132 else {
00133 iret = BAD_STORAGE_TYPE;
00134 }
00135 }
00136 }
00137
00138 for ( i = context.begin(); i != context.end(); i++ ) {
00139 ContextEntry& e = (*i);
00140 if ( 0 != e.converter() ) {
00141 status = e.converter()->updateRep(e.address(), e.object());
00142 if ( !status.isSuccess() ) {
00143 iret = status;
00144 }
00145 }
00146 }
00147
00148 for ( i = context.begin(); i != context.end(); i++ ) {
00149 ContextEntry& e = (*i);
00150 if ( 0 != e.converter() ) {
00151 status = e.converter()->updateRepRefs(e.address(), e.object());
00152 if ( !status.isSuccess() ) {
00153 iret = status;
00154 }
00155 }
00156 }
00157 return iret;
00158 }
00159
00161 StatusCode ConversionSvc::createReps(IDataSelector* pSelector) {
00162 MsgStream log(msgSvc(), name());
00163 Context::iterator i;
00164 IDataSelector::iterator j;
00165 Context context;
00166 StatusCode status = NO_CONVERTER;
00167 StatusCode iret = StatusCode::SUCCESS;
00168
00169 for ( j = pSelector->begin(); j != pSelector->end(); j++ ) {
00170 const CLID& obj_class = (*j)->clID();
00171 IConverter* cnv = converter(obj_class);
00172 if ( 0 == cnv ) {
00173 log << MSG::INFO << "no converter for object "
00174 << System::typeinfoName(typeid(**j)) << " CLID= " << obj_class
00175 << endreq;
00176 iret = NO_CONVERTER;
00177 } else {
00178 context.push_back(ContextEntry(cnv, (*j)->address(), (*j)));
00179 }
00180 }
00181
00182 for ( i = context.begin(); i != context.end(); i++ ) {
00183 ContextEntry& e = (*i);
00184 if ( 0 != e.converter() ) {
00185 status = e.converter()->createRep(e.object(), e.address());
00186 if ( status.isSuccess() ) {
00187 status = m_dataSvc->updateRegistryEntry(e.address(), e.object());
00188 if ( !status.isSuccess() ) {
00189 iret = status;
00190 }
00191 }
00192 else {
00193 iret = status;
00194 }
00195 }
00196 }
00197
00198 for ( i = context.begin(); i != context.end(); i++ ) {
00199 ContextEntry& e = (*i);
00200
00201 if ( 0 != e.converter() && 0 != e.address() ) {
00202 status = e.converter()->fillRepRefs(e.address(), e.object());
00203 if ( !status.isSuccess() ) {
00204 iret = status;
00205 }
00206 }
00207 }
00208 return iret;
00209 }
00210
00212 const ICnvFactory* ConversionSvc::findCnvFactory(const CLID& wanted) {
00213 return (m_cnvManager) ? m_cnvManager->factory(m_type, wanted) : 0;
00214 }
00215
00217 IConverter* ConversionSvc::converter(const CLID& wanted) {
00218 IConverter* cnv = 0;
00219 Workers::iterator i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(wanted));
00220 if ( i != m_workers->end() ) {
00221 cnv = (*i).converter();
00222 }
00223 if ( 0 == cnv ) {
00224 const ICnvFactory* fac = findCnvFactory(wanted);
00225 if ( 0 != fac ) {
00226 addConverter(*fac);
00227 i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(wanted));
00228 if ( i != m_workers->end() ) {
00229 cnv = (*i).converter();
00230 }
00231 }
00232 }
00233 return cnv;
00234 }
00235
00237 StatusCode ConversionSvc::setStore(IDataProviderSvc* pDataSvc) {
00238
00239
00240 m_dataSvc = pDataSvc;
00241 return StatusCode::SUCCESS;
00242 }
00243
00245 StatusCode ConversionSvc::initializeConverter(IConverter* cnv) {
00246 if ( cnv ) {
00247 return cnv->initialize();
00248 }
00249 return StatusCode::FAILURE;
00250 }
00251
00253 IConverter* ConversionSvc::createConverter(const ICnvFactory& fac) {
00254 return fac.instantiate(serviceLocator());
00255 }
00256
00258 StatusCode ConversionSvc::addConverter(IConverter* pConverter) {
00259 const CLID& clid = pConverter->objType();
00260 removeConverter(clid);
00261 m_workers->push_back(WorkerEntry(clid, pConverter));
00262 pConverter->addRef();
00263 initializeConverter( pConverter );
00264 return StatusCode::SUCCESS;
00265 }
00266
00268 StatusCode ConversionSvc::addConverter(const ICnvFactory& refFactory) {
00269 IConverter* pConverter = createConverter(refFactory);
00270 unsigned char typ = pConverter->repSvcType();
00271 if ( typ == repSvcType() ) {
00272 return addConverter(pConverter);
00273 }
00274 pConverter->release();
00275 return StatusCode::FAILURE;
00276 }
00277
00279 StatusCode ConversionSvc::removeConverter(const CLID& clid) {
00280 CnvTest test(clid);
00281 Workers::iterator stop = m_workers->end();
00282 Workers::iterator start = m_workers->begin();
00283 for(Workers::iterator i=start; i != stop; i++ ) {
00284 if ( test( *i ) ) {
00285 (*i).converter()->release();
00286 }
00287 }
00288 Workers::iterator j = std::remove_if(start, stop, test);
00289 if ( j != stop ) {
00290 m_workers->erase(j, stop);
00291 return StatusCode::SUCCESS;
00292 }
00293 return NO_CONVERTER;
00294 }
00295
00297 StatusCode ConversionSvc::queryInterface(const IID& riid, void** ppvInterface) {
00298 if ( IID_IConversionSvc == riid ) {
00299 *ppvInterface = (IConversionSvc*)this;
00300 }
00301 else if ( IID_IAddressCreator == riid ) {
00302 *ppvInterface = (IAddressCreator*)this;
00303 }
00304 else {
00305
00306 return Service::queryInterface(riid, ppvInterface);
00307 }
00308 addRef();
00309 return StatusCode::SUCCESS;
00310 }
00311
00313 unsigned char ConversionSvc::repSvcType() const {
00314 return m_type;
00315 }
00316
00318 StatusCode ConversionSvc::connectOutput(const std::string&) {
00319 return StatusCode::SUCCESS;
00320 }
00321
00323 StatusCode ConversionSvc::setAddressCreator(IAddressCreator* creator) {
00324 m_addressCreator = creator;
00325 return StatusCode::SUCCESS;
00326 }
00327
00329 StatusCode ConversionSvc::createAddress(unsigned char type,
00330 const CLID& classId,
00331 const std::string& dbName,
00332 const std::string& contName,
00333 int seqId,
00334 IOpaqueAddress*& refpAddress) {
00335 refpAddress = 0;
00336 if ( type == repSvcType() && 0 != m_addressFactory ) {
00337 refpAddress = m_addressFactory->instantiate(classId, dbName, contName, seqId);
00338 return (0==refpAddress) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00339 }
00340 return BAD_STORAGE_TYPE;
00341 }
00342
00344 StatusCode ConversionSvc::createAddress(const GenericLinkBase& link,
00345 const std::string& dbName,
00346 const std::string& contName,
00347 const std::string& objName,
00348 IOpaqueAddress*& refpAddress) {
00349 refpAddress = 0;
00350 if ( link.svcType() == repSvcType() && 0 != m_addressFactory ) {
00351 refpAddress = m_addressFactory->instantiate(link, dbName, contName, objName);
00352 return (0==refpAddress) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00353 }
00354 return BAD_STORAGE_TYPE;
00355 }
00356
00358 ConversionSvc::ConversionSvc(const std::string& name, ISvcLocator* svc, unsigned char type)
00359 : Service(name, svc)
00360 {
00361 m_type = type;
00362 m_dataSvc = 0;
00363 m_cnvManager = 0;
00364 m_addressFactory = 0;
00365 m_workers = new Workers();
00366 }
00367
00369 ConversionSvc::~ConversionSvc() {
00370
00371 for ( Workers::iterator i = m_workers->begin(); i != m_workers->end(); i++ ) {
00372 (*i).converter()->release();
00373 }
00374 m_workers->erase(m_workers->begin(), m_workers->end() );
00375 delete m_workers;
00376 }