![]() |
|
|
Generated: 8 Jan 2009 |
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 }