| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ConversionSvc.cpp
Go to the documentation of this file.
1 #define GAUDIKERNEL_CONVERSIONSVC_CPP
2
3 #include "GaudiKernel/MsgStream.h"
4 #include "GaudiKernel/CnvFactory.h"
5 #include "GaudiKernel/DataObject.h"
6 #include "GaudiKernel/System.h"
7 #include "GaudiKernel/IConverter.h"
8 #include "GaudiKernel/IDataProviderSvc.h"
9 #include "GaudiKernel/IOpaqueAddress.h"
10 #include "GaudiKernel/ConversionSvc.h"
11 #include "GaudiKernel/Converter.h"
12
13 enum CnvSvcAction {
14 CREATE_OBJ,
15 FILL_OBJ_REFS,
16 UPDATE_OBJ,
17 UPDATE_OBJ_REFS,
18 CREATE_REP,
19 FILL_REP_REFS,
20 UPDATE_REP,
21 UPDATE_REP_REFS
22 };
23
24 StatusCode ConversionSvc::makeCall(int typ,
25 bool ignore_add,
26 bool ignore_obj,
27 bool update,
28 IOpaqueAddress*& pAddress,
29 DataObject*& pObject) {
30 if ( 0 != pAddress || ignore_add ) {
31 if ( 0 != pObject || ignore_obj ) {
32 const CLID& obj_class =
33 (0 != pObject && !ignore_obj) ? pObject->clID()
34 : (0 != pAddress && !ignore_add)
35 ? pAddress->clID()
36 : CLID_NULL;
37 IConverter* cnv = converter(obj_class);
38 if ( !cnv && pObject ) {
39 //Give it a try to autoload the class (dictionary) for which the converter is needed
40 loadConverter( pObject);
41 cnv = converter(obj_class);
42 }
43
44 StatusCode status(StatusCode::FAILURE,true);
45 if ( 0 != cnv ) {
46 switch(typ) {
47 case CREATE_OBJ:
48 pObject = 0;
49 status = cnv->createObj(pAddress, pObject);
50 break;
51 case FILL_OBJ_REFS:
52 status = cnv->fillObjRefs(pAddress, pObject);
53 break;
54 case UPDATE_OBJ:
55 status = cnv->updateObj(pAddress, pObject);
56 break;
57 case UPDATE_OBJ_REFS:
58 status = cnv->updateObjRefs(pAddress, pObject);
59 break;
60 case CREATE_REP:
61 pAddress = 0;
62 status = cnv->createRep(pObject, pAddress);
63 break;
64 case FILL_REP_REFS:
65 status = cnv->fillRepRefs(pAddress, pObject);
66 break;
67 case UPDATE_REP:
68 status = cnv->updateRep(pAddress, pObject);
69 break;
70 case UPDATE_REP_REFS:
71 status = cnv->updateRepRefs(pAddress, pObject);
72 break;
73 default:
74 status = StatusCode::FAILURE;
75 break;
76 }
77 if ( status.isSuccess() && update ) {
78 status = updateServiceState(pAddress);
79 }
80 return status;
81 }
82 status.ignore();
83 MsgStream log(msgSvc(), name());
84 log << MSG::INFO << "No converter for object ";
85 if ( pObject != 0 ) {
86 log << System::typeinfoName(typeid(*pObject));
87 }
88 log << " CLID= " << obj_class << endmsg;
89 return NO_CONVERTER;
90 }
91 return INVALID_OBJECT;
92 }
93 return INVALID_ADDRESS;
94 }
95
96 void ConversionSvc::loadConverter(DataObject*) {
97
98 }
99
100 StatusCode ConversionSvc::updateServiceState(IOpaqueAddress* /*pAddress */) {
101 return StatusCode::SUCCESS;
102 }
103
105 StatusCode ConversionSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObj) {
106 return makeCall(CREATE_OBJ, false, true, false, pAddress, refpObj);
107 }
108
110 StatusCode ConversionSvc::fillObjRefs(IOpaqueAddress* pAddress, DataObject* pObj) {
111 return makeCall(FILL_OBJ_REFS, false, true, true, pAddress, pObj);
112 }
113
115 StatusCode ConversionSvc::updateObj(IOpaqueAddress* pAddress, DataObject* pObj) {
116 return makeCall(UPDATE_OBJ, false, true, false, pAddress, pObj);
117 }
118
120 StatusCode ConversionSvc::updateObjRefs(IOpaqueAddress* pAddress, DataObject* pObj) {
121 return makeCall(UPDATE_OBJ_REFS, false, true, true, pAddress, pObj);
122 }
123
125 StatusCode ConversionSvc::createRep(DataObject* pObj, IOpaqueAddress*& refpAddress) {
126 return makeCall(CREATE_REP, true, false, false, refpAddress, pObj);
127 }
128
130 StatusCode ConversionSvc::fillRepRefs(IOpaqueAddress* pAddress, DataObject* pObj) {
131 return makeCall(FILL_REP_REFS, true, false, false, pAddress, pObj);
132 }
133
135 StatusCode ConversionSvc::updateRep(IOpaqueAddress* pAddress, DataObject* pObj) {
136 return makeCall(UPDATE_REP, true, false, false, pAddress, pObj);
137 }
138
140 StatusCode ConversionSvc::updateRepRefs(IOpaqueAddress* pAddress, DataObject* pObj) {
141 return makeCall(UPDATE_REP_REFS, true, false, false, pAddress, pObj);
142 }
143
145 IConverter* ConversionSvc::converter(const CLID& clid) {
146 IConverter* cnv = 0;
147 Workers::iterator i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(clid));
148 if ( i != m_workers->end() ) {
149 cnv = (*i).converter();
150 }
151 if ( 0 == cnv ) {
152 StatusCode status = addConverter(clid);
153 if ( status.isSuccess() ) {
154 i = std::find_if(m_workers->begin(),m_workers->end(),CnvTest(clid));
155 if ( i != m_workers->end() ) {
156 cnv = (*i).converter();
157 }
158 }
159 }
160 return cnv;
161 }
162
164 StatusCode ConversionSvc::setDataProvider(IDataProviderSvc* pDataSvc) {
165 if ( !pDataSvc ) return StatusCode::SUCCESS; //Atlas does not use DataSvc
166 if ( m_dataSvc ) m_dataSvc->release();
167 m_dataSvc = pDataSvc;
168 m_dataSvc->addRef();
169 Workers::iterator stop = m_workers->end();
170 Workers::iterator start = m_workers->begin();
171 for(Workers::iterator i=start; i != stop; i++ ) {
172 IConverter* cnv = (*i).converter();
173 if ( 0 != cnv ) {
174 if (cnv->setDataProvider(m_dataSvc).isFailure()) {
175 MsgStream log(msgSvc(), name());
176 log << MSG::ERROR << "setting Data Provider" << endmsg;
177 }
178 }
179 }
180 return StatusCode::SUCCESS;
181 }
182
184 SmartIF<IDataProviderSvc>& ConversionSvc::dataProvider() const {
185 return m_dataSvc;
186 }
187
189 StatusCode ConversionSvc::setAddressCreator(IAddressCreator* creator) {
190 m_addressCreator = creator;
191 Workers::iterator stop = m_workers->end();
192 Workers::iterator start = m_workers->begin();
193 for(Workers::iterator i=start; i != stop; i++ ) {
194 IConverter* cnv = (*i).converter();
195 if ( 0 != cnv ) {
196 if (cnv->setAddressCreator(m_addressCreator).isFailure()) {
197 MsgStream log(msgSvc(), name());
198 log << MSG::ERROR << "setting Address Creator" << endmsg;
199 }
200 }
201 }
202 return StatusCode::SUCCESS;
203 }
204
206 SmartIF<IAddressCreator>& ConversionSvc::addressCreator() const {
207 return m_addressCreator;
208 }
209
211 StatusCode ConversionSvc::setConversionSvc(IConversionSvc* /* svc */) {
212 return StatusCode::FAILURE;
213 }
214
216 SmartIF<IConversionSvc>& ConversionSvc::conversionSvc() const {
217 return m_cnvSvc;
218 }
219
221 StatusCode ConversionSvc::addConverter(const CLID& clid) {
222 // First look for the more specific converter
223 long typ = repSvcType();
224 IConverter* pConverter = createConverter(typ, clid, 0);
225 if ( 0 != pConverter ) {
226 StatusCode status = configureConverter( typ, clid, pConverter );
227 if ( status.isSuccess() ) {
228 status = initializeConverter( typ, clid, pConverter );
229 if ( status.isSuccess() ) {
230 status = activateConverter( typ, clid, pConverter );
231 if ( status.isSuccess() ) {
232 long conv_typ = pConverter->repSvcType();
233 const CLID& conv_clid = pConverter->objType();
234 typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
235 conv_typ = (conv_typ<0xFF) ? conv_typ : conv_typ&0xFFFFFF00;
236 if ( conv_typ == typ && conv_clid == clid ) {
237 return addConverter(pConverter);
238 }
239 }
240 }
241 }
242 pConverter->release();
243 }
244 return NO_CONVERTER;
245 }
246
248 StatusCode ConversionSvc::addConverter(IConverter* pConverter) {
249 if ( 0 != pConverter ) {
250 const CLID& clid = pConverter->objType();
251 removeConverter(clid).ignore();
252 m_workers->push_back(WorkerEntry(clid, pConverter));
253 pConverter->addRef();
254 return StatusCode::SUCCESS;
255 }
256 return NO_CONVERTER;
257 }
258
260 StatusCode ConversionSvc::removeConverter(const CLID& clid) {
261 CnvTest test(clid);
262 Workers::iterator stop = m_workers->end();
263 Workers::iterator start = m_workers->begin();
264 for(Workers::iterator i=start; i != stop; i++ ) {
265 if ( test( *i ) ) {
266 (*i).converter()->finalize().ignore();
267 (*i).converter()->release();
268 }
269 }
270 Workers::iterator j = std::remove_if(start, stop, test);
271 if ( j != stop ) {
272 m_workers->erase(j, stop);
273 return StatusCode::SUCCESS;
274 }
275 return NO_CONVERTER;
276 }
277
279 StatusCode ConversionSvc::initialize() {
280 StatusCode status = Service::initialize();
281 return status;
282 }
283
285 StatusCode ConversionSvc::finalize() {
286 // Release all workers.
287 MsgStream log(msgSvc(), name());
288 for ( Workers::iterator i = m_workers->begin(); i != m_workers->end(); i++ ) {
289 if ( (*i).converter()->finalize().isFailure() ) {
290 log << MSG::ERROR << "finalizing worker" << endmsg;
291 }
292 (*i).converter()->release();
293 }
294 m_workers->erase(m_workers->begin(), m_workers->end() );
295 // release interfaces
296 m_addressCreator = 0;
297 m_dataSvc = 0;
298 m_cnvSvc = 0;
299 return Service::finalize();
300 }
301
302
304 IConverter* ConversionSvc::createConverter(long typ,
305 const CLID& clid,
306 const ICnvFactory* /*fac*/) {
307 IConverter* pConverter;
308 pConverter = Converter::Factory::create(ConverterID(typ,clid), serviceLocator().get());
309 if ( 0 == pConverter ) {
310 typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
311 pConverter = Converter::Factory::create(ConverterID(typ,clid), serviceLocator().get());
312 }
313 return pConverter;
314 }
315
317 StatusCode ConversionSvc::configureConverter(long /* typ */,
318 const CLID& /* clid */,
319 IConverter* pConverter) {
320 if ( 0 != pConverter ) {
321 pConverter->setConversionSvc(this).ignore();
322 pConverter->setAddressCreator(m_addressCreator).ignore();
323 pConverter->setDataProvider(m_dataSvc).ignore();
324 return StatusCode::SUCCESS;
325 }
326 return NO_CONVERTER;
327 }
328
330 StatusCode ConversionSvc::initializeConverter(long /* typ */,
331 const CLID& /* clid */,
332 IConverter* pConverter) {
333 if ( pConverter ) {
334 return pConverter->initialize();
335 }
336 return NO_CONVERTER;
337 }
338
340 StatusCode ConversionSvc::activateConverter(long /* typ */,
341 const CLID& /* clid */,
342 IConverter* pConverter) {
343 if ( 0 != pConverter ) {
344 return StatusCode::SUCCESS;
345 }
346 return NO_CONVERTER;
347 }
348
350 const CLID& ConversionSvc::objType() const {
351 return CLID_NULL;
352 }
353
355 long ConversionSvc::repSvcType() const {
356 return m_type;
357 }
358
360 StatusCode ConversionSvc::connectOutput(const std::string& outputFile,
361 const std::string& /* openMode */) {
362 return connectOutput(outputFile);
363 }
364
366 StatusCode ConversionSvc::connectOutput(const std::string& /* outputFile */) {
367 return StatusCode::SUCCESS;
368 }
369
371 StatusCode ConversionSvc::commitOutput(const std::string& , bool ) {
372 return StatusCode::SUCCESS;
373 }
374
376 StatusCode ConversionSvc::createAddress(long /* svc_type */,
377 const CLID& /* clid */,
378 const std::string* /* par */,
379 const unsigned long* /* ip */,
380 IOpaqueAddress*& refpAddress) {
381 refpAddress = 0;
382 return StatusCode::FAILURE;
383 }
384
386 StatusCode ConversionSvc::convertAddress( const IOpaqueAddress* /* pAddress */,
387 std::string& refAddress)
388 {
389 refAddress = "";
390 return StatusCode::FAILURE;
391 }
392
394 StatusCode ConversionSvc::createAddress( long /* svc_type */,
395 const CLID& /* clid */,
396 const std::string& /* refAddress */,
397 IOpaqueAddress*& refpAddress)
398 {
399 refpAddress = 0;
400 return StatusCode::FAILURE;
401 }
402
404 ConversionSvc::ConversionSvc(const std::string& name, ISvcLocator* svc, long type)
405 : base_class(name, svc),
406 m_cnvSvc(static_cast<IConversionSvc*>(this))
407 {
408 m_type = type;
409 m_dataSvc = 0;
410 m_workers = new Workers();
411 setAddressCreator(this).ignore();
412 }
413
415 ConversionSvc::~ConversionSvc() {
416 // Release all workers.
417 for ( Workers::iterator i = m_workers->begin(); i != m_workers->end(); i++ ) {
418 (*i).converter()->release();
419 }
420 m_workers->erase(m_workers->begin(), m_workers->end() );
421 delete m_workers;
422 }