All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ConversionSvc.cpp
Go to the documentation of this file.
1 #define GAUDIKERNEL_CONVERSIONSVC_CPP
2 
3 #include "GaudiKernel/MsgStream.h"
4 #include "GaudiKernel/DataObject.h"
5 #include "GaudiKernel/System.h"
6 #include "GaudiKernel/IConverter.h"
7 #include "GaudiKernel/IDataProviderSvc.h"
8 #include "GaudiKernel/IOpaqueAddress.h"
9 #include "GaudiKernel/ConversionSvc.h"
10 #include "GaudiKernel/Converter.h"
11 
21 };
22 
24  bool ignore_add,
25  bool ignore_obj,
26  bool update,
27  IOpaqueAddress*& pAddress,
28  DataObject*& pObject) {
29  if ( pAddress || ignore_add ) {
30  if ( pObject || ignore_obj ) {
31  const CLID& obj_class =
32  ( pObject && !ignore_obj) ? pObject->clID()
33  : ( pAddress && !ignore_add)
34  ? pAddress->clID()
35  : CLID_NULL;
36  IConverter* cnv = converter(obj_class);
37  if ( !cnv && pObject ) {
38  //Give it a try to autoload the class (dictionary) for which the converter is needed
39  loadConverter( pObject);
40  cnv = converter(obj_class);
41  }
42 
43  StatusCode status(StatusCode::FAILURE,true);
44  if ( cnv ) {
45  switch(typ) {
46  case CREATE_OBJ:
47  pObject = nullptr;
48  status = cnv->createObj(pAddress, pObject);
49  break;
50  case FILL_OBJ_REFS:
51  status = cnv->fillObjRefs(pAddress, pObject);
52  break;
53  case UPDATE_OBJ:
54  status = cnv->updateObj(pAddress, pObject);
55  break;
56  case UPDATE_OBJ_REFS:
57  status = cnv->updateObjRefs(pAddress, pObject);
58  break;
59  case CREATE_REP:
60  pAddress = nullptr;
61  status = cnv->createRep(pObject, pAddress);
62  break;
63  case FILL_REP_REFS:
64  status = cnv->fillRepRefs(pAddress, pObject);
65  break;
66  case UPDATE_REP:
67  status = cnv->updateRep(pAddress, pObject);
68  break;
69  case UPDATE_REP_REFS:
70  status = cnv->updateRepRefs(pAddress, pObject);
71  break;
72  default:
73  status = StatusCode::FAILURE;
74  break;
75  }
76  if ( status.isSuccess() && update ) {
77  status = updateServiceState(pAddress);
78  }
79  return status;
80  }
81  status.ignore();
82  MsgStream log(msgSvc(), name());
83  log << MSG::INFO << "No converter for object ";
84  if ( pObject ) {
85  log << System::typeinfoName(typeid(*pObject));
86  }
87  log << " CLID= " << obj_class << endmsg;
88  return NO_CONVERTER;
89  }
90  return INVALID_OBJECT;
91  }
92  return INVALID_ADDRESS;
93 }
94 
96 
97 }
98 
100  return StatusCode::SUCCESS;
101 }
102 
105  return makeCall(CREATE_OBJ, false, true, false, pAddress, refpObj);
106 }
107 
110  return makeCall(FILL_OBJ_REFS, false, true, true, pAddress, pObj);
111 }
112 
115  return makeCall(UPDATE_OBJ, false, true, false, pAddress, pObj);
116 }
117 
120  return makeCall(UPDATE_OBJ_REFS, false, true, true, pAddress, pObj);
121 }
122 
125  return makeCall(CREATE_REP, true, false, false, refpAddress, pObj);
126 }
127 
130  return makeCall(FILL_REP_REFS, true, false, false, pAddress, pObj);
131 }
132 
135  return makeCall(UPDATE_REP, true, false, false, pAddress, pObj);
136 }
137 
140  return makeCall(UPDATE_REP_REFS, true, false, false, pAddress, pObj);
141 }
142 
145  IConverter* cnv = nullptr;
146  auto i = std::find_if(m_workers.begin(),m_workers.end(),CnvTest(clid));
147  if ( i != m_workers.end() ) {
148  cnv = i->converter();
149  }
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() ) {
155  cnv = i->converter();
156  }
157  }
158  }
159  return cnv;
160 }
161 
164  if ( !pDataSvc ) return StatusCode::SUCCESS; //Atlas does not use DataSvc
165  m_dataSvc = pDataSvc;
166  for(auto& i : m_workers ) {
167  IConverter* cnv = i.converter();
168  if ( cnv && cnv->setDataProvider(m_dataSvc).isFailure()) {
169  MsgStream log(msgSvc(), name());
170  log << MSG::ERROR << "setting Data Provider" << endmsg;
171  }
172  }
173  return StatusCode::SUCCESS;
174 }
175 
178  return m_dataSvc;
179 }
180 
183  m_addressCreator = creator;
184  for(auto& i : m_workers ) {
185  auto* cnv = i.converter();
186  if ( cnv ) {
187  if (cnv->setAddressCreator(m_addressCreator).isFailure()) {
188  MsgStream log(msgSvc(), name());
189  log << MSG::ERROR << "setting Address Creator" << endmsg;
190  }
191  }
192  }
193  return StatusCode::SUCCESS;
194 }
195 
198  return m_addressCreator;
199 }
200 
203  return StatusCode::FAILURE;
204 }
205 
208  return m_cnvSvc;
209 }
210 
213  // First look for the more specific converter
214  long typ = repSvcType();
215  IConverter* pConverter = createConverter(typ, clid, nullptr);
216  if ( pConverter ) {
217  StatusCode status = configureConverter( typ, clid, pConverter );
218  if ( status.isSuccess() ) {
219  status = initializeConverter( typ, clid, pConverter );
220  if ( status.isSuccess() ) {
221  status = activateConverter( typ, clid, pConverter );
222  if ( status.isSuccess() ) {
223  long conv_typ = pConverter->repSvcType();
224  const CLID& conv_clid = pConverter->objType();
225  typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
226  conv_typ = (conv_typ<0xFF) ? conv_typ : conv_typ&0xFFFFFF00;
227  if ( conv_typ == typ && conv_clid == clid ) {
228  return addConverter(pConverter);
229  }
230  }
231  }
232  }
233  pConverter->release();
234  }
235  return NO_CONVERTER;
236 }
237 
240  if ( pConverter ) {
241  const CLID& clid = pConverter->objType();
242  removeConverter(clid).ignore();
243  m_workers.emplace_back(clid, pConverter);
244  pConverter->addRef();
245  return StatusCode::SUCCESS;
246  }
247  return NO_CONVERTER;
248 }
249 
252 
253  auto i = std::partition( std::begin(m_workers), std::end(m_workers),
254  std::not1( CnvTest{clid} ) );
255  if ( i == std::end(m_workers) ) return NO_CONVERTER;
256  std::for_each( i, std::end(m_workers), []( WorkerEntry& w ) {
257  w.converter()->finalize().ignore();
258  w.converter()->release();
259  });
260  m_workers.erase( i, std::end(m_workers) );
261  return StatusCode::SUCCESS;
262 }
263 
266  StatusCode status = Service::initialize();
267  return status;
268 }
269 
272  // Release all workers.
273  MsgStream log(msgSvc(), name());
274  for ( auto& i : m_workers ) {
275  if ( i.converter()->finalize().isFailure() ) {
276  log << MSG::ERROR << "finalizing worker" << endmsg;
277  }
278  i.converter()->release();
279  }
280  m_workers.clear();
281  // release interfaces
282  m_addressCreator = nullptr;
283  m_dataSvc = nullptr;
284  m_cnvSvc = nullptr;
285  return Service::finalize();
286 }
287 
288 
291  const CLID& clid,
292  const ICnvFactory* /*fac*/) {
293  IConverter* pConverter = Converter::Factory::create(ConverterID(typ,clid), serviceLocator().get());
294  if ( !pConverter ) {
295  typ = (typ<0xFF) ? typ : typ&0xFFFFFF00;
296  pConverter = Converter::Factory::create(ConverterID(typ,clid), serviceLocator().get());
297  }
298  return pConverter;
299 }
300 
303  const CLID& /* clid */,
304  IConverter* pConverter) {
305  if ( !pConverter ) return NO_CONVERTER;
306  pConverter->setConversionSvc(this).ignore();
308  pConverter->setDataProvider(m_dataSvc).ignore();
309  return StatusCode::SUCCESS;
310 }
311 
314  const CLID& /* clid */,
315  IConverter* pConverter) {
316  return pConverter ? pConverter->initialize()
317  : NO_CONVERTER;
318 }
319 
322  const CLID& /* clid */,
323  IConverter* pConverter) {
324  return pConverter ? StatusCode{StatusCode::SUCCESS}
325  : NO_CONVERTER;
326 }
327 
329 const CLID& ConversionSvc::objType() const {
330  return CLID_NULL;
331 }
332 
335  return m_type;
336 }
337 
339 StatusCode ConversionSvc::connectOutput(const std::string& outputFile,
340  const std::string& /* openMode */) {
341  return connectOutput(outputFile);
342 }
343 
345 StatusCode ConversionSvc::connectOutput(const std::string& /* outputFile */) {
346  return StatusCode::SUCCESS;
347 }
348 
350 StatusCode ConversionSvc::commitOutput(const std::string& , bool ) {
351  return StatusCode::SUCCESS;
352 }
353 
356  const CLID& /* clid */,
357  const std::string* /* par */,
358  const unsigned long* /* ip */,
359  IOpaqueAddress*& refpAddress) {
360  refpAddress = nullptr;
361  return StatusCode::FAILURE;
362 }
363 
366  std::string& refAddress)
367 {
368  refAddress.clear();
369  return StatusCode::FAILURE;
370 }
371 
374  const CLID& /* clid */,
375  const std::string& /* refAddress */,
376  IOpaqueAddress*& refpAddress)
377 {
378  refpAddress = nullptr;
379  return StatusCode::FAILURE;
380 }
381 
383 ConversionSvc::ConversionSvc(const std::string& name, ISvcLocator* svc, long type)
384  : base_class(name, svc),
385  m_cnvSvc(static_cast<IConversionSvc*>(this))
386 {
387  m_type = type;
388  m_dataSvc = nullptr;
389  setAddressCreator(this).ignore();
390 }
391 
394  // Release all workers.
395  for ( auto & i : m_workers ) i.converter()->release();
396 }
IConverter * converter()
Definition: ConversionSvc.h:65
virtual const CLID & objType() const =0
Retrieve the class type of objects the converter produces.
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)
Implementation of IConverter: Convert the transient object to the requested representation.
virtual SmartIF< IConversionSvc > & conversionSvc() const
Implementation of IConverter: Get conversion service the converter is connected to.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
virtual StatusCode configureConverter(long typ, const CLID &clid, IConverter *cnv)
Configure the new converter before initialize is called.
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)
Implementation of IConverter: Resolve the references of the created transient object.
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
virtual StatusCode commitOutput(const std::string &output, bool do_commit)
Commit pending output.
The data converters are responsible to translate data from one representation into another...
Definition: IConverter.h:57
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
const CLID & objType() const
Implementation of IConverter: dummy call.
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
StatusCode finalize() override
Definition: Service.cpp:188
virtual StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)
Implementation of IConverter: Update the references of an already converted object.
ConversionSvc(const std::string &name, ISvcLocator *svc, long type)
Standard Constructor.
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)
Implementation of IConverter: Resolve the references of the converted object.
virtual StatusCode addConverter(const CLID &clid)
Add converter object to conversion service.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:297
IAddressCreator interface definition.
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
Definition: ConversionSvc.h:49
virtual StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject)
Implementation of IConverter: Update the transient object from the other representation.
virtual StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject)
Implementation of IConverter: Update the converted representation of a transient object.
virtual StatusCode connectOutput(const std::string &outputFile, const std::string &openMode)
Connect the output file to the service with open mode.
virtual ~ConversionSvc()
Standard Destructor.
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)=0
Convert the transient object to the requested representation.
Data provider interface definition.
std::vector< WorkerEntry > m_workers
List of conversion workers.
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:86
virtual void loadConverter(DataObject *pObject)
Load converter or dictionary needed by the converter.
virtual StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject)=0
Update the transient object from the other representation.
virtual StatusCode removeConverter(const CLID &clid)
Remove converter object from conversion service (if present).
virtual StatusCode setConversionSvc(IConversionSvc *pService)=0
Set conversion service the converter is connected to.
virtual StatusCode setConversionSvc(IConversionSvc *svc)
Implementation of IConverter: Set conversion service the converter is connected to.
virtual long repSvcType() const
Retrieve the class type of the data store the converter uses.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
Definition: DataObject.cpp:68
virtual StatusCode finalize()
stop the service.
virtual const CLID & clID() const =0
Retrieve class information from link.
virtual long repSvcType() const =0
Retrieve the class type of the data store the converter uses.
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
SmartIF< IConversionSvc > m_cnvSvc
Pointer to the IConversionSvc interface of this.
virtual StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an updated transient object.
virtual StatusCode setAddressCreator(IAddressCreator *creator)
Set address creator facility.
CnvSvcAction
virtual StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the converted representation of a transient object.
virtual StatusCode convertAddress(const IOpaqueAddress *pAddress, std::string &refAddress)
Convert an address to string form.
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)
Implementation of IConverter: Create the transient representation of an object.
virtual StatusCode initialize()=0
Initialize the converter.
virtual StatusCode updateServiceState(IOpaqueAddress *pAddress)
Update state of the service.
virtual StatusCode setAddressCreator(IAddressCreator *creator)=0
Set address creator facility.
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.
def update
Definition: install.py:213
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
long m_type
Conversion service type.
SmartIF< IAddressCreator > m_addressCreator
Pointer to the address creation service interface.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
virtual StatusCode setDataProvider(IDataProviderSvc *pService)
Implementation of IConverter: Set Data provider service.
virtual IConverter * createConverter(long typ, const CLID &clid, const ICnvFactory *fac)
Create new Converter using factory.
virtual SmartIF< IAddressCreator > & addressCreator() const
Retrieve address creator facility.
virtual StatusCode initialize()
Initialize the service.
virtual StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress)
Create a Generic address using explicit arguments to identify a single object.
Opaque address interface definition.
void ignore() const
Definition: StatusCode.h:108
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
virtual IConverter * converter(const CLID &wanted)
Retrieve converter from list.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
list i
Definition: ana.py:128
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the converted object.
virtual StatusCode activateConverter(long typ, const CLID &clid, IConverter *cnv)
Activate the new converter after initialization.
SmartIF< IDataProviderSvc > m_dataSvc
Pointer to data provider service.
string type
Definition: gaudirun.py:151
virtual StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)
Implementation of IConverter: Update the references of an updated transient object.
virtual StatusCode finalize()=0
Terminate the converter.
virtual SmartIF< IDataProviderSvc > & dataProvider() const
Implementation of IConverter: Get Data provider service.