DataSvcFileEntriesTool.cpp
Go to the documentation of this file.
1 // ========== header
2 #include "GaudiKernel/AlgTool.h"
3 #include "GaudiKernel/IDataStoreLeaves.h"
4 #include "GaudiKernel/IIncidentListener.h"
5 #include "GaudiKernel/SmartIF.h"
6 
7 class IIncidentSvc;
8 class IDataManagerSvc;
9 class IDataProviderSvc;
10 class IRegistry;
26 class DataSvcFileEntriesTool: public extends2<AlgTool, IDataStoreLeaves, IIncidentListener> {
27 public:
29  DataSvcFileEntriesTool(const std::string& type,
30  const std::string& name,
31  const IInterface* parent);
32 
34  ~DataSvcFileEntriesTool() override = default;
35 
37  StatusCode initialize() override;
38 
40  StatusCode finalize() override;
41 
46  const LeavesList & leaves() const override;
47 
51  void handle(const Incident& incident) override;
52 
53 private:
54 
56  std::string m_dataSvcName;
58  std::string m_rootNode;
61 
68 
70  LeavesList m_leaves;
71 
73  void i_collectLeaves();
75  void i_collectLeaves(IRegistry *reg);
76 
80 
85  std::string m_initialBase;
86 
89 };
90 
91 // ========== implementation
92 #include "GaudiKernel/IIncidentSvc.h"
93 #include "GaudiKernel/IDataManagerSvc.h"
94 #include "GaudiKernel/IDataProviderSvc.h"
95 #include "GaudiKernel/IRegistry.h"
96 #include "GaudiKernel/IOpaqueAddress.h"
97 #include "GaudiKernel/DataObject.h"
98 #include "GaudiKernel/DataStoreItem.h"
99 
100 #include "GaudiKernel/GaudiException.h"
101 
103  const std::string& name,
104  const IInterface* parent):
105  base_class(type, name, parent) {
106 
107  declareProperty("DataService", m_dataSvcName = "EventDataSvc",
108  "Name of the data service to use");
109 
110  declareProperty("Root", m_rootNode,
111  "Path to the element from which to start the scan");
112 
113  declareProperty("ScanOnBeginEvent", m_scanOnBeginEvent = false,
114  "If the scan has to be started during the BeginEvent incident (true) or on demand (false, default)");
115 
116  declareProperty("IgnoreOriginChange", m_ignoreOriginChange = false,
117  "Disable the detection of the change in the origin of object between the BeginEvent and the scan");
118 }
119 
122  if (sc.isFailure()) return sc;
123 
124  // Retrieve the pointer to the needed services.
125 
126  m_incidentSvc = serviceLocator()->service("IncidentSvc");
127  if ( ! m_incidentSvc ) {
128  MsgStream log(msgSvc(), name());
129  log << MSG::ERROR << "Cannot get IncidentSvc" << endmsg;
130  return StatusCode::FAILURE;
131  }
132 
133  m_dataMgrSvc = m_dataSvc = serviceLocator()->service(m_dataSvcName);
134  if ( ! m_dataSvc || ! m_dataMgrSvc ) {
135  MsgStream log(msgSvc(), name());
136  log << MSG::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  MsgStream log(msgSvc(), name());
177  log << MSG::VERBOSE << "::handle scanning on " << incident.type() << endmsg;
178  i_collectLeaves();
179  }
180 }
181 
183  if (m_leaves.empty()) {
184  const_cast<DataSvcFileEntriesTool*>(this)->i_collectLeaves();
185  }
186  return m_leaves;
187 }
188 
190  DataObject * obj = nullptr;
192  if (sc.isFailure()) {
193  throw GaudiException("Cannot get " + m_rootNode + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
194  }
195  return obj->registry();
196 }
197 
198 
201 }
202 
205  MsgStream log(msgSvc(), name());
206  // I do not put sanity checks on the pointers because I know how I'm calling the function
207  IOpaqueAddress *addr = reg->address();
208  if (addr) { // we consider only objects that are in a file
209  if (outputLevel() <= MSG::VERBOSE)
210  log << MSG::VERBOSE << "::i_collectLeaves added " << reg->identifier() << endmsg;
211  m_leaves.push_back(reg->object()); // add this object
212  // Origin of the current object
213  const std::string& base = addr->par()[0];
214  // Compare with the origin seen during BeginEvent
215  if ( !m_ignoreOriginChange && (m_initialBase != base) )
216  throw GaudiException("Origin of data has changed ('"
217  + m_initialBase + "' != '" + base
218  + "'), probably OutputStream was called before "
219  "InputCopyStream: check options",
221 
222  std::vector<IRegistry*> lfs; // leaves of the current object
223  StatusCode sc = m_dataMgrSvc->objectLeaves(reg, lfs);
224  if (sc.isSuccess()) {
225  for(const auto& i : lfs) {
226  // Continue if the leaf has the same database as the parent
227  if ( i->address() && i->address()->par()[0] == base ) {
228  DataObject* obj = nullptr;
229  sc = m_dataSvc->retrieveObject(reg, i->name(), obj);
230  if (sc.isSuccess()) {
232  } else {
233  throw GaudiException("Cannot get " + i->identifier() + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
234  }
235  }
236  }
237  }
238  }
239 }
240 
241 
virtual const std::string * par() const =0
Retrieve String parameters.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
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.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
const std::string & type() const
Access to the incident type.
Definition: Incident.h:34
StatusCode initialize() override
Definition: AlgTool.cpp:325
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
bool m_scanOnBeginEvent
Variable for the property ScanOnBeginEvent.
std::vector< DataObject * > LeavesList
Returned type.
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...
SmartIF< IDataManagerSvc > m_dataMgrSvc
Pointer to the IDataManagerSvc interface of the data service.
StatusCode finalize() override
Definition: AlgTool.cpp:395
StatusCode finalize() override
Finalize the tool.
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
~DataSvcFileEntriesTool() override=default
Destructor.
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
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
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:16
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
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.
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.
IRegistry * i_getRootNode()
Return the pointer to the IRegistry object associated to the node specified as Root.
void handle(const Incident &incident) override
Call-back function for the BeginEvent incident.
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:21
string type
Definition: gaudirun.py:151
virtual StatusCode retrieveObject(IRegistry *pDirectory, const std::string &path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.