VFSSvc.cpp
Go to the documentation of this file.
1 #include "VFSSvc.h"
2 
3 #include "GaudiKernel/MsgStream.h"
4 #include "GaudiKernel/IToolSvc.h"
5 #include "GaudiKernel/IAlgTool.h"
6 
8 
9 //------------------------------------------------------------------------------
10 VFSSvc::VFSSvc(const std::string& name, ISvcLocator* svc):
11  base_class(name,svc)
12 {
13  declareProperty("FileAccessTools",m_urlHandlersNames,
14  "List of tools implementing the IFileAccess interface.");
15 
16  declareProperty("FallBackProtocol",m_fallBackProtocol = "file",
17  "URL prefix to use if the prefix is not present.");
18 }
19 //------------------------------------------------------------------------------
22  if (sc.isFailure()) return sc;
23 
24  MsgStream log(msgSvc(), name());
25 
26  m_toolSvc = serviceLocator()->service("ToolSvc");
27  if (!m_toolSvc){
28  log << MSG::ERROR << "Cannot locate ToolSvc" << endmsg;
29  return StatusCode::FAILURE;
30  }
31 
32  IAlgTool *tool;
33  for(const auto& i : m_urlHandlersNames) {
34  // retrieve the tool and the pointer to the interface
35  sc = m_toolSvc->retrieve(i,IAlgTool::interfaceID(),tool,0,true);
36  if (sc.isFailure()){
37  log << MSG::ERROR << "Cannot get tool " << i << endmsg;
38  return sc;
39  }
40  m_acquiredTools.push_back(tool); // this is one tool that we will have to release
41  auto hndlr = SmartIF<IFileAccess>(tool);
42  if (!hndlr){
43  log << MSG::ERROR << i << " does not implement IFileAccess" << endmsg;
44  return StatusCode::FAILURE;
45  }
46  // We do not need to increase the reference count for the IFileAccess interface
47  // because we hold the tool by its IAlgTool interface.
48  // loop over the list of supported protocols and add them to the map (for quick access)
49  for ( const auto& prot : hndlr->protocols() ) m_urlHandlers[prot] = hndlr.get();
50  }
51 
52  // Now let's check if we can handle the fallback protocol
54  log << MSG::ERROR << "No handler specified for fallback protocol prefix "
56  return StatusCode::FAILURE;
57  }
58 
59  // Note: the list of handled protocols will be filled only if requested
60 
61  return sc;
62 }
63 //------------------------------------------------------------------------------
65  m_urlHandlers.clear(); // clear the map
66  m_protocols.clear();
67 
68  if (m_toolSvc) {
69  // release the acquired tools (from the last acquired one)
70  while ( !m_acquiredTools.empty() ){
71  m_toolSvc->releaseTool(m_acquiredTools.back()).ignore();
72  m_acquiredTools.pop_back();
73  }
74  m_toolSvc.reset() ; // release the tool service
75  }
76  return Service::finalize();
77 }
78 //------------------------------------------------------------------------------
79 std::unique_ptr<std::istream> VFSSvc::open(const std::string &url){
80 
81  // get the url prefix endpos
82  auto pos = url.find("://");
83 
84  if (std::string::npos == pos) { // no url prefix
85  return m_urlHandlers[m_fallBackProtocol]->open(url);
86  }
87 
88  std::string url_prefix(url,0,pos);
89  if ( m_urlHandlers.find(url_prefix) == m_urlHandlers.end() ) {
90  // if we do not have a handler for the URL prefix,
91  // use the fall back one and pass only the path
92  return m_urlHandlers[m_fallBackProtocol]->open(url.substr(pos+3));
93  }
94  return m_urlHandlers[url_prefix]->open(url);
95 }
96 //------------------------------------------------------------------------------
97 namespace {
100  constexpr struct select1st_t
101  {
102  template <typename S, typename T>
103  const S& operator() (const std::pair<S,T> &x) const { return x.first; }
104  } select1st {} ;
105 }
106 
107 const std::vector<std::string> &VFSSvc::protocols() const
108 {
109  if (m_protocols.empty()){
110  // prepare the list of handled protocols
111  std::transform( m_urlHandlers.begin(),m_urlHandlers.end(),
112  std::back_inserter(const_cast<VFSSvc*>(this)->m_protocols),
113  select1st );
114  }
115  return m_protocols;
116 }
SmartIF< IToolSvc > m_toolSvc
Handle to the tool service.
Definition: VFSSvc.h:59
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:62
virtual StatusCode retrieve(const std::string &type, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent=0, bool createIf=true)=0
Retrieve tool with tool dependent part of the name automatically assigned.
std::unique_ptr< std::istream > open(const std::string &url) override
Definition: VFSSvc.cpp:79
std::vector< std::string > m_protocols
Protocols registered.
Definition: VFSSvc.h:50
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
StatusCode finalize() override
Definition: Service.cpp:187
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode initialize() override
Initialize Service.
Definition: VFSSvc.cpp:20
constexpr struct select1st_t select1st
STL namespace.
std::string m_fallBackProtocol
Protocol to use in case there is not a specific tool to handle the URL.
Definition: VFSSvc.h:53
GaudiUtils::HashMap< std::string, IFileAccess * > m_urlHandlers
Map of the tools handling the known protocols.
Definition: VFSSvc.h:56
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
iterator end()
Definition: Map.h:132
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
iterator find(const key_type &key)
Definition: Map.h:149
prot
Definition: ana.py:53
iterator begin()
Definition: Map.h:131
StatusCode finalize() override
Finalize Service.
Definition: VFSSvc.cpp:64
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
std::vector< IAlgTool * > m_acquiredTools
List of acquired tools (needed to release them).
Definition: VFSSvc.h:62
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:22
void clear()
Definition: Map.h:178
virtual StatusCode releaseTool(IAlgTool *tool)=0
Release the tool.
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:88
Simple service that allows to read files independently from the storage.
Definition: VFSSvc.h:26
const std::vector< std::string > & protocols() const override
Definition: VFSSvc.cpp:107
list i
Definition: ana.py:128
std::vector< std::string > m_urlHandlersNames
Names of the handlers to use.
Definition: VFSSvc.h:47