The Gaudi Framework  v28r3 (cc1cf868)
ConversionSvc.cpp
Go to the documentation of this file.
1 #define GAUDIKERNEL_CONVERSIONSVC_CPP
2 
5 #include "GaudiKernel/System.h"
10 #include "GaudiKernel/Converter.h"
11 
12 namespace {
13 
14 auto CnvTest = [](CLID clid) { return [clid](const auto& i)
15  { return i.clID() == clid; }; };
16 
18  CREATE_OBJ,
20  UPDATE_OBJ,
22  CREATE_REP,
24  UPDATE_REP,
26 };
27 
28 }
29 
31  bool ignore_add,
32  bool ignore_obj,
33  bool update,
34  IOpaqueAddress*& pAddress,
35  DataObject*& pObject) {
36  if ( !pAddress && !ignore_add ) return INVALID_ADDRESS;
37  if ( !pObject && !ignore_obj ) return INVALID_OBJECT;
38  const CLID& obj_class =
39  ( pObject && !ignore_obj) ? pObject->clID()
40  : ( pAddress && !ignore_add)
41  ? pAddress->clID()
42  : CLID_NULL;
43  IConverter* cnv = converter(obj_class);
44  if ( !cnv && pObject ) {
45  //Give it a try to autoload the class (dictionary) for which the converter is needed
46  loadConverter( pObject);
47  cnv = converter(obj_class);
48  }
49 
50  StatusCode status(StatusCode::FAILURE,true);
51  if ( cnv ) {
52  switch(typ) {
53  case CREATE_OBJ:
54  pObject = nullptr;
55  status = cnv->createObj(pAddress, pObject);
56  break;
57  case FILL_OBJ_REFS:
58  status = cnv->fillObjRefs(pAddress, pObject);
59  break;
60  case UPDATE_OBJ:
61  status = cnv->updateObj(pAddress, pObject);
62  break;
63  case UPDATE_OBJ_REFS:
64  status = cnv->updateObjRefs(pAddress, pObject);
65  break;
66  case CREATE_REP:
67  pAddress = nullptr;
68  status = cnv->createRep(pObject, pAddress);
69  break;
70  case FILL_REP_REFS:
71  status = cnv->fillRepRefs(pAddress, pObject);
72  break;
73  case UPDATE_REP:
74  status = cnv->updateRep(pAddress, pObject);
75  break;
76  case UPDATE_REP_REFS:
77  status = cnv->updateRepRefs(pAddress, pObject);
78  break;
79  default:
80  status = StatusCode::FAILURE;
81  break;
82  }
83  if ( status.isSuccess() && update ) {
84  status = updateServiceState(pAddress);
85  }
86  return status;
87  }
88  status.ignore();
89  info() << "No converter for object ";
90  if ( pObject ) {
91  msgStream() << System::typeinfoName(typeid(*pObject));
92  }
93  msgStream() << " CLID= " << obj_class << endmsg;
94  return NO_CONVERTER;
95 }
96 
98 
99 }
100 
102  return StatusCode::SUCCESS;
103 }
104 
107  return makeCall(CREATE_OBJ, false, true, false, pAddress, refpObj);
108 }
109 
112  return makeCall(FILL_OBJ_REFS, false, true, true, pAddress, pObj);
113 }
114 
117  return makeCall(UPDATE_OBJ, false, true, false, pAddress, pObj);
118 }
119 
122  return makeCall(UPDATE_OBJ_REFS, false, true, true, pAddress, pObj);
123 }
124 
127  return makeCall(CREATE_REP, true, false, false, refpAddress, pObj);
128 }
129 
132  return makeCall(FILL_REP_REFS, true, false, false, pAddress, pObj);
133 }
134 
137  return makeCall(UPDATE_REP, true, false, false, pAddress, pObj);
138 }
139 
142  return makeCall(UPDATE_REP_REFS, true, false, false, pAddress, pObj);
143 }
144 
147  IConverter* cnv = nullptr;
148  auto i = std::find_if(m_workers.begin(),m_workers.end(),CnvTest(clid));
149  if ( i != m_workers.end() ) cnv = i->converter();
150  if ( !cnv ) {
151  StatusCode status = addConverter(clid);
152  if ( status.isSuccess() ) {
153  i = std::find_if(m_workers.begin(),m_workers.end(),CnvTest(clid));
154  if ( i != m_workers.end() ) cnv = i->converter();
155  }
156  }
157  return cnv;
158 }
159 
162  if ( !pDataSvc ) return StatusCode::SUCCESS; //Atlas does not use DataSvc
163  m_dataSvc = pDataSvc;
164  for(auto& i : m_workers) {
165  IConverter* cnv = i.converter();
166  if ( cnv && cnv->setDataProvider(m_dataSvc).isFailure()) {
167  error() << "setting Data Provider" << endmsg;
168  }
169  }
170  return StatusCode::SUCCESS;
171 }
172 
175  return m_dataSvc;
176 }
177 
180  m_addressCreator = creator;
181  for (auto& i : m_workers) {
182  auto* cnv = i.converter();
183  if ( cnv ) {
184  if (cnv->setAddressCreator(m_addressCreator).isFailure()) {
185  error() << "setting Address Creator" << endmsg;
186  }
187  }
188  }
189  return StatusCode::SUCCESS;
190 }
191 
194  return m_addressCreator;
195 }
196 
199  return StatusCode::FAILURE;
200 }
201 
204  return m_cnvSvc;
205 }
206 
209  // First look for the more specific converter
210  long typ = repSvcType();
211  IConverter* pConverter = createConverter(typ, clid, nullptr);
212  if ( pConverter ) {
213  StatusCode status = configureConverter( typ, clid, pConverter );
214  if ( status.isSuccess() ) {
215  status = initializeConverter( typ, clid, pConverter );
216  if ( status.isSuccess() ) {
217  status = activateConverter( typ, clid, pConverter );
218  if ( status.isSuccess() ) {
219  long conv_typ = pConverter->repSvcType();
220  const CLID& conv_clid = pConverter->objType();
221  typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
222  conv_typ = (conv_typ<0xFF) ? conv_typ : conv_typ&0xFFFFFF00;
223  if ( conv_typ == typ && conv_clid == clid ) {
224  return addConverter(pConverter);
225  }
226  }
227  }
228  }
229  pConverter->release();
230  }
231  return NO_CONVERTER;
232 }
233 
236  if ( pConverter ) {
237  const CLID& clid = pConverter->objType();
238  removeConverter(clid).ignore();
239  m_workers.emplace_back(clid, pConverter);
240  return StatusCode::SUCCESS;
241  }
242  return NO_CONVERTER;
243 }
244 
247 
249  [f=CnvTest(clid)](const WorkerEntry& we)
250  { return !f(we); } );
251  if ( i == std::end(m_workers) ) return NO_CONVERTER;
253  w.converter()->finalize().ignore();
254  });
255  m_workers.erase( i, std::end(m_workers) );
256  return StatusCode::SUCCESS;
257 }
258 
261  return Service::initialize();
262 }
263 
266  // Release all workers.
267  for ( auto& i : m_workers ) {
268  if ( i.converter()->finalize().isFailure() ) {
269  error() << "finalizing worker" << endmsg;
270  }
271  }
272  m_workers.clear();
273  // release interfaces
274  m_addressCreator = nullptr;
275  m_dataSvc = nullptr;
276  m_cnvSvc = nullptr;
277  return Service::finalize();
278 }
279 
280 
283  const CLID& clid,
284  const ICnvFactory* /*fac*/) {
285  IConverter* pConverter = Converter::Factory::create(ConverterID(typ,clid), serviceLocator().get());
286  if ( !pConverter ) {
287  typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
288  pConverter = Converter::Factory::create(ConverterID(typ,clid), serviceLocator().get());
289  }
290  return pConverter;
291 }
292 
295  const CLID& /* clid */,
296  IConverter* pConverter) {
297  if ( !pConverter ) return NO_CONVERTER;
298  pConverter->setConversionSvc(this).ignore();
300  pConverter->setDataProvider(m_dataSvc).ignore();
301  return StatusCode::SUCCESS;
302 }
303 
306  const CLID& /* clid */,
307  IConverter* pConverter) {
308  return pConverter ? pConverter->initialize()
309  : NO_CONVERTER;
310 }
311 
314  const CLID& /* clid */,
315  IConverter* pConverter) {
316  return pConverter ? StatusCode::SUCCESS
317  : StatusCode(NO_CONVERTER);
318 }
319 
321 const CLID& ConversionSvc::objType() const {
322  return CLID_NULL;
323 }
324 
327  return m_type;
328 }
329 
332  const std::string& /* openMode */) {
333  return connectOutput(outputFile);
334 }
335 
338  return StatusCode::SUCCESS;
339 }
340 
343  return StatusCode::SUCCESS;
344 }
345 
348  const CLID& /* clid */,
349  const std::string* /* par */,
350  const unsigned long* /* ip */,
351  IOpaqueAddress*& refpAddress) {
352  refpAddress = nullptr;
353  return StatusCode::FAILURE;
354 }
355 
358  std::string& refAddress)
359 {
360  refAddress.clear();
361  return StatusCode::FAILURE;
362 }
363 
366  const CLID& /* clid */,
367  const std::string& /* refAddress */,
368  IOpaqueAddress*& refpAddress)
369 {
370  refpAddress = nullptr;
371  return StatusCode::FAILURE;
372 }
373 
376 : base_class(name, svc),
377  m_cnvSvc(this)
378 {
379  m_type = type;
380  m_dataSvc = nullptr;
381  setAddressCreator(this).ignore();
382 }
IConverter * converter()
Definition: ConversionSvc.h:77
StatusCode initialize() override
Definition: Service.cpp:64
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
virtual StatusCode configureConverter(long typ, const CLID &clid, IConverter *cnv)
Configure the new converter before initialize is called.
StatusCode makeCall(int typ, bool ignore_add, bool ignore_obj, bool update, IOpaqueAddress *&pAddress, DataObject *&pObject)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
The data converters are responsible to translate data from one representation into another...
Definition: IConverter.h:57
virtual const CLID & clID() const =0
Retrieve class information from link.
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:289
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
StatusCode finalize() override
Definition: Service.cpp:174
StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the references of an updated transient object.
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
virtual const CLID & objType() const =0
Retrieve the class type of objects the converter produces.
StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the converted representation of a transient object.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:299
ConversionSvc(const std::string &name, ISvcLocator *svc, long type)
Standard Constructor.
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:74
StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Implementation of IConverter: Convert the transient object to the requested representation.
IAddressCreator interface definition.
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
Definition: ConversionSvc.h:50
StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the references of an already converted object.
T end(T...args)
SmartIF< IAddressCreator > m_addressCreator
Pointer to the address creation service interface.
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)=0
Convert the transient object to the requested representation.
Data provider interface definition.
virtual StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an already converted object.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:84
virtual void loadConverter(DataObject *pObject)
Load converter or dictionary needed by the converter.
T partition(T...args)
virtual StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject)=0
Update the transient object from the other representation.
STL class.
virtual StatusCode setConversionSvc(IConversionSvc *pService)=0
Set conversion service the converter is connected to.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
IConverter * converter(const CLID &wanted) override
Retrieve converter from list.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
Definition: DataObject.cpp:68
StatusCode removeConverter(const CLID &clid) override
Remove converter object from conversion service (if present).
StatusCode setAddressCreator(IAddressCreator *creator) override
Set address creator facility.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
void clear(STATE_TYPE _i=std::ios_base::failbit)
Definition: MsgStream.h:222
SmartIF< IDataProviderSvc > & dataProvider() const override
Implementation of IConverter: Get Data provider service.
virtual StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an updated transient object.
StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Resolve the references of the converted object.
CnvSvcAction
virtual StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the converted representation of a transient object.
StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
Create a Generic address using explicit arguments to identify a single object.
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
T clear(T...args)
virtual StatusCode initialize()=0
Initialize the converter.
StatusCode convertAddress(const IOpaqueAddress *pAddress, std::string &refAddress) override
Convert an address to string form.
virtual StatusCode updateServiceState(IOpaqueAddress *pAddress)
Update state of the service.
SmartIF< IDataProviderSvc > m_dataSvc
Pointer to data provider service.
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Implementation of IConverter: Create the transient representation of an object.
virtual StatusCode setAddressCreator(IAddressCreator *creator)=0
Set address creator facility.
StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Resolve the references of the created transient object.
T find_if(T...args)
virtual StatusCode initializeConverter(long typ, const CLID &clid, IConverter *cnv)
Initialize the new converter.
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the created transient object.
virtual unsigned long release()=0
Release Interface instance.
virtual long repSvcType() const =0
Retrieve the class type of the data store the converter uses.
T begin(T...args)
SmartIF< IConversionSvc > m_cnvSvc
Pointer to the IConversionSvc interface of this.
StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject) override
Implementation of IConverter: Update the transient object from the other representation.
StatusCode setDataProvider(IDataProviderSvc *pService) override
Implementation of IConverter: Set Data provider service.
long m_type
Conversion service type.
MsgStream & msgStream() const
Return an uninitialized MsgStream.
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
StatusCode commitOutput(const std::string &output, bool do_commit) override
Commit pending output.
virtual IConverter * createConverter(long typ, const CLID &clid, const ICnvFactory *fac)
Create new Converter using factory.
Opaque address interface definition.
void ignore() const
Definition: StatusCode.h:106
StatusCode addConverter(const CLID &clid) override
Add converter object to conversion service.
T for_each(T...args)
std::vector< WorkerEntry > m_workers
List of conversion workers.
StatusCode setConversionSvc(IConversionSvc *svc) override
Implementation of IConverter: Set conversion service the converter is connected to.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
StatusCode finalize() override
stop the service.
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the converted object.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:292
virtual StatusCode activateConverter(long typ, const CLID &clid, IConverter *cnv)
Activate the new converter after initialization.
const CLID & objType() const override
Implementation of IConverter: dummy call.
StatusCode initialize() override
Initialize the service.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
virtual StatusCode finalize()=0
Terminate the converter.
SmartIF< IConversionSvc > & conversionSvc() const override
Implementation of IConverter: Get conversion service the converter is connected to.