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 class IDataManagerSvc;
9 class IDataProviderSvc;
10 class IRegistry;
26 class DataSvcFileEntriesTool: public extends<AlgTool,
27  IDataStoreLeaves,
28  IIncidentListener> {
29 public:
32  const std::string& name,
33  const IInterface* parent);
34 
36  ~DataSvcFileEntriesTool() override = default;
37 
39  StatusCode initialize() override;
40 
42  StatusCode finalize() override;
43 
48  const LeavesList & leaves() const override;
49 
53  void handle(const Incident& incident) override;
54 
55 private:
56 
63 
70 
72  LeavesList m_leaves;
73 
75  void i_collectLeaves();
77  void i_collectLeaves(IRegistry *reg);
78 
82 
88 
91 };
92 
93 // ========== implementation
97 #include "GaudiKernel/IRegistry.h"
99 #include "GaudiKernel/DataObject.h"
101 
103 
105  const std::string& name,
106  const IInterface* parent):
107  base_class(type, name, parent) {
108 
109  declareProperty("DataService", m_dataSvcName = "EventDataSvc",
110  "Name of the data service to use");
111 
112  declareProperty("Root", m_rootNode,
113  "Path to the element from which to start the scan");
114 
115  declareProperty("ScanOnBeginEvent", m_scanOnBeginEvent = false,
116  "If the scan has to be started during the BeginEvent incident (true) or on demand (false, default)");
117 
118  declareProperty("IgnoreOriginChange", m_ignoreOriginChange = false,
119  "Disable the detection of the change in the origin of object between the BeginEvent and the scan");
120 }
121 
124  if (sc.isFailure()) return sc;
125 
126  // Retrieve the pointer to the needed services.
127 
128  m_incidentSvc = serviceLocator()->service("IncidentSvc");
129  if ( ! m_incidentSvc ) {
130  error() << "Cannot get IncidentSvc" << endmsg;
131  return StatusCode::FAILURE;
132  }
133 
135  if ( ! m_dataSvc || ! m_dataMgrSvc ) {
136  error() << "Cannot get IDataProviderSvc+IDataManagerSvc " << m_dataSvcName << endmsg;
137  return StatusCode::FAILURE;
138  }
139 
140  // Register ourself to the incident service as listener for BeginEvent
141  m_incidentSvc->addListener(this, IncidentType::BeginEvent);
142 
143  // If the Root node is not specified, take the name from the data service itself.
144  if (m_rootNode.empty()) {
146  }
147 
148  // Clear the cache (in case the instance is re-initilized).
149  m_leaves.clear();
150  return StatusCode::SUCCESS;
151 }
152 
154  // unregister from the incident service
155  if (m_incidentSvc) {
156  m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
157  }
158  // Release the services
161  m_dataSvc.reset();
162 
163  return AlgTool::finalize();
164 }
165 
167  // Get the file id of the root node at every event
168  IOpaqueAddress *addr = i_getRootNode()->address();
169  if (addr)
170  m_initialBase = addr->par()[0];
171  else
172  m_initialBase.clear(); // use empty file id if there is no address
173 
174  m_leaves.clear();
175  if (m_scanOnBeginEvent) {
176  verbose() << "::handle scanning on " << incident.type() << endmsg;
177  i_collectLeaves();
178  }
179 }
180 
182  if (m_leaves.empty()) {
183  const_cast<DataSvcFileEntriesTool*>(this)->i_collectLeaves();
184  }
185  return m_leaves;
186 }
187 
189  DataObject * obj = nullptr;
191  if (sc.isFailure()) {
192  throw GaudiException("Cannot get " + m_rootNode + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
193  }
194  return obj->registry();
195 }
196 
197 
200 }
201 
204  // I do not put sanity checks on the pointers because I know how I'm calling the function
205  IOpaqueAddress *addr = reg->address();
206  if (addr) { // we consider only objects that are in a file
207  if (msgLevel(MSG::VERBOSE))
208  verbose() << "::i_collectLeaves added " << reg->identifier() << endmsg;
209  m_leaves.push_back(reg->object()); // add this object
210  // Origin of the current object
211  const std::string& base = addr->par()[0];
212  // Compare with the origin seen during BeginEvent
213  if ( !m_ignoreOriginChange && (m_initialBase != base) )
214  throw GaudiException("Origin of data has changed ('"
215  + m_initialBase + "' != '" + base
216  + "'), probably OutputStream was called before "
217  "InputCopyStream: check options",
219 
220  std::vector<IRegistry*> lfs; // leaves of the current object
221  StatusCode sc = m_dataMgrSvc->objectLeaves(reg, lfs);
222  if (sc.isSuccess()) {
223  for(const auto& i : lfs) {
224  // Continue if the leaf has the same database as the parent
225  if ( i->address() && i->address()->par()[0] == base ) {
226  DataObject* obj = nullptr;
227  sc = m_dataSvc->retrieveObject(reg, i->name(), obj);
228  if (sc.isSuccess()) {
230  } else {
231  throw GaudiException("Cannot get " + i->identifier() + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
232  }
233  }
234  }
235  }
236  }
237 }
238 
239 
virtual const std::string * par() const =0
Retrieve String parameters.
T empty(T...args)
const LeavesList & leaves() const override
Return the list of collected objects.
bool m_ignoreOriginChange
Variable for the property ScanOnBeginEvent.
Define general base for Gaudi exception.
const std::string & type() const
Access to the incident type.
Definition: Incident.h:41
StatusCode initialize() override
Definition: AlgTool.cpp:290
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
bool m_scanOnBeginEvent
Variable for the property ScanOnBeginEvent.
Data provider interface definition.
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
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
Test for a status code of FAILURE.
Definition: StatusCode.h:86
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:74
Tool to scan a transient store branch that collects all the objects that belong to the same source (f...
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
SmartIF< IDataManagerSvc > m_dataMgrSvc
Pointer to the IDataManagerSvc interface of the data service.
STL class.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: AlgTool.cpp:86
StatusCode finalize() override
Definition: AlgTool.cpp:360
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:78
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
StatusCode finalize() override
Finalize the tool.
string type
Definition: gaudirun.py:151
void i_collectLeaves()
Scan the data service starting from the node specified as Root.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: AlgTool.h:249
~DataSvcFileEntriesTool() override=default
Destructor.
Definition of the basic interface.
Definition: IInterface.h:234
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
T clear(T...args)
virtual const std::string & rootName() const =0
Get Name of root Event.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
virtual DataObject * object() const =0
Retrieve object behind the link.
StatusCode initialize() override
Initialize the tool.
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 ...
std::string m_dataSvcName
Variable for the property DataService.
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.
const std::string & type() const override
Retrieve type (concrete class) of the sub-algtool.
Definition: AlgTool.cpp:72
virtual const id_type & identifier() const =0
Full identifier (or key)
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:88
DataSvcFileEntriesTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard constructor.
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.
MSG::Level msgLevel() const
get the output level from the embedded MsgStream
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
list i
Definition: ana.py:128
std::string m_rootNode
Variable for the property Root.
const std::string & name() const override
Retrieve full identifying name of the concrete tool object.
Definition: AlgTool.cpp:65
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:244
void handle(const Incident &incident) override
Call-back function for the BeginEvent incident.
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:21
virtual StatusCode retrieveObject(IRegistry *pDirectory, const std::string &path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
const IInterface * parent() const override
Retrieve parent of the sub-algtool.
Definition: AlgTool.cpp:79