The Gaudi Framework  v30r3 (a5ef0a68)
ConversionSvc.cpp
Go to the documentation of this file.
1 #define GAUDIKERNEL_CONVERSIONSVC_CPP
2 
10 #include "GaudiKernel/System.h"
11 
12 namespace
13 {
14 
15  auto CnvTest = []( CLID clid ) { return [clid]( const auto& i ) { return i.clID() == clid; }; };
16 
17  enum CnvSvcAction {
18  CREATE_OBJ,
20  UPDATE_OBJ,
22  CREATE_REP,
24  UPDATE_REP,
26  };
27 }
28 
29 StatusCode ConversionSvc::makeCall( int typ, bool ignore_add, bool ignore_obj, bool update, IOpaqueAddress*& pAddress,
30  DataObject*& pObject )
31 {
32  if ( !pAddress && !ignore_add ) return Status::INVALID_ADDRESS;
33  if ( !pObject && !ignore_obj ) return Status::INVALID_OBJECT;
34  const CLID& obj_class =
35  ( pObject && !ignore_obj ) ? pObject->clID() : ( pAddress && !ignore_add ) ? pAddress->clID() : 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  info() << "No converter for object ";
83  if ( pObject ) {
84  msgStream() << System::typeinfoName( typeid( *pObject ) );
85  }
86  msgStream() << " CLID= " << obj_class << endmsg;
87  return Status::NO_CONVERTER;
88 }
89 
91 
93 
96 {
97  return makeCall( CREATE_OBJ, false, true, false, pAddress, refpObj );
98 }
99 
102 {
103  return makeCall( FILL_OBJ_REFS, false, true, true, pAddress, pObj );
104 }
105 
108 {
109  return makeCall( UPDATE_OBJ, false, true, false, pAddress, pObj );
110 }
111 
114 {
115  return makeCall( UPDATE_OBJ_REFS, false, true, true, pAddress, pObj );
116 }
117 
120 {
121  return makeCall( CREATE_REP, true, false, false, refpAddress, pObj );
122 }
123 
126 {
127  return makeCall( FILL_REP_REFS, true, false, false, pAddress, pObj );
128 }
129 
132 {
133  return makeCall( UPDATE_REP, true, false, false, pAddress, pObj );
134 }
135 
138 {
139  return makeCall( UPDATE_REP_REFS, true, false, false, pAddress, pObj );
140 }
141 
144 {
145  IConverter* cnv = nullptr;
146  auto i = std::find_if( m_workers.begin(), m_workers.end(), CnvTest( clid ) );
147  if ( i != m_workers.end() ) cnv = i->converter();
148  if ( !cnv ) {
149  StatusCode status = addConverter( clid );
150  if ( status.isSuccess() ) {
151  i = std::find_if( m_workers.begin(), m_workers.end(), CnvTest( clid ) );
152  if ( i != m_workers.end() ) cnv = i->converter();
153  }
154  }
155  return cnv;
156 }
157 
160 {
161  if ( !pDataSvc ) return StatusCode::SUCCESS; // Atlas does not use DataSvc
162  m_dataSvc = pDataSvc;
163  for ( auto& i : m_workers ) {
164  IConverter* cnv = i.converter();
165  if ( cnv && cnv->setDataProvider( m_dataSvc ).isFailure() ) {
166  error() << "setting Data Provider" << endmsg;
167  }
168  }
169  return StatusCode::SUCCESS;
170 }
171 
174 
177 {
178  m_addressCreator = creator;
179  for ( auto& i : m_workers ) {
180  auto* cnv = i.converter();
181  if ( cnv ) {
182  if ( cnv->setAddressCreator( m_addressCreator ).isFailure() ) {
183  error() << "setting Address Creator" << endmsg;
184  }
185  }
186  }
187  return StatusCode::SUCCESS;
188 }
189 
192 
195 
198 
201 {
202  // First look for the more specific converter
203  long typ = repSvcType();
204  IConverter* pConverter = createConverter( typ, clid, nullptr );
205  if ( pConverter ) {
206  StatusCode status = configureConverter( typ, clid, pConverter );
207  if ( status.isSuccess() ) {
208  status = initializeConverter( typ, clid, pConverter );
209  if ( status.isSuccess() ) {
210  status = activateConverter( typ, clid, pConverter );
211  if ( status.isSuccess() ) {
212  long conv_typ = pConverter->repSvcType();
213  const CLID& conv_clid = pConverter->objType();
214  typ = ( typ < 0xFF ) ? typ : typ & 0xFFFFFF00;
215  conv_typ = ( conv_typ < 0xFF ) ? conv_typ : conv_typ & 0xFFFFFF00;
216  if ( conv_typ == typ && conv_clid == clid ) {
217  return addConverter( pConverter );
218  }
219  }
220  }
221  }
222  pConverter->release();
223  }
224  return Status::NO_CONVERTER;
225 }
226 
229 {
230  if ( pConverter ) {
231  const CLID& clid = pConverter->objType();
232  removeConverter( clid ).ignore();
233  m_workers.emplace_back( clid, pConverter );
234  return StatusCode::SUCCESS;
235  }
236  return Status::NO_CONVERTER;
237 }
238 
241 {
242 
244  [f = CnvTest( clid )]( const WorkerEntry& we ) { return !f( we ); } );
245  if ( i == std::end( m_workers ) ) return Status::NO_CONVERTER;
246  std::for_each( i, std::end( m_workers ), []( WorkerEntry& w ) { w.converter()->finalize().ignore(); } );
247  m_workers.erase( i, std::end( m_workers ) );
248  return StatusCode::SUCCESS;
249 }
250 
253 
256 {
257  // Release all workers.
258  for ( auto& i : m_workers ) {
259  if ( i.converter()->finalize().isFailure() ) {
260  error() << "finalizing worker" << endmsg;
261  }
262  }
263  m_workers.clear();
264  // release interfaces
265  m_addressCreator = nullptr;
266  m_dataSvc = nullptr;
267  m_cnvSvc = nullptr;
268  return Service::finalize();
269 }
270 
272 IConverter* ConversionSvc::createConverter( long typ, const CLID& clid, const ICnvFactory* /*fac*/ )
273 {
274  IConverter* pConverter = Converter::Factory::create( ConverterID( typ, clid ), serviceLocator().get() ).release();
275  if ( !pConverter ) {
276  typ = ( typ < 0xFF ) ? typ : typ & 0xFFFFFF00;
277  pConverter = Converter::Factory::create( ConverterID( typ, clid ), serviceLocator().get() ).release();
278  }
279  return pConverter;
280 }
281 
283 StatusCode ConversionSvc::configureConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter )
284 {
285  if ( !pConverter ) return Status::NO_CONVERTER;
286  pConverter->setConversionSvc( this ).ignore();
287  pConverter->setAddressCreator( m_addressCreator ).ignore();
288  pConverter->setDataProvider( m_dataSvc ).ignore();
289  return StatusCode::SUCCESS;
290 }
291 
293 StatusCode ConversionSvc::initializeConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter )
294 {
295  return pConverter ? pConverter->initialize() : Status::NO_CONVERTER;
296 }
297 
299 StatusCode ConversionSvc::activateConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter )
300 {
301  return pConverter ? StatusCode::SUCCESS : StatusCode( Status::NO_CONVERTER );
302 }
303 
305 const CLID& ConversionSvc::objType() const { return CLID_NULL; }
306 
308 long ConversionSvc::repSvcType() const { return m_type; }
309 
311 StatusCode ConversionSvc::connectOutput( const std::string& outputFile, const std::string& /* openMode */ )
312 {
313  return connectOutput( outputFile );
314 }
315 
318 
321 
323 StatusCode ConversionSvc::createAddress( long /* svc_type */, const CLID& /* clid */,
324  const std::string* /* par */, const unsigned long* /* ip */,
325  IOpaqueAddress*& refpAddress )
326 {
327  refpAddress = nullptr;
328  return StatusCode::FAILURE;
329 }
330 
333 {
334  refAddress.clear();
335  return StatusCode::FAILURE;
336 }
337 
339 StatusCode ConversionSvc::createAddress( long /* svc_type */, const CLID& /* clid */,
340  const std::string& /* refAddress */, IOpaqueAddress*& refpAddress )
341 {
342  refpAddress = nullptr;
343  return StatusCode::FAILURE;
344 }
345 
348  : base_class( name, svc ), m_cnvSvc( this )
349 {
350  m_type = type;
351  m_dataSvc = nullptr;
352  setAddressCreator( this ).ignore();
353 }
IConverter * converter()
Definition: ConversionSvc.h:78
constexpr static const auto FAILURE
Definition: StatusCode.h:88
StatusCode initialize() override
Definition: Service.cpp:63
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:58
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:288
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
StatusCode finalize() override
Definition: Service.cpp:173
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:332
ConversionSvc(const std::string &name, ISvcLocator *svc, long type)
Standard Constructor.
bool isSuccess() const
Definition: StatusCode.h:287
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:47
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
Definition: StatusCode.h:139
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:62
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:51
void clear(STATE_TYPE _i=std::ios_base::failbit)
Definition: MsgStream.h:187
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.
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
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)
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:165
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.
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:291
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:209
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.