| # Gaudi Framework, version v21r10p1 |

Home |  | Generated: 29 Jul 2010

# 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 };
    00077
    00078 // ========== implementation
    00079 #include "GaudiKernel/IIncidentSvc.h"
    00080 #include "GaudiKernel/IDataManagerSvc.h"
    00081 #include "GaudiKernel/IDataProviderSvc.h"
    00082 #include "GaudiKernel/IRegistry.h"
    00083 #include "GaudiKernel/IOpaqueAddress.h"
    00084 #include "GaudiKernel/DataObject.h"
    00085 #include "GaudiKernel/DataStoreItem.h"
    00086
    00087 #include "GaudiKernel/GaudiException.h"
    00088
    00089 DataSvcFileEntriesTool::DataSvcFileEntriesTool(const std::string& type,
    00090       const std::string& name,
    00091       const IInterface* parent):
    00092    base_class(type, name, parent) {
    00093
    00094   declareProperty("DataService", m_dataSvcName = "EventDataSvc",
    00095       "Name of the data service to use");
    00096
    00097   declareProperty("Root", m_rootNode,
    00098       "Path to the element from which to start the scan");
    00099
    00100   declareProperty("ScanOnBeginEvent", m_scanOnBeginEvent = false,
    00101       "If the scan has to be started during the BeginEvent incident (true) or on demand (false, default)");
    00102 }
    00103
    00104 DataSvcFileEntriesTool::~DataSvcFileEntriesTool() {}
    00105
    00106 StatusCode DataSvcFileEntriesTool::initialize(){
    00107   StatusCode sc = AlgTool::initialize();
    00108   if (sc.isFailure()) return sc;
    00109
    00110   // Retrieve the pointer to the needed services.
    00111
    00112   m_incidentSvc = serviceLocator()->service("IncidentSvc");
    00113   if ( ! m_incidentSvc ) {
    00114     MsgStream log(msgSvc(), name());
    00115     log << MSG::ERROR << "Cannot get IncidentSvc" << endmsg;
    00116     return StatusCode::FAILURE;
    00117   }
    00118
    00119   m_dataMgrSvc = m_dataSvc = serviceLocator()->service(m_dataSvcName);
    00120   if ( ! m_dataSvc || ! m_dataMgrSvc ) {
    00121     MsgStream log(msgSvc(), name());
    00122     log << MSG::ERROR << "Cannot get IDataProviderSvc+IDataManagerSvc " << m_dataSvcName << endmsg;
    00123     return StatusCode::FAILURE;
    00124   }
    00125
    00126   // Register ourself to the incident service as listener for BeginEvent
    00127   m_incidentSvc->addListener(this, IncidentType::BeginEvent);
    00128
    00129   // If the Root node is not specified, take the name from the data service itself.
    00130   if (m_rootNode.empty()) {
    00131     m_rootNode = m_dataMgrSvc->rootName();
    00132   }
    00133
    00134   // Clear the cache (in case the instance is re-initilized).
    00135   m_leaves.clear();
    00136   return StatusCode::SUCCESS;
    00137 }
    00138
    00139 StatusCode DataSvcFileEntriesTool::finalize(){
    00140   // unregister from the incident service
    00141   if (m_incidentSvc) {
    00142     m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
    00143   }
    00144   // Release the services
    00145   m_incidentSvc.reset();
    00146   m_dataMgrSvc.reset();
    00147   m_dataSvc.reset();
    00148
    00149   return AlgTool::finalize();
    00150 }
    00151
    00152 void DataSvcFileEntriesTool::handle(const Incident& incident) {
    00153   m_leaves.clear();
    00154   if (m_scanOnBeginEvent) {
    00155     MsgStream log(msgSvc(), name());
    00156     log << MSG::VERBOSE << "::handle scanning on " << incident.type() << endmsg;
    00157     i_collectLeaves();
    00158   }
    00159 }
    00160
    00161 const IDataStoreLeaves::LeavesList & DataSvcFileEntriesTool::leaves() const {
    00162   if (m_leaves.empty()) {
    00163     const_cast<DataSvcFileEntriesTool*>(this)->i_collectLeaves();
    00164   }
    00165   return m_leaves;
    00166 }
    00167
    00168 void DataSvcFileEntriesTool::i_collectLeaves() {
    00169   DataObject * obj = 0;
    00170   StatusCode sc = m_dataSvc->retrieveObject(m_rootNode, obj);
    00171   if (sc.isSuccess()) {
    00172     MsgStream log(msgSvc(), name());
    00173     log << MSG::DEBUG << "::i_collectLeaves scanning " << m_dataSvcName
    00174         << " from " << m_rootNode << endmsg;
    00175     i_collectLeaves(obj->registry());
    00176   } else {
    00177     throw GaudiException("Cannot get " + m_rootNode + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
    00178   }
    00179 }
    00180
    00182 void DataSvcFileEntriesTool::i_collectLeaves(IRegistry* reg) {
    00183   MsgStream log(msgSvc(), name());
    00184   // I do not put sanity checks on the pointers because I know how I'm calling the function
    00185   IOpaqueAddress *addr = reg->address();
    00186   if (addr) { // we consider only objects that are in a file
    00187     if (outputLevel() <= MSG::VERBOSE)
    00188       log << MSG::VERBOSE << "::i_collectLeaves added " << reg->identifier() << endmsg;
    00189     m_leaves.push_back(reg->object()); // add this object
    00190     // Origin of the current object
    00191     const std::string& base = addr->par()[0];
    00192
    00193     std::vector<IRegistry*> lfs; // leaves of the current object
    00194     StatusCode sc = m_dataMgrSvc->objectLeaves(reg, lfs);
    00195     if (sc.isSuccess()) {
    00196       for(std::vector<IRegistry*>::iterator i = lfs.begin(); i != lfs.end(); ++i)  {
    00197         // Continue if the leaf has the same database as the parent
    00198         if ( (*i)->address() && (*i)->address()->par()[0] == base )  {
    00199           DataObject* obj = 0;
    00200           sc = m_dataSvc->retrieveObject(reg, (*i)->name(), obj);
    00201           if (sc.isSuccess())  {
    00202             i_collectLeaves(*i);
    00203           } else {
    00204             throw GaudiException("Cannot get " + (*i)->identifier() + " from " + m_dataSvcName, name(), StatusCode::FAILURE);
    00205           }
    00206         }
    00207       }
    00208     }
    00209   }
    00210 }
    00211
    00212
    00213 #include "GaudiKernel/ToolFactory.h"
    00214 DECLARE_TOOL_FACTORY(DataSvcFileEntriesTool)