The Gaudi Framework  master (37c0b60a)
ConversionSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #define GAUDIKERNEL_CONVERSIONSVC_CPP
12 
14 #include <GaudiKernel/Converter.h>
15 #include <GaudiKernel/DataObject.h>
16 #include <GaudiKernel/IConverter.h>
19 #include <GaudiKernel/MsgStream.h>
20 #include <GaudiKernel/System.h>
21 
22 namespace {
23 
24  auto CnvTest = []( CLID clid ) { return [clid]( const auto& i ) { return i.clID() == clid; }; };
25 
26  enum CnvSvcAction {
27  CREATE_OBJ,
29  UPDATE_OBJ,
31  CREATE_REP,
33  UPDATE_REP,
35  };
36 } // namespace
37 
38 StatusCode ConversionSvc::makeCall( int typ, bool ignore_add, bool ignore_obj, bool update, IOpaqueAddress*& pAddress,
39  DataObject*& pObject ) {
40  if ( !pAddress && !ignore_add ) return Status::INVALID_ADDRESS;
41  if ( !pObject && !ignore_obj ) return Status::INVALID_OBJECT;
42  const CLID& obj_class = ( pObject && !ignore_obj ) ? pObject->clID()
43  : ( pAddress && !ignore_add ) ? pAddress->clID()
44  : CLID_NULL;
45  IConverter* cnv = converter( obj_class );
46  if ( !cnv && pObject ) {
47  // Give it a try to autoload the class (dictionary) for which the converter is needed
48  loadConverter( pObject );
49  cnv = converter( obj_class );
50  }
51 
53  if ( cnv ) {
54  switch ( typ ) {
55  case CREATE_OBJ:
56  pObject = nullptr;
57  status = cnv->createObj( pAddress, pObject );
58  break;
59  case FILL_OBJ_REFS:
60  status = cnv->fillObjRefs( pAddress, pObject );
61  break;
62  case UPDATE_OBJ:
63  status = cnv->updateObj( pAddress, pObject );
64  break;
65  case UPDATE_OBJ_REFS:
66  status = cnv->updateObjRefs( pAddress, pObject );
67  break;
68  case CREATE_REP:
69  pAddress = nullptr;
70  status = cnv->createRep( pObject, pAddress );
71  break;
72  case FILL_REP_REFS:
73  status = cnv->fillRepRefs( pAddress, pObject );
74  break;
75  case UPDATE_REP:
76  status = cnv->updateRep( pAddress, pObject );
77  break;
78  case UPDATE_REP_REFS:
79  status = cnv->updateRepRefs( pAddress, pObject );
80  break;
81  default:
82  status = StatusCode::FAILURE;
83  break;
84  }
85  if ( status.isSuccess() && update ) { status = updateServiceState( pAddress ); }
86  return status;
87  }
88  status.ignore();
89  info() << "No converter for object ";
90  if ( pObject ) { msgStream() << System::typeinfoName( typeid( *pObject ) ); }
91  msgStream() << " CLID= " << obj_class << endmsg;
92  return Status::NO_CONVERTER;
93 }
94 
96 
98 
101  return makeCall( CREATE_OBJ, false, true, false, pAddress, refpObj );
102 }
103 
106  return makeCall( FILL_OBJ_REFS, false, true, true, pAddress, pObj );
107 }
108 
111  return makeCall( UPDATE_OBJ, false, true, false, pAddress, pObj );
112 }
113 
116  return makeCall( UPDATE_OBJ_REFS, false, true, true, pAddress, pObj );
117 }
118 
121  return makeCall( CREATE_REP, true, false, false, refpAddress, pObj );
122 }
123 
126  return makeCall( FILL_REP_REFS, true, false, false, pAddress, pObj );
127 }
128 
131  return makeCall( UPDATE_REP, true, false, false, pAddress, pObj );
132 }
133 
136  return makeCall( UPDATE_REP_REFS, true, false, false, pAddress, pObj );
137 }
138 
141  IConverter* cnv = nullptr;
142  auto i = std::find_if( m_workers.begin(), m_workers.end(), CnvTest( clid ) );
143  if ( i != m_workers.end() ) cnv = i->converter();
144  if ( !cnv ) {
145  StatusCode status = addConverter( clid );
146  if ( status.isSuccess() ) {
147  i = std::find_if( m_workers.begin(), m_workers.end(), CnvTest( clid ) );
148  if ( i != m_workers.end() ) cnv = i->converter();
149  }
150  }
151  return cnv;
152 }
153 
156  if ( !pDataSvc ) return StatusCode::SUCCESS; // Atlas does not use DataSvc
157  m_dataSvc = pDataSvc;
158  for ( auto& i : m_workers ) {
159  IConverter* cnv = i.converter();
160  if ( cnv && cnv->setDataProvider( m_dataSvc ).isFailure() ) { error() << "setting Data Provider" << endmsg; }
161  }
162  return StatusCode::SUCCESS;
163 }
164 
167 
171  for ( auto& i : m_workers ) {
172  auto* cnv = i.converter();
173  if ( cnv ) {
174  if ( cnv->setAddressCreator( m_addressCreator ).isFailure() ) { error() << "setting Address Creator" << endmsg; }
175  }
176  }
177  return StatusCode::SUCCESS;
178 }
179 
182 
185 
188 
191  // First look for the more specific converter
192  long typ = repSvcType();
193  IConverter* pConverter = createConverter( typ, clid, nullptr );
194  if ( pConverter ) {
195  StatusCode status = configureConverter( typ, clid, pConverter );
196  if ( status.isSuccess() ) {
197  status = initializeConverter( typ, clid, pConverter );
198  if ( status.isSuccess() ) {
199  status = activateConverter( typ, clid, pConverter );
200  if ( status.isSuccess() ) {
201  long conv_typ = pConverter->repSvcType();
202  const CLID& conv_clid = pConverter->objType();
203  typ = ( typ < 0xFF ) ? typ : typ & 0xFFFFFF00;
204  conv_typ = ( conv_typ < 0xFF ) ? conv_typ : conv_typ & 0xFFFFFF00;
205  if ( conv_typ == typ && conv_clid == clid ) { return addConverter( pConverter ); }
206  }
207  }
208  }
209  pConverter->release();
210  }
211  return Status::NO_CONVERTER;
212 }
213 
216  if ( pConverter ) {
217  const CLID& clid = pConverter->objType();
218  removeConverter( clid ).ignore();
219  m_workers.emplace_back( clid, pConverter );
220  return StatusCode::SUCCESS;
221  }
222  return Status::NO_CONVERTER;
223 }
224 
227 
229  [f = CnvTest( clid )]( const WorkerEntry& we ) { return !f( we ); } );
230  if ( i == std::end( m_workers ) ) return Status::NO_CONVERTER;
231  std::for_each( i, std::end( m_workers ), []( WorkerEntry& w ) { w.converter()->finalize().ignore(); } );
232  m_workers.erase( i, std::end( m_workers ) );
233  return StatusCode::SUCCESS;
234 }
235 
238 
241  // Release all workers.
242  for ( auto& i : m_workers ) {
243  if ( i.converter()->finalize().isFailure() ) { error() << "finalizing worker" << endmsg; }
244  }
245  m_workers.clear();
246  // release interfaces
247  m_addressCreator = nullptr;
248  m_dataSvc = nullptr;
249  m_cnvSvc = nullptr;
250  return Service::finalize();
251 }
252 
254 IConverter* ConversionSvc::createConverter( long typ, const CLID& clid, const ICnvFactory* /*fac*/ ) {
255  IConverter* pConverter = Converter::Factory::create( ConverterID( typ, clid ), serviceLocator().get() ).release();
256  if ( !pConverter ) {
257  typ = ( typ < 0xFF ) ? typ : typ & 0xFFFFFF00;
258  pConverter = Converter::Factory::create( ConverterID( typ, clid ), serviceLocator().get() ).release();
259  }
260  return pConverter;
261 }
262 
264 StatusCode ConversionSvc::configureConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) {
265  if ( !pConverter ) return Status::NO_CONVERTER;
266  pConverter->setConversionSvc( this ).ignore();
267  pConverter->setAddressCreator( m_addressCreator ).ignore();
268  pConverter->setDataProvider( m_dataSvc ).ignore();
269  return StatusCode::SUCCESS;
270 }
271 
273 StatusCode ConversionSvc::initializeConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) {
274  return pConverter ? pConverter->initialize() : Status::NO_CONVERTER;
275 }
276 
278 StatusCode ConversionSvc::activateConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) {
279  return pConverter ? StatusCode::SUCCESS : StatusCode( Status::NO_CONVERTER );
280 }
281 
283 const CLID& ConversionSvc::objType() const { return CLID_NULL; }
284 
286 long ConversionSvc::repSvcType() const { return m_type; }
287 
289 StatusCode ConversionSvc::connectOutput( const std::string& outputFile, const std::string& /* openMode */ ) {
290  return connectOutput( outputFile );
291 }
292 
295 
298 
300 StatusCode ConversionSvc::createAddress( long /* svc_type */, const CLID& /* clid */, const std::string* /* par */,
301  const unsigned long* /* ip */, IOpaqueAddress*& refpAddress ) {
302  refpAddress = nullptr;
303  return StatusCode::FAILURE;
304 }
305 
308  refAddress.clear();
309  return StatusCode::FAILURE;
310 }
311 
313 StatusCode ConversionSvc::createAddress( long /* svc_type */, const CLID& /* clid */,
314  const std::string& /* refAddress */, IOpaqueAddress*& refpAddress ) {
315  refpAddress = nullptr;
316  return StatusCode::FAILURE;
317 }
318 
321  : base_class( name, svc ), m_cnvSvc( this ) {
322  m_type = type;
323  m_dataSvc = nullptr;
324  setAddressCreator( this ).ignore();
325 }
UPDATE_REP_REFS
@ UPDATE_REP_REFS
Definition: PersistencySvc.cpp:33
std::for_each
T for_each(T... args)
ConversionSvc::addConverter
StatusCode addConverter(const CLID &clid) override
Add converter object to conversion service.
Definition: ConversionSvc.cpp:190
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:118
IAddressCreator
Definition: IAddressCreator.h:38
std::string
STL class.
ConversionSvc::m_addressCreator
SmartIF< IAddressCreator > m_addressCreator
Pointer to the address creation service interface.
Definition: ConversionSvc.h:214
ConversionSvc::objType
const CLID & objType() const override
Implementation of IConverter: dummy call.
Definition: ConversionSvc.cpp:283
ConversionSvc::createAddress
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.
Definition: ConversionSvc.cpp:300
IConverter::fillRepRefs
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the converted object.
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
IConverter::updateRepRefs
virtual StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an already converted object.
ConversionSvc::configureConverter
virtual StatusCode configureConverter(long typ, const CLID &clid, IConverter *cnv)
Configure the new converter before initialize is called.
Definition: ConversionSvc.cpp:264
System.h
CnvSvcAction
CnvSvcAction
Definition: PersistencySvc.cpp:25
ConversionSvc::makeCall
StatusCode makeCall(int typ, bool ignore_add, bool ignore_obj, bool update, IOpaqueAddress *&pAddress, DataObject *&pObject)
Definition: ConversionSvc.cpp:38
CREATE_OBJ
@ CREATE_OBJ
Definition: PersistencySvc.cpp:26
IOpaqueAddress
Definition: IOpaqueAddress.h:33
std::find_if
T find_if(T... args)
ISvcLocator
Definition: ISvcLocator.h:46
ConversionSvc::ConversionSvc
ConversionSvc(const std::string &name, ISvcLocator *svc, long type)
Standard Constructor.
Definition: ConversionSvc.cpp:320
IConverter::setConversionSvc
virtual StatusCode setConversionSvc(IConversionSvc *pService)=0
Set conversion service the converter is connected to.
GaudiPartProp.decorators.get
get
decorate the vector of properties
Definition: decorators.py:283
IConverter
Definition: IConverter.h:68
ConversionSvc::createObj
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Implementation of IConverter: Create the transient representation of an object.
Definition: ConversionSvc.cpp:100
ConversionSvc::converter
IConverter * converter(const CLID &wanted) override
Retrieve converter from list.
Definition: ConversionSvc.cpp:140
IConverter::createObj
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
ConversionSvc::WorkerEntry
Definition: ConversionSvc.h:56
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:315
ConversionSvc::activateConverter
virtual StatusCode activateConverter(long typ, const CLID &clid, IConverter *cnv)
Activate the new converter after initialization.
Definition: ConversionSvc.cpp:278
ConversionSvc::WorkerEntry::converter
IConverter * converter()
Definition: ConversionSvc.h:81
ConversionSvc::loadConverter
virtual void loadConverter(DataObject *pObject)
Load converter or dictionary needed by the converter.
Definition: ConversionSvc.cpp:95
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:222
IDataProviderSvc.h
std::string::clear
T clear(T... args)
FILL_OBJ_REFS
@ FILL_OBJ_REFS
Definition: PersistencySvc.cpp:27
ConversionSvc::fillObjRefs
StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Resolve the references of the created transient object.
Definition: ConversionSvc.cpp:105
Converter.h
IConverter::setDataProvider
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
ConversionSvc::updateObjRefs
StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the references of an updated transient object.
Definition: ConversionSvc.cpp:115
ConversionSvc::updateServiceState
virtual StatusCode updateServiceState(IOpaqueAddress *pAddress)
Update state of the service.
Definition: ConversionSvc.cpp:97
ConversionSvc::removeConverter
StatusCode removeConverter(const CLID &clid) override
Remove converter object from conversion service (if present).
Definition: ConversionSvc.cpp:226
ConverterID
Definition: Converter.h:147
ConversionSvc::convertAddress
StatusCode convertAddress(const IOpaqueAddress *pAddress, std::string &refAddress) override
Convert an address to string form.
Definition: ConversionSvc.cpp:307
ConversionSvc::conversionSvc
SmartIF< IConversionSvc > & conversionSvc() const override
Implementation of IConverter: Get conversion service the converter is connected to.
Definition: ConversionSvc.cpp:187
StatusCode
Definition: StatusCode.h:65
IConverter::createRep
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)=0
Convert the transient object to the requested representation.
ConversionSvc::connectOutput
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
Definition: ConversionSvc.cpp:289
IOpaqueAddress.h
CommonMessaging
Definition: CommonMessaging.h:66
ConversionSvc::setConversionSvc
StatusCode setConversionSvc(IConversionSvc *svc) override
Implementation of IConverter: Set conversion service the converter is connected to.
Definition: ConversionSvc.cpp:184
IConverter::setAddressCreator
virtual StatusCode setAddressCreator(IAddressCreator *creator)=0
Set address creator facility.
CREATE_REP
@ CREATE_REP
Definition: PersistencySvc.cpp:30
IConverter::updateObj
virtual StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject)=0
Update the transient object from the other representation.
IOpaqueAddress::clID
virtual const CLID & clID() const =0
Retrieve class information from link.
ConversionSvc::updateObj
StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject) override
Implementation of IConverter: Update the transient object from the other representation.
Definition: ConversionSvc.cpp:110
Write.creator
creator
Definition: Write.py:23
ConversionSvc::m_type
long m_type
Conversion service type.
Definition: ConversionSvc.h:218
SmartIF< IDataProviderSvc >
CLID
unsigned int CLID
Class ID definition.
Definition: ClassID.h:18
ConversionSvc::updateRep
StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the converted representation of a transient object.
Definition: ConversionSvc.cpp:130
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
ConversionSvc::updateRepRefs
StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the references of an already converted object.
Definition: ConversionSvc.cpp:135
IConverter::repSvcType
virtual long repSvcType() const =0
Retrieve the class type of the data store the converter uses.
UPDATE_REP
@ UPDATE_REP
Definition: PersistencySvc.cpp:32
IConverter.h
StatusCode::ignore
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition: StatusCode.h:139
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
ConversionSvc::m_cnvSvc
SmartIF< IConversionSvc > m_cnvSvc
Pointer to the IConversionSvc interface of this.
Definition: ConversionSvc.h:216
gaudirun.type
type
Definition: gaudirun.py:160
ConversionSvc::setDataProvider
StatusCode setDataProvider(IDataProviderSvc *pService) override
Implementation of IConverter: Set Data provider service.
Definition: ConversionSvc.cpp:155
UPDATE_OBJ_REFS
@ UPDATE_OBJ_REFS
Definition: PersistencySvc.cpp:29
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
ConversionSvc::initialize
StatusCode initialize() override
Initialize the service.
Definition: ConversionSvc.cpp:237
DataObject.h
ConversionSvc::createConverter
virtual IConverter * createConverter(long typ, const CLID &clid, const ICnvFactory *fac)
Create new Converter using factory.
Definition: ConversionSvc.cpp:254
IConverter::updateObjRefs
virtual StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an updated transient object.
std::begin
T begin(T... args)
IConverter::updateRep
virtual StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the converted representation of a transient object.
ConversionSvc::finalize
StatusCode finalize() override
stop the service.
Definition: ConversionSvc.cpp:240
GaudiPython.Pythonizations.update
update
Definition: Pythonizations.py:145
ConversionSvc::fillRepRefs
StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Resolve the references of the converted object.
Definition: ConversionSvc.cpp:125
ConversionSvc::commitOutput
StatusCode commitOutput(const std::string &output, bool do_commit) override
Commit pending output.
Definition: ConversionSvc.cpp:297
DataObject
Definition: DataObject.h:36
UPDATE_OBJ
@ UPDATE_OBJ
Definition: PersistencySvc.cpp:28
ConversionSvc::createRep
StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Implementation of IConverter: Convert the transient object to the requested representation.
Definition: ConversionSvc.cpp:120
IConverter::initialize
virtual StatusCode initialize()=0
Initialize the converter.
IConverter::fillObjRefs
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the created transient object.
std::end
T end(T... args)
IDataProviderSvc
Definition: IDataProviderSvc.h:53
IConverter::objType
virtual const CLID & objType() const =0
Retrieve the class type of objects the converter produces.
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
ConversionSvc::addressCreator
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
Definition: ConversionSvc.cpp:181
ConversionSvc::initializeConverter
virtual StatusCode initializeConverter(long typ, const CLID &clid, IConverter *cnv)
Initialize the new converter.
Definition: ConversionSvc.cpp:273
ConversionSvc::setAddressCreator
StatusCode setAddressCreator(IAddressCreator *creator) override
Set address creator facility.
Definition: ConversionSvc.cpp:169
IInterface::release
virtual unsigned long release()=0
Release Interface instance.
ConversionSvc.h
ConversionSvc::m_dataSvc
SmartIF< IDataProviderSvc > m_dataSvc
Pointer to data provider service.
Definition: ConversionSvc.h:212
DataObject::clID
virtual const CLID & clID() const
Retrieve reference to class definition structure.
Definition: DataObject.cpp:66
std::partition
T partition(T... args)
ConversionSvc::repSvcType
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
Definition: ConversionSvc.cpp:286
ConversionSvc::dataProvider
SmartIF< IDataProviderSvc > & dataProvider() const override
Implementation of IConverter: Get Data provider service.
Definition: ConversionSvc.cpp:166
FILL_REP_REFS
@ FILL_REP_REFS
Definition: PersistencySvc.cpp:31
MsgStream.h
ConversionSvc::m_workers
std::vector< WorkerEntry > m_workers
List of conversion workers.
Definition: ConversionSvc.h:220
Service::serviceLocator
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator
Definition: Service.cpp:335
IConversionSvc
Definition: IConversionSvc.h:47