| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# 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   Service(name,svc), m_toolSvc(0) {
    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::queryInterface(const InterfaceID& riid,
    00026                                       void** ppvInterface) {
    00027   StatusCode sc = StatusCode::FAILURE;
    00028   if ( ppvInterface ) {
    00029     *ppvInterface = 0;
    00030
    00031     if ( IFileAccess::interfaceID().versionMatch(riid) )    {
    00032       *ppvInterface = static_cast<IFileAccess*>(this);
    00033       sc = StatusCode::SUCCESS;
    00034       addRef();
    00035     }
    00036     else
    00037       sc = Service::queryInterface( riid, ppvInterface );
    00038   }
    00039   return sc;
    00040 }
    00041 //------------------------------------------------------------------------------
    00042 StatusCode VFSSvc::initialize() {
    00043   StatusCode sc = Service::initialize();
    00044   if (sc.isFailure()){
    00045     return sc;
    00046   }
    00047
    00048   MsgStream log(messageService(), name());
    00049
    00050   sc = serviceLocator()->service( "ToolSvc" , m_toolSvc , true );
    00051   if (sc.isFailure()){
    00052     log << MSG::ERROR << "Cannot locate ToolSvc" << endmsg;
    00053     return sc;
    00054   }
    00055
    00056   IAlgTool *tool;
    00057   IFileAccess *hndlr;
    00058   std::vector<std::string>::iterator i;
    00059   for(i = m_urlHandlersNames.begin(); i != m_urlHandlersNames.end(); ++i){
    00060     // retrieve the tool and the pointer to the interface
    00061     sc = m_toolSvc->retrieve(*i,IAlgTool::interfaceID(),tool,0,true);
    00062     if (sc.isFailure()){
    00063       log << MSG::ERROR << "Cannot get tool " << *i << endmsg;
    00064       return sc;
    00065     }
    00066     m_acquiredTools.push_front(tool); // this is one tool that we will have to release
    00067     sc = tool->queryInterface(IFileAccess::interfaceID(),pp_cast<void>(&hndlr));
    00068     if (sc.isFailure()){
    00069       log << MSG::ERROR << *i << " does not implement IFileAccess" << endmsg;
    00070       return sc;
    00071     }
    00072     // We do not need to increase the reference count for the IFileAccess interface
    00073     // because we hold the tool by its IAlgTool interface.
    00074     hndlr->release();
    00075     // loop over the list of supported protocols and add them to the map (for quick access)
    00076     for ( std::vector<std::string>::const_iterator prot = hndlr->protocols().begin();
    00077           prot != hndlr->protocols().end(); ++prot ){
    00078       m_urlHandlers[*prot] = hndlr;
    00079     }
    00080   }
    00081
    00082   // Now let's check if we can handle the fallback protocol
    00083   if ( m_urlHandlers.find(m_fallBackProtocol) == m_urlHandlers.end() ) {
    00084     log << MSG::ERROR << "No handler specified for fallback protocol prefix "
    00085         << m_fallBackProtocol << endmsg;
    00086     return StatusCode::FAILURE;
    00087   }
    00088
    00089   // Note: the list of handled protocols will be filled only if requested
    00090
    00091   return sc;
    00092 }
    00093 //------------------------------------------------------------------------------
    00094 StatusCode VFSSvc::finalize() {
    00095   m_urlHandlers.clear(); // clear the map
    00096   m_protocols.clear();
    00097
    00098   if (m_toolSvc) {
    00099     // release the acquired tools (from the last acquired one)
    00100     while ( m_acquiredTools.begin() != m_acquiredTools.end() ){
    00101       m_toolSvc->releaseTool(*m_acquiredTools.begin()).ignore();
    00102       m_acquiredTools.pop_front();
    00103     }
    00104     m_toolSvc->release(); // release the tool service
    00105     m_toolSvc = 0;
    00106   }
    00107   return Service::finalize();
    00108 }
    00109 //------------------------------------------------------------------------------
    00110 std::auto_ptr<std::istream> VFSSvc::open(const std::string &url){
    00111
    00112   // get the url prefix endpos
    00113   std::string::size_type pos = url.find("://");
    00114
    00115   if (std::string::npos == pos) { // no url prefix
    00116     return m_urlHandlers[m_fallBackProtocol]->open(url);
    00117   }
    00118
    00119   std::string url_prefix(url,0,pos);
    00120   if ( m_urlHandlers.find(url_prefix) == m_urlHandlers.end() ) {
    00121     // if we do not have a handler for the URL prefix,
    00122     // use the fall back one and pass only the path
    00123     return m_urlHandlers[m_fallBackProtocol]->open(url.substr(pos+3));
    00124   }
    00125   return m_urlHandlers[url_prefix]->open(url);
    00126 }
    00127 //------------------------------------------------------------------------------
    00128 namespace {
    00131   template <class Container>
    00132   struct append_key
    00133   {
    00134     append_key(Container &C):c(C){}
    00135
    00136     template <class PAIR>
    00137     void operator() (const PAIR &x)
    00138     {
    00139       c.push_back(x.first);
    00140     }
    00141
    00142     Container &c;
    00143   };
    00144 }
    00145 const std::vector<std::string> &VFSSvc::protocols() const
    00146 {
    00147   if (m_protocols.empty()){
    00148     // prepare the list of handled protocols
    00149     std::for_each(m_urlHandlers.begin(),m_urlHandlers.end(),
    00150                   append_key<std::vector<std::string> >(const_cast<VFSSvc*>(this)->m_protocols));
    00151   }
    00152   return m_protocols;
    00153 }