All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 extends2<AlgTool, IDataStoreLeaves, IIncidentListener> {
27 public:
29  DataSvcFileEntriesTool(const std::string& type,
30  const std::string& name,
31  const IInterface* parent);
32 
34  virtual ~DataSvcFileEntriesTool();
35 
37  virtual StatusCode initialize();
38 
40  virtual StatusCode finalize();
41 
46  virtual const LeavesList & leaves() const;
47 
51  virtual void handle(const Incident& incident);
52 
53 private:
54 
56  std::string m_dataSvcName;
58  std::string m_rootNode;
61 
68 
71 
73  void i_collectLeaves();
75  void i_collectLeaves(IRegistry *reg);
76 
80 
85  std::string m_initialBase;
86 
89 };
90 
91 // ========== implementation
95 #include "GaudiKernel/IRegistry.h"
97 #include "GaudiKernel/DataObject.h"
99 
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 
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  MsgStream log(msgSvc(), name());
131  log << MSG::ERROR << "Cannot get IncidentSvc" << endmsg;
132  return StatusCode::FAILURE;
133  }
134 
136  if ( ! m_dataSvc || ! m_dataMgrSvc ) {
137  MsgStream log(msgSvc(), name());
138  log << MSG::ERROR << "Cannot get IDataProviderSvc+IDataManagerSvc " << m_dataSvcName << endmsg;
139  return StatusCode::FAILURE;
140  }
141 
142  // Register ourself to the incident service as listener for BeginEvent
143  m_incidentSvc->addListener(this, IncidentType::BeginEvent);
144 
145  // If the Root node is not specified, take the name from the data service itself.
146  if (m_rootNode.empty()) {
147  m_rootNode = m_dataMgrSvc->rootName();
148  }
149 
150  // Clear the cache (in case the instance is re-initilized).
151  m_leaves.clear();
152  return StatusCode::SUCCESS;
153 }
154 
156  // unregister from the incident service
157  if (m_incidentSvc) {
158  m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
159  }
160  // Release the services
163  m_dataSvc.reset();
164 
165  return AlgTool::finalize();
166 }
167 
169  // Get the file id of the root node at every event
170  IOpaqueAddress *addr = i_getRootNode()->address();
171  if (addr)
172  m_initialBase = addr->par()[0];
173  else
174  m_initialBase.clear(); // use empty file id if there is no address
175 
176  m_leaves.clear();
177  if (m_scanOnBeginEvent) {
178  MsgStream log(msgSvc(), name());
179  log << MSG::VERBOSE << "::handle scanning on " << incident.type() << endmsg;
180  i_collectLeaves();
181  }
182 }
183 
185  if (m_leaves.empty()) {
186  const_cast<DataSvcFileEntriesTool*>(this)->i_collectLeaves();
187  }
188  return m_leaves;
189 }
190 
192  DataObject * obj = 0;
193  StatusCode sc = m_dataSvc->retrieveObject(m_rootNode, obj);
194  if (sc.isFailure()) {
195  throw GaudiException("Cannot get " + m_rootNode + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
196  }
197  return obj->registry();
198 }
199 
200 
203 }
204 
207  MsgStream log(msgSvc(), name());
208  // I do not put sanity checks on the pointers because I know how I'm calling the function
209  IOpaqueAddress *addr = reg->address();
210  if (addr) { // we consider only objects that are in a file
211  if (outputLevel() <= MSG::VERBOSE)
212  log << MSG::VERBOSE << "::i_collectLeaves added " << reg->identifier() << endmsg;
213  m_leaves.push_back(reg->object()); // add this object
214  // Origin of the current object
215  const std::string& base = addr->par()[0];
216  // Compare with the origin seen during BeginEvent
217  if ( !m_ignoreOriginChange && (m_initialBase != base) )
218  throw GaudiException("Origin of data has changed ('"
219  + m_initialBase + "' != '" + base
220  + "'), probably OutputStream was called before "
221  "InputCopyStream: check options",
223 
224  std::vector<IRegistry*> lfs; // leaves of the current object
225  StatusCode sc = m_dataMgrSvc->objectLeaves(reg, lfs);
226  if (sc.isSuccess()) {
227  for(std::vector<IRegistry*>::iterator i = lfs.begin(); i != lfs.end(); ++i) {
228  // Continue if the leaf has the same database as the parent
229  if ( (*i)->address() && (*i)->address()->par()[0] == base ) {
230  DataObject* obj = 0;
231  sc = m_dataSvc->retrieveObject(reg, (*i)->name(), obj);
232  if (sc.isSuccess()) {
233  i_collectLeaves(*i);
234  } else {
235  throw GaudiException("Cannot get " + (*i)->identifier() + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
236  }
237  }
238  }
239  }
240  }
241 }
242 
243 
244 #include "GaudiKernel/ToolFactory.h"
const std::string BeginEvent
Processing of a new event has started.
Definition: Incident.h:60
virtual ~DataSvcFileEntriesTool()
Destructor.
virtual const std::string * par() const =0
Retrieve String parameters.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
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:34
virtual const std::string & type() const
Retrieve type (concrete class) of the sub-algtool.
Definition: AlgTool.cpp:58
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
Definition: AlgTool.cpp:434
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:62
bool m_scanOnBeginEvent
Variable for the property ScanOnBeginEvent.
virtual const name_type & name() const =0
Name of the directory (or key)
Base class used to extend a class implementing other interfaces.
Definition: extends.h:75
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:72
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:69
ISvcLocator * serviceLocator() const
Retrieve pointer to service locator.
Definition: AlgTool.cpp:72
virtual StatusCode finalize()
Finalize the tool.
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.
virtual const LeavesList & leaves() const
Return the list of collected objects.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:82
string type
Definition: gaudirun.py:126
IMessageSvc * msgSvc() const
Retrieve pointer to message service.
Definition: AlgTool.cpp:79
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:30
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: AlgTool.h:234
Definition of the basic interface.
Definition: IInterface.h:160
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
virtual DataObject * object() const =0
Retrieve object behind the link.
std::string m_dataSvcName
Variable for the property DataService.
Base class for all Incidents (computing events).
Definition: Incident.h:16
int outputLevel() const
get tool's output level
Definition: AlgTool.h:305
virtual const IInterface * parent() const
Retrieve parent of the sub-algtool.
Definition: AlgTool.cpp:65
virtual const id_type & identifier() const =0
Full identifier (or key)
DataSvcFileEntriesTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard constructor.
virtual StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
Definition: AlgTool.cpp:307
Opaque address interface definition.
virtual StatusCode initialize()
Initialize the tool.
LeavesList m_leaves
Internal cache for the list of objects found during the scan.
virtual const std::string & name() const
Retrieve full identifying name of the concrete tool object.
Definition: AlgTool.cpp:51
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:31
list i
Definition: ana.py:128
std::string m_rootNode
Variable for the property Root.
virtual void handle(const Incident &incident)
Call-back function for the BeginEvent incident.
void reset(TYPE *ptr=0)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:74
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
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:22