The Gaudi Framework  master (82fdf313)
Loading...
Searching...
No Matches
ConversionSvc.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 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
20#include <GaudiKernel/System.h>
21
22namespace {
23
24 auto CnvTest = []( CLID clid ) { return [clid]( const auto& i ) { return i.clID() == clid; }; };
25
26 enum CnvSvcAction {
35 };
36} // namespace
37
38StatusCode 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
170 m_addressCreator = creator;
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
228 auto i = std::partition( std::begin( m_workers ), std::end( m_workers ),
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
254IConverter* 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
264StatusCode ConversionSvc::configureConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) {
265 if ( !pConverter ) return Status::NO_CONVERTER;
266 pConverter->setConversionSvc( this ).ignore();
268 pConverter->setDataProvider( m_dataSvc ).ignore();
269 return StatusCode::SUCCESS;
270}
271
273StatusCode ConversionSvc::initializeConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) {
274 return pConverter ? pConverter->initialize() : Status::NO_CONVERTER;
275}
276
278StatusCode ConversionSvc::activateConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) {
279 return pConverter ? StatusCode::SUCCESS : StatusCode( Status::NO_CONVERTER );
280}
281
283const CLID& ConversionSvc::objType() const { return CLID_NULL; }
284
286long ConversionSvc::repSvcType() const { return m_type; }
287
289StatusCode ConversionSvc::connectOutput( const std::string& outputFile, const std::string& /* openMode */ ) {
290 return connectOutput( outputFile );
291}
292
294StatusCode ConversionSvc::connectOutput( const std::string& /* outputFile */ ) { return StatusCode::SUCCESS; }
295
297StatusCode ConversionSvc::commitOutput( const std::string&, bool ) { return StatusCode::SUCCESS; }
298
300StatusCode 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
307StatusCode ConversionSvc::convertAddress( const IOpaqueAddress* /* pAddress */, std::string& refAddress ) {
308 refAddress.clear();
309 return StatusCode::FAILURE;
310}
311
313StatusCode ConversionSvc::createAddress( long /* svc_type */, const CLID& /* clid */,
314 const std::string& /* refAddress */, IOpaqueAddress*& refpAddress ) {
315 refpAddress = nullptr;
316 return StatusCode::FAILURE;
317}
318
320ConversionSvc::ConversionSvc( const std::string& name, ISvcLocator* svc, long type )
321 : base_class( name, svc ), m_dataSvc( nullptr ), m_cnvSvc( this ), m_type( type ) {
322 setAddressCreator( this ).ignore();
323}
unsigned int CLID
Class ID definition.
Definition ClassID.h:16
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
CnvSvcAction
@ CREATE_OBJ
@ UPDATE_OBJ
@ UPDATE_REP
@ UPDATE_REP_REFS
@ CREATE_REP
@ FILL_OBJ_REFS
@ FILL_REP_REFS
@ UPDATE_OBJ_REFS
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & msgStream() const
Return an uninitialized MsgStream.
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
IConverter * converter()
StatusCode makeCall(int typ, bool ignore_add, bool ignore_obj, bool update, IOpaqueAddress *&pAddress, DataObject *&pObject)
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
virtual IConverter * createConverter(long typ, const CLID &clid, const ICnvFactory *fac)
Create new Converter using factory.
StatusCode removeConverter(const CLID &clid) override
Remove converter object from conversion service (if present).
StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Resolve the references of the converted object.
StatusCode convertAddress(const IOpaqueAddress *pAddress, std::string &refAddress) override
Convert an address to string form.
virtual void loadConverter(DataObject *pObject)
Load converter or dictionary needed by the converter.
SmartIF< IConversionSvc > & conversionSvc() const override
Implementation of IConverter: Get conversion service the converter is connected to.
StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject) override
Implementation of IConverter: Update the transient object from the other representation.
StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the references of an updated transient object.
StatusCode finalize() override
stop the service.
StatusCode setAddressCreator(IAddressCreator *creator) override
Set address creator facility.
virtual StatusCode configureConverter(long typ, const CLID &clid, IConverter *cnv)
Configure the new converter before initialize is called.
StatusCode setConversionSvc(IConversionSvc *svc) override
Implementation of IConverter: Set conversion service the converter is connected to.
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
virtual StatusCode initializeConverter(long typ, const CLID &clid, IConverter *cnv)
Initialize the new converter.
long m_type
Conversion service type.
SmartIF< IAddressCreator > m_addressCreator
Pointer to the address creation service interface.
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.
StatusCode setDataProvider(IDataProviderSvc *pService) override
Implementation of IConverter: Set Data provider service.
virtual StatusCode activateConverter(long typ, const CLID &clid, IConverter *cnv)
Activate the new converter after initialization.
IConverter * converter(const CLID &wanted) override
Retrieve converter from list.
StatusCode initialize() override
Initialize the service.
SmartIF< IDataProviderSvc > & dataProvider() const override
Implementation of IConverter: Get Data provider service.
SmartIF< IConversionSvc > m_cnvSvc
Pointer to the IConversionSvc interface of this.
const CLID & objType() const override
Implementation of IConverter: dummy call.
virtual StatusCode updateServiceState(IOpaqueAddress *pAddress)
Update state of the service.
StatusCode commitOutput(const std::string &output, bool do_commit) override
Commit pending output.
StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the converted representation of a transient object.
StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Update the references of an already converted object.
StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Implementation of IConverter: Convert the transient object to the requested representation.
ConversionSvc(const std::string &name, ISvcLocator *svc, long type)
Standard Constructor.
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Implementation of IConverter: Create the transient representation of an object.
StatusCode addConverter(const CLID &clid) override
Add converter object to conversion service.
SmartIF< IDataProviderSvc > m_dataSvc
Pointer to data provider service.
StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Resolve the references of the created transient object.
std::vector< WorkerEntry > m_workers
List of conversion workers.
A DataObject is the base class of any identifiable object on any data store.
Definition DataObject.h:37
virtual const CLID & clID() const
Retrieve reference to class definition structure.
IAddressCreator interface definition.
The data converters are responsible to translate data from one representation into another.
Definition IConverter.h:65
virtual StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an already converted object.
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the created transient object.
virtual StatusCode finalize()=0
Terminate the converter.
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
virtual StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject)=0
Update the transient object from the other representation.
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
virtual StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the converted representation of a transient object.
virtual StatusCode setConversionSvc(IConversionSvc *pService)=0
Set conversion service the converter is connected to.
virtual long repSvcType() const =0
Retrieve the class type of the data store the converter uses.
virtual StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an updated transient object.
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)=0
Convert the transient object to the requested representation.
virtual StatusCode initialize()=0
Initialize the converter.
virtual const CLID & objType() const =0
Retrieve the class type of objects the converter produces.
virtual StatusCode setAddressCreator(IAddressCreator *creator)=0
Set address creator facility.
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the converted object.
Data provider interface definition.
virtual unsigned long release() const =0
Release Interface instance.
Opaque address interface definition.
virtual const CLID & clID() const =0
Retrieve class information from link.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition Service.cpp:336
StatusCode finalize() override
Definition Service.cpp:223
const std::string & name() const override
Retrieve name of the service.
Definition Service.cpp:333
StatusCode initialize() override
Definition Service.cpp:118
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isFailure() const
Definition StatusCode.h:129
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition StatusCode.h:139
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260