Gaudi Framework, version v23r2

Home   Generated: Thu Jun 28 2012

DataSvcFileEntriesTool.cpp

Go to the documentation of this file.
00001 // ========== header
00002 #include "GaudiKernel/AlgTool.h"
00003 #include "GaudiKernel/IDataStoreLeaves.h"
00004 #include "GaudiKernel/IIncidentListener.h"
00005 #include "GaudiKernel/SmartIF.h"
00006 
00007 class IIncidentSvc;
00008 class IDataManagerSvc;
00009 class IDataProviderSvc;
00010 class IRegistry;
00026 class DataSvcFileEntriesTool: public extends2<AlgTool, IDataStoreLeaves, IIncidentListener> {
00027 public:
00029   DataSvcFileEntriesTool(const std::string& type,
00030       const std::string& name,
00031       const IInterface* parent);
00032 
00034   virtual ~DataSvcFileEntriesTool();
00035 
00037   virtual StatusCode initialize();
00038 
00040   virtual StatusCode finalize();
00041 
00046   virtual const LeavesList & leaves() const;
00047 
00051   virtual void handle(const Incident& incident);
00052 
00053 private:
00054 
00056   std::string m_dataSvcName;
00058   std::string m_rootNode;
00060   bool m_scanOnBeginEvent;
00061 
00063   SmartIF<IIncidentSvc> m_incidentSvc;
00065   SmartIF<IDataManagerSvc> m_dataMgrSvc;
00067   SmartIF<IDataProviderSvc> m_dataSvc;
00068 
00070   LeavesList m_leaves;
00071 
00073   void i_collectLeaves();
00075   void i_collectLeaves(IRegistry *reg);
00076 
00079   IRegistry* i_getRootNode();
00080 
00085   std::string m_initialBase;
00086 
00088   bool m_ignoreOriginChange;
00089 };
00090 
00091 // ========== implementation
00092 #include "GaudiKernel/IIncidentSvc.h"
00093 #include "GaudiKernel/IDataManagerSvc.h"
00094 #include "GaudiKernel/IDataProviderSvc.h"
00095 #include "GaudiKernel/IRegistry.h"
00096 #include "GaudiKernel/IOpaqueAddress.h"
00097 #include "GaudiKernel/DataObject.h"
00098 #include "GaudiKernel/DataStoreItem.h"
00099 
00100 #include "GaudiKernel/GaudiException.h"
00101 
00102 DataSvcFileEntriesTool::DataSvcFileEntriesTool(const std::string& type,
00103       const std::string& name,
00104       const IInterface* parent):
00105    base_class(type, name, parent) {
00106 
00107   declareProperty("DataService", m_dataSvcName = "EventDataSvc",
00108       "Name of the data service to use");
00109 
00110   declareProperty("Root", m_rootNode,
00111       "Path to the element from which to start the scan");
00112 
00113   declareProperty("ScanOnBeginEvent", m_scanOnBeginEvent = false,
00114       "If the scan has to be started during the BeginEvent incident (true) or on demand (false, default)");
00115 
00116   declareProperty("IgnoreOriginChange", m_ignoreOriginChange = false,
00117       "Disable the detection of the change in the origin of object between the BeginEvent and the scan");
00118 }
00119 
00120 DataSvcFileEntriesTool::~DataSvcFileEntriesTool() {}
00121 
00122 StatusCode DataSvcFileEntriesTool::initialize(){
00123   StatusCode sc = AlgTool::initialize();
00124   if (sc.isFailure()) return sc;
00125 
00126   // Retrieve the pointer to the needed services.
00127 
00128   m_incidentSvc = serviceLocator()->service("IncidentSvc");
00129   if ( ! m_incidentSvc ) {
00130     MsgStream log(msgSvc(), name());
00131     log << MSG::ERROR << "Cannot get IncidentSvc" << endmsg;
00132     return StatusCode::FAILURE;
00133   }
00134 
00135   m_dataMgrSvc = m_dataSvc = serviceLocator()->service(m_dataSvcName);
00136   if ( ! m_dataSvc || ! m_dataMgrSvc ) {
00137     MsgStream log(msgSvc(), name());
00138     log << MSG::ERROR << "Cannot get IDataProviderSvc+IDataManagerSvc " << m_dataSvcName << endmsg;
00139     return StatusCode::FAILURE;
00140   }
00141 
00142   // Register ourself to the incident service as listener for BeginEvent
00143   m_incidentSvc->addListener(this, IncidentType::BeginEvent);
00144 
00145   // If the Root node is not specified, take the name from the data service itself.
00146   if (m_rootNode.empty()) {
00147     m_rootNode = m_dataMgrSvc->rootName();
00148   }
00149 
00150   // Clear the cache (in case the instance is re-initilized).
00151   m_leaves.clear();
00152   return StatusCode::SUCCESS;
00153 }
00154 
00155 StatusCode DataSvcFileEntriesTool::finalize(){
00156   // unregister from the incident service
00157   if (m_incidentSvc) {
00158     m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
00159   }
00160   // Release the services
00161   m_incidentSvc.reset();
00162   m_dataMgrSvc.reset();
00163   m_dataSvc.reset();
00164 
00165   return AlgTool::finalize();
00166 }
00167 
00168 void DataSvcFileEntriesTool::handle(const Incident& incident) {
00169   // Get the file id of the root node at every event
00170   IOpaqueAddress *addr = i_getRootNode()->address();
00171   if (addr)
00172     m_initialBase = addr->par()[0];
00173   else
00174     m_initialBase.clear(); // use empty file id if there is no address
00175 
00176   m_leaves.clear();
00177   if (m_scanOnBeginEvent) {
00178     MsgStream log(msgSvc(), name());
00179     log << MSG::VERBOSE << "::handle scanning on " << incident.type() << endmsg;
00180     i_collectLeaves();
00181   }
00182 }
00183 
00184 const IDataStoreLeaves::LeavesList & DataSvcFileEntriesTool::leaves() const {
00185   if (m_leaves.empty()) {
00186     const_cast<DataSvcFileEntriesTool*>(this)->i_collectLeaves();
00187   }
00188   return m_leaves;
00189 }
00190 
00191 IRegistry* DataSvcFileEntriesTool::i_getRootNode() {
00192   DataObject * obj = 0;
00193   StatusCode sc = m_dataSvc->retrieveObject(m_rootNode, obj);
00194   if (sc.isFailure()) {
00195     throw GaudiException("Cannot get " + m_rootNode + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
00196   }
00197   return obj->registry();
00198 }
00199 
00200 
00201 void DataSvcFileEntriesTool::i_collectLeaves() {
00202   i_collectLeaves(i_getRootNode());
00203 }
00204 
00206 void DataSvcFileEntriesTool::i_collectLeaves(IRegistry* reg) {
00207   MsgStream log(msgSvc(), name());
00208   // I do not put sanity checks on the pointers because I know how I'm calling the function
00209   IOpaqueAddress *addr = reg->address();
00210   if (addr) { // we consider only objects that are in a file
00211     if (outputLevel() <= MSG::VERBOSE)
00212       log << MSG::VERBOSE << "::i_collectLeaves added " << reg->identifier() << endmsg;
00213     m_leaves.push_back(reg->object()); // add this object
00214     // Origin of the current object
00215     const std::string& base = addr->par()[0];
00216     // Compare with the origin seen during BeginEvent
00217     if ( !m_ignoreOriginChange && (m_initialBase != base) )
00218       throw GaudiException("Origin of data has changed ('"
00219                            + m_initialBase + "' !=  '" + base
00220                            + "'), probably OutputStream was called before "
00221                                "InputCopyStream: check options",
00222                            name(), StatusCode::FAILURE);
00223 
00224     std::vector<IRegistry*> lfs; // leaves of the current object
00225     StatusCode sc = m_dataMgrSvc->objectLeaves(reg, lfs);
00226     if (sc.isSuccess()) {
00227       for(std::vector<IRegistry*>::iterator i = lfs.begin(); i != lfs.end(); ++i)  {
00228         // Continue if the leaf has the same database as the parent
00229         if ( (*i)->address() && (*i)->address()->par()[0] == base )  {
00230           DataObject* obj = 0;
00231           sc = m_dataSvc->retrieveObject(reg, (*i)->name(), obj);
00232           if (sc.isSuccess())  {
00233             i_collectLeaves(*i);
00234           } else {
00235             throw GaudiException("Cannot get " + (*i)->identifier() + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
00236           }
00237         }
00238       }
00239     }
00240   }
00241 }
00242 
00243 
00244 #include "GaudiKernel/ToolFactory.h"
00245 DECLARE_TOOL_FACTORY(DataSvcFileEntriesTool)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Thu Jun 28 2012 23:27:16 for Gaudi Framework, version v23r2 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004