| # Gaudi Framework, version v21r10p1 |

Home |  | Generated: 29 Jul 2010

# VFSSvc.cpp

Go to the documentation of this file.

    00001 #include "VFSSvc.h"
    00002
    00003 #include "GaudiKernel/MsgStream.h"
    00004 #include "GaudiKernel/SvcFactory.h"
    00005 #include "GaudiKernel/IToolSvc.h"
    00006 #include "GaudiKernel/IAlgTool.h"
    00007
    00008 DECLARE_SERVICE_FACTORY(VFSSvc)
    00009
    00010 //------------------------------------------------------------------------------
    00011 VFSSvc::VFSSvc(const std::string& name, ISvcLocator* svc):
    00012   base_class(name,svc) {
    00013
    00014   m_urlHandlersNames.push_back("FileReadTool");
    00015
    00016   declareProperty("FileAccessTools",m_urlHandlersNames,
    00017                   "List of tools implementing the IFileAccess interface.");
    00018
    00019   declareProperty("FallBackProtocol",m_fallBackProtocol = "file",
    00020                   "URL prefix to use if the prefix is not present.");
    00021 }
    00022 //------------------------------------------------------------------------------
    00023 VFSSvc::~VFSSvc(){}
    00024 //------------------------------------------------------------------------------
    00025 StatusCode VFSSvc::initialize() {
    00026   StatusCode sc = Service::initialize();
    00027   if (sc.isFailure()){
    00028     return sc;
    00029   }
    00030
    00031   MsgStream log(msgSvc(), name());
    00032
    00033   m_toolSvc = serviceLocator()->service("ToolSvc");
    00034   if (!m_toolSvc.isValid()){
    00035     log << MSG::ERROR << "Cannot locate ToolSvc" << endmsg;
    00036     return StatusCode::FAILURE;
    00037   }
    00038
    00039   IAlgTool *tool;
    00040   IFileAccess *hndlr;
    00041   std::vector<std::string>::iterator i;
    00042   for(i = m_urlHandlersNames.begin(); i != m_urlHandlersNames.end(); ++i){
    00043     // retrieve the tool and the pointer to the interface
    00044     sc = m_toolSvc->retrieve(*i,IAlgTool::interfaceID(),tool,0,true);
    00045     if (sc.isFailure()){
    00046       log << MSG::ERROR << "Cannot get tool " << *i << endmsg;
    00047       return sc;
    00048     }
    00049     m_acquiredTools.push_front(tool); // this is one tool that we will have to release
    00050     sc = tool->queryInterface(IFileAccess::interfaceID(),pp_cast<void>(&hndlr));
    00051     if (sc.isFailure()){
    00052       log << MSG::ERROR << *i << " does not implement IFileAccess" << endmsg;
    00053       return sc;
    00054     }
    00055     // We do not need to increase the reference count for the IFileAccess interface
    00056     // because we hold the tool by its IAlgTool interface.
    00057     hndlr->release();
    00058     // loop over the list of supported protocols and add them to the map (for quick access)
    00059     for ( std::vector<std::string>::const_iterator prot = hndlr->protocols().begin();
    00060           prot != hndlr->protocols().end(); ++prot ){
    00061       m_urlHandlers[*prot] = hndlr;
    00062     }
    00063   }
    00064
    00065   // Now let's check if we can handle the fallback protocol
    00066   if ( m_urlHandlers.find(m_fallBackProtocol) == m_urlHandlers.end() ) {
    00067     log << MSG::ERROR << "No handler specified for fallback protocol prefix "
    00068         << m_fallBackProtocol << endmsg;
    00069     return StatusCode::FAILURE;
    00070   }
    00071
    00072   // Note: the list of handled protocols will be filled only if requested
    00073
    00074   return sc;
    00075 }
    00076 //------------------------------------------------------------------------------
    00077 StatusCode VFSSvc::finalize() {
    00078   m_urlHandlers.clear(); // clear the map
    00079   m_protocols.clear();
    00080
    00081   if (m_toolSvc) {
    00082     // release the acquired tools (from the last acquired one)
    00083     while ( m_acquiredTools.begin() != m_acquiredTools.end() ){
    00084       m_toolSvc->releaseTool(*m_acquiredTools.begin()).ignore();
    00085       m_acquiredTools.pop_front();
    00086     }
    00087     m_toolSvc->release(); // release the tool service
    00088     m_toolSvc = 0;
    00089   }
    00090   return Service::finalize();
    00091 }
    00092 //------------------------------------------------------------------------------
    00093 std::auto_ptr<std::istream> VFSSvc::open(const std::string &url){
    00094
    00095   // get the url prefix endpos
    00096   std::string::size_type pos = url.find("://");
    00097
    00098   if (std::string::npos == pos) { // no url prefix
    00099     return m_urlHandlers[m_fallBackProtocol]->open(url);
    00100   }
    00101
    00102   std::string url_prefix(url,0,pos);
    00103   if ( m_urlHandlers.find(url_prefix) == m_urlHandlers.end() ) {
    00104     // if we do not have a handler for the URL prefix,
    00105     // use the fall back one and pass only the path
    00106     return m_urlHandlers[m_fallBackProtocol]->open(url.substr(pos+3));
    00107   }
    00108   return m_urlHandlers[url_prefix]->open(url);
    00109 }
    00110 //------------------------------------------------------------------------------
    00111 namespace {
    00114   template <class Container>
    00115   struct append_key
    00116   {
    00117     append_key(Container &C):c(C){}
    00118
    00119     template <class PAIR>
    00120     void operator() (const PAIR &x)
    00121     {
    00122       c.push_back(x.first);
    00123     }
    00124
    00125     Container &c;
    00126   };
    00127 }
    00128 const std::vector<std::string> &VFSSvc::protocols() const
    00129 {
    00130   if (m_protocols.empty()){
    00131     // prepare the list of handled protocols
    00132     std::for_each(m_urlHandlers.begin(),m_urlHandlers.end(),
    00133                   append_key<std::vector<std::string> >(const_cast<VFSSvc*>(this)->m_protocols));
    00134   }
    00135   return m_protocols;
    00136 }