The Gaudi Framework  v30r3 (a5ef0a68)
DataSvcFileEntriesTool.cpp
Go to the documentation of this file.
1 // ========== header
2 #include "GaudiKernel/AlgTool.h"
5 #include "GaudiKernel/SmartIF.h"
6 
7 class IIncidentSvc;
8 struct IDataManagerSvc;
9 class IDataProviderSvc;
10 class IRegistry;
27 class DataSvcFileEntriesTool : public extends<AlgTool, IDataStoreLeaves, IIncidentListener>
28 {
29 public:
31  using extends::extends;
32 
34  StatusCode initialize() override;
35 
37  StatusCode finalize() override;
38 
43  const LeavesList& leaves() const override;
44 
48  void handle( const Incident& incident ) override;
49 
50 private:
51  Gaudi::Property<std::string> m_dataSvcName{this, "DataService", "EventDataSvc", "Name of the data service to use"};
52  Gaudi::Property<std::string> m_rootNode{this, "Root", "", "Path to the element from which to start the scan"};
54  this, "ScanOnBeginEvent", false,
55  "If the scan has to be started during the BeginEvent incident (true) or on demand (false, default)"};
57  this, "IgnoreOriginChange", false,
58  "Disable the detection of the change in the origin of object between the BeginEvent and the scan"};
59 
66 
68  LeavesList m_leaves;
69 
71  void i_collectLeaves();
73  void i_collectLeaves( IRegistry* reg );
74 
78 
84 };
85 
86 // ========== implementation
87 #include "GaudiKernel/DataObject.h"
93 #include "GaudiKernel/IRegistry.h"
94 
96 
98 {
100  if ( sc.isFailure() ) return sc;
101 
102  // Retrieve the pointer to the needed services.
103 
104  m_incidentSvc = serviceLocator()->service( "IncidentSvc" );
105  if ( !m_incidentSvc ) {
106  error() << "Cannot get IncidentSvc" << endmsg;
107  return StatusCode::FAILURE;
108  }
109 
111  if ( !m_dataSvc || !m_dataMgrSvc ) {
112  error() << "Cannot get IDataProviderSvc+IDataManagerSvc " << m_dataSvcName << endmsg;
113  return StatusCode::FAILURE;
114  }
115 
116  // Register ourself to the incident service as listener for BeginEvent
117  m_incidentSvc->addListener( this, IncidentType::BeginEvent );
118 
119  // If the Root node is not specified, take the name from the data service itself.
120  if ( m_rootNode.empty() ) {
122  }
123 
124  // Clear the cache (in case the instance is re-initilized).
125  m_leaves.clear();
126  return StatusCode::SUCCESS;
127 }
128 
130 {
131  // unregister from the incident service
132  if ( m_incidentSvc ) {
133  m_incidentSvc->removeListener( this, IncidentType::BeginEvent );
134  }
135  // Release the services
138  m_dataSvc.reset();
139 
140  return AlgTool::finalize();
141 }
142 
144 {
145  // Get the file id of the root node at every event
146  IOpaqueAddress* addr = i_getRootNode()->address();
147  if ( addr )
148  m_initialBase = addr->par()[0];
149  else
150  m_initialBase.clear(); // use empty file id if there is no address
151 
152  m_leaves.clear();
153  if ( m_scanOnBeginEvent ) {
154  verbose() << "::handle scanning on " << incident.type() << endmsg;
155  i_collectLeaves();
156  }
157 }
158 
160 {
161  if ( m_leaves.empty() ) {
162  const_cast<DataSvcFileEntriesTool*>( this )->i_collectLeaves();
163  }
164  return m_leaves;
165 }
166 
168 {
169  DataObject* obj = nullptr;
170  StatusCode sc = m_dataSvc->retrieveObject( m_rootNode.value(), obj );
171  if ( sc.isFailure() ) {
172  throw GaudiException( "Cannot get " + m_rootNode + " from " + m_dataSvcName, name(), StatusCode::FAILURE );
173  }
174  return obj->registry();
175 }
176 
178 
181 {
182  // I do not put sanity checks on the pointers because I know how I'm calling the function
183  IOpaqueAddress* addr = reg->address();
184  if ( addr ) { // we consider only objects that are in a file
185  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "::i_collectLeaves added " << reg->identifier() << endmsg;
186  m_leaves.push_back( reg->object() ); // add this object
187  // Origin of the current object
188  const std::string& base = addr->par()[0];
189  // Compare with the origin seen during BeginEvent
190  if ( !m_ignoreOriginChange && ( m_initialBase != base ) )
191  throw GaudiException( "Origin of data has changed ('" + m_initialBase + "' != '" + base +
192  "'), probably OutputStream was called before "
193  "InputCopyStream: check options",
195 
196  std::vector<IRegistry*> lfs; // leaves of the current object
197  StatusCode sc = m_dataMgrSvc->objectLeaves( reg, lfs );
198  if ( sc.isSuccess() ) {
199  for ( const auto& i : lfs ) {
200  // Continue if the leaf has the same database as the parent
201  if ( i->address() && i->address()->par()[0] == base ) {
202  DataObject* obj = nullptr;
203  sc = m_dataSvc->retrieveObject( reg, i->name(), obj );
204  if ( sc.isSuccess() ) {
205  i_collectLeaves( i );
206  } else {
207  throw GaudiException( "Cannot get " + i->identifier() + " from " + m_dataSvcName, name(),
209  }
210  }
211  }
212  }
213  }
214 }
215 
constexpr static const auto FAILURE
Definition: StatusCode.h:88
virtual StatusCode objectLeaves(const DataObject *pObject, std::vector< IRegistry * > &refLeaves)=0
Explore the object store: retrieve all leaves attached to the object The object is identified by its ...
Define general base for Gaudi exception.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: AlgTool.cpp:83
const std::string & type() const
Access to the incident type.
Definition: Incident.h:41
Implementation of property with value of concrete type.
Definition: Property.h:381
StatusCode initialize() override
Definition: AlgTool.cpp:223
bool isSuccess() const
Definition: StatusCode.h:287
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
virtual const name_type & name() const =0
Name of the directory (or key)
Gaudi::Property< std::string > m_rootNode
Data provider interface definition.
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
virtual const std::string * par() const =0
Retrieve String parameters.
SmartIF< IDataProviderSvc > m_dataSvc
Pointer to the IDataProviderSvc interface of the data service.
std::string m_initialBase
File ID of the Root node.
bool isFailure() const
Definition: StatusCode.h:139
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:73
Tool to scan a transient store branch that collects all the objects that belong to the same source (f...
SmartIF< IDataManagerSvc > m_dataMgrSvc
Pointer to the IDataManagerSvc interface of the data service.
STL class.
#define DECLARE_COMPONENT(type)
StatusCode finalize() override
Definition: AlgTool.cpp:293
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:79
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
StatusCode finalize() override
Finalize the tool.
void i_collectLeaves()
Scan the data service starting from the node specified as Root.
virtual const id_type & identifier() const =0
Full identifier (or key)
Gaudi::Property< bool > m_ignoreOriginChange
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
Gaudi::Property< std::string > m_dataSvcName
Gaudi::Property< bool > m_scanOnBeginEvent
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
virtual StatusCode retrieveObject(IRegistry *pDirectory, boost::string_ref path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
T clear(T...args)
virtual const std::string & rootName() const =0
Get Name of root Event.
StatusCode initialize() override
Initialize the tool.
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
virtual DataObject * object() const =0
Retrieve object behind the link.
const std::string & name() const override
Retrieve full identifying name of the concrete tool object.
Definition: AlgTool.cpp:62
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
Base class for all Incidents (computing events).
Definition: Incident.h:17
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:92
const LeavesList & leaves() const override
Return the list of collected objects.
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
Opaque address interface definition.
LeavesList m_leaves
Internal cache for the list of objects found during the scan.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
IRegistry * i_getRootNode()
Return the pointer to the IRegistry object associated to the node specified as Root.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
void handle(const Incident &incident) override
Call-back function for the BeginEvent incident.
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:23
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)