| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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"
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 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;
60 bool m_scanOnBeginEvent;
61
63 SmartIF<IIncidentSvc> m_incidentSvc;
65 SmartIF<IDataManagerSvc> m_dataMgrSvc;
67 SmartIF<IDataProviderSvc> m_dataSvc;
68
70 LeavesList m_leaves;
71
73 void i_collectLeaves();
75 void i_collectLeaves(IRegistry *reg);
76
79 IRegistry* i_getRootNode();
80
85 std::string m_initialBase;
86
88 bool m_ignoreOriginChange;
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
102 DataSvcFileEntriesTool::DataSvcFileEntriesTool(const std::string& type,
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
120 DataSvcFileEntriesTool::~DataSvcFileEntriesTool() {}
121
122 StatusCode DataSvcFileEntriesTool::initialize(){
123 StatusCode sc = AlgTool::initialize();
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
135 m_dataMgrSvc = m_dataSvc = serviceLocator()->service(m_dataSvcName);
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
155 StatusCode DataSvcFileEntriesTool::finalize(){
156 // unregister from the incident service
157 if (m_incidentSvc) {
158 m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
159 }
160 // Release the services
161 m_incidentSvc.reset();
162 m_dataMgrSvc.reset();
163 m_dataSvc.reset();
164
165 return AlgTool::finalize();
166 }
167
168 void DataSvcFileEntriesTool::handle(const Incident& incident) {
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
184 const IDataStoreLeaves::LeavesList & DataSvcFileEntriesTool::leaves() const {
185 if (m_leaves.empty()) {
186 const_cast<DataSvcFileEntriesTool*>(this)->i_collectLeaves();
187 }
188 return m_leaves;
189 }
190
191 IRegistry* DataSvcFileEntriesTool::i_getRootNode() {
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
201 void DataSvcFileEntriesTool::i_collectLeaves() {
202 i_collectLeaves(i_getRootNode());
203 }
204
206 void DataSvcFileEntriesTool::i_collectLeaves(IRegistry* reg) {
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",
222 name(), StatusCode::FAILURE);
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"
245 DECLARE_COMPONENT(DataSvcFileEntriesTool)