| # Gaudi Framework, version v22r0 |

Home |  | Generated: 9 Feb 2011

# 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