Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

XMLFileCatalog.cpp

Go to the documentation of this file.
00001 #include "xercesc/framework/LocalFileFormatTarget.hpp"
00002 #include "xercesc/framework/MemBufInputSource.hpp"
00003 #include "xercesc/sax/SAXParseException.hpp"
00004 #include "xercesc/sax/EntityResolver.hpp"
00005 #include "xercesc/sax/InputSource.hpp"
00006 #include "xercesc/parsers/XercesDOMParser.hpp"
00007 #include "xercesc/util/PlatformUtils.hpp"
00008 #include "xercesc/util/XercesDefs.hpp"
00009 #include "xercesc/util/XMLUni.hpp"
00010 #include "xercesc/util/XMLURL.hpp"
00011 #include "xercesc/util/XMLString.hpp"
00012 #include "xercesc/dom/DOM.hpp"
00013 
00014 #include "GaudiKernel/MsgStream.h"
00015 #include "GaudiKernel/Service.h"
00016 #include "Reflex/PluginService.h"
00017 
00018 #include "XMLFileCatalog.h"
00019 
00020 #include <fstream>
00021 #include <iostream>
00022 #include <stdexcept>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include "uuid/uuid.h"
00026 
00027 using namespace xercesc;
00028 using namespace Gaudi;
00029 using namespace std;
00030 
00031 #if _XERCES_VERSION <= 30000
00032 // API change between XercesC 2 and 3
00033 #define setIdAttribute(a, b) setIdAttribute(a)
00034 #endif
00035 
00036 PLUGINSVC_FACTORY(XMLFileCatalog,IInterface*(std::string, IMessageSvc*))
00037 
00038 namespace {
00039 
00040   typedef const string& CSTR;
00041   inline string _toString(const XMLCh *toTranscode)  {
00042     char * buff = XMLString::transcode(toTranscode);
00043     string tmp(buff==0 ? "" : buff);
00044     XMLString::release(&buff);
00045     return tmp;
00046   }
00047   struct __Init  {
00048     __Init() {
00049       try { XMLPlatformUtils::Initialize();      }
00050       catch (const XMLException& e)   {
00051         cout << "Xerces-c error in initialization:" << _toString(e.getMessage()) << endl;
00052       }
00053     }
00054     ~__Init() {
00055       XMLPlatformUtils::Terminate();
00056     }
00057   };
00058   __Init __In__;
00059 
00060   struct XMLStr  {
00061     XMLCh* m_xml;
00062     XMLStr(CSTR c)                { m_xml=XMLString::transcode(c.c_str());  }
00063     ~XMLStr()                     { if (m_xml) XMLString::release(&m_xml);  }
00064     operator const XMLCh*() const { return m_xml;                           }
00065   };
00066   struct XMLTag : public XMLStr {
00067     string m_str;
00068     XMLTag(CSTR s) : XMLStr(s), m_str(s) {  }
00069     ~XMLTag()                            {  }
00070     operator CSTR () const  { return m_str; }
00071   };
00072   // bool operator==(const XMLTag& b, CSTR c) {  return c==b.m_str; }
00073   bool operator==(CSTR c, const XMLTag& b) {  return c==b.m_str; }
00074   struct XMLCollection  {
00075     DOMElement* m_node;
00076     XMLCollection(DOMNode* n, bool use_children=true) : m_node((DOMElement*)n) {
00077       if ( use_children )  {
00078         if ( m_node ) m_node = (DOMElement*)m_node->getFirstChild();
00079         if ( m_node && m_node->getNodeType() != DOMNode::ELEMENT_NODE ) ++(*this);
00080       }
00081     }
00082     operator bool()  const                { return 0 != m_node;                         }
00083     operator DOMNode* () const            { return m_node;                              }
00084     operator DOMElement* () const         { return m_node;                              }
00085     DOMElement* operator->() const        { return m_node;                              }
00086     string attr(const XMLTag& tag) const  { return _toString(m_node->getAttribute(tag));}
00087     string attr(CSTR tag)  const          { return attr(XMLTag(tag));                   }
00088     string tag() const                    { return _toString(m_node->getTagName());     }
00089     void operator++()   {
00090       while(m_node)  {
00091         m_node = (DOMElement*)m_node->getNextSibling();
00092         if ( m_node && m_node->getNodeType() == DOMNode::ELEMENT_NODE ) {
00093           return;
00094         }
00095       }
00096     }
00097   };
00098   struct ErrHandler : public ErrorHandler    {
00100     IMessageSvc* m_msg;
00102     ErrHandler(IMessageSvc* m) : m_msg(m) {}
00104     void resetErrors()                          {      }
00106     void warning(const SAXParseException& /* e */)    {     }
00108     void error(const SAXParseException& e);
00110     void fatalError(const SAXParseException& e);
00111   };
00112   struct DTDRedirect : public EntityResolver  {
00113     InputSource* resolveEntity(const XMLCh* const /* pubId */, const XMLCh* const /* sysId */)  {
00114       static const char* dtdID = "redirectinmem.dtd";
00115       static const char* dtd = \
00116         "\
00117         <!ELEMENT POOLFILECATALOG (META*,File*)>\
00118         <!ELEMENT META EMPTY>\
00119         <!ELEMENT File (physical,logical,metadata*)>\
00120         <!ATTLIST META name CDATA #REQUIRED>\
00121         <!ATTLIST META type CDATA #REQUIRED>\
00122         <!ELEMENT physical (pfn)+>\
00123         <!ELEMENT logical (lfn)*>\
00124         <!ELEMENT metadata EMPTY>\
00125         <!ELEMENT lfn EMPTY>\
00126         <!ELEMENT pfn EMPTY>\
00127         <!ATTLIST File ID ID  #REQUIRED>\
00128         <!ATTLIST pfn name ID #REQUIRED>\
00129         <!ATTLIST pfn filetype CDATA #IMPLIED>\
00130         <!ATTLIST lfn name ID #REQUIRED>\
00131         <!ATTLIST metadata att_name  CDATA #REQUIRED>\
00132         <!ATTLIST metadata att_value CDATA #REQUIRED>\
00133         ";
00134       static const size_t len = strlen(dtd);
00135       return new MemBufInputSource((const XMLByte*)dtd,len,dtdID,false);
00136     }
00137   };
00138 
00139   void ErrHandler::error(const SAXParseException& e)  {
00140     string m(_toString(e.getMessage()));
00141     if (m.find("The values for attribute 'name' must be names or name tokens")!=string::npos ||
00142       m.find("The values for attribute 'ID' must be names or name tokens")!=string::npos   ||
00143       m.find("for attribute 'name' must be Name or Nmtoken")!=string::npos                 ||
00144       m.find("for attribute 'ID' must be Name or Nmtoken")!=string::npos                   ||
00145       m.find("for attribute 'name' is invalid Name or NMTOKEN value")!=string::npos        ||
00146       m.find("for attribute 'ID' is invalid Name or NMTOKEN value")!=string::npos      )
00147       return;
00148     string sys(_toString(e.getSystemId()));
00149     MsgStream log(m_msg,"XMLCatalog");
00150     log << MSG::ERROR << "Error at file \""  << sys
00151       << "\", line " << e.getLineNumber() << ", column " << e.getColumnNumber() << endmsg
00152       << "Message: " << m << endmsg;
00153   }
00154   void ErrHandler::fatalError(const SAXParseException& e)  {
00155     MsgStream log(m_msg,"XMLCatalog");
00156     string m(_toString(e.getMessage()));
00157     string sys(_toString(e.getSystemId()));
00158     log << MSG::ERROR << "Fatal Error at file \"" << sys
00159       << "\", line " << e.getLineNumber() << ", column " << e.getColumnNumber() << endmsg
00160       << "Message: " << m << endmsg;
00161     throw runtime_error( "Standard pool exception : Fatal Error on the DOM Parser" );
00162   }
00163 
00164   const XMLTag EmptyCatalog("<!-- Edited By POOL -->\n"
00165                               "<!DOCTYPE POOLFILECATALOG SYSTEM \"InMemory\">\n"
00166                               "<POOLFILECATALOG>\n"
00167                               "</POOLFILECATALOG>\n");
00168   const XMLTag PFNCOLL         ("physical");
00169   const XMLTag LFNCOLL         ("logical");
00170   const XMLTag PFNNODE         ( "pfn");
00171   const XMLTag LFNNODE         ( "lfn");
00172   const XMLTag Attr_type       ( "type");
00173   const XMLTag Attr_ID         ( "ID");
00174   const XMLTag Attr_name       ( "name");
00175   const XMLTag Attr_ftype      ( "filetype");
00176   const XMLTag MetaNode        ( "metadata");
00177   const XMLTag Attr_metaName   ( "att_name");
00178   const XMLTag Attr_metaValue  ( "att_value");
00179 }
00180 
00182 std::string Gaudi::createGuidAsString()  {
00183   char text[64];
00184   uuid_t uuid;
00185   ::uuid_generate_time(uuid);
00186   struct Guid {
00187     unsigned int   Data1;
00188     unsigned short Data2;
00189     unsigned short Data3;
00190     unsigned char  Data4[8];
00191   } *g = (Guid*)&uuid;
00192   ::sprintf(text, "%08X-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
00193             g->Data1, g->Data2, g->Data3,
00194             g->Data4[0], g->Data4[1], g->Data4[2], g->Data4[3],
00195             g->Data4[4], g->Data4[5], g->Data4[6], g->Data4[7]);
00196   return text;
00197 }
00198 // ----------------------------------------------------------------------------
00199 XMLFileCatalog::XMLFileCatalog(CSTR uri, IMessageSvc* m)
00200 : m_rdOnly(false),m_update(false),m_doc(0),m_parser(0),m_errHdlr(0),
00201   m_file(uri), m_msgSvc(m)
00202 {
00203 }
00204 // ----------------------------------------------------------------------------
00205 XMLFileCatalog::~XMLFileCatalog()   {
00206   if (m_parser) delete m_parser;
00207   m_parser = 0;
00208   if (m_errHdlr) delete m_errHdlr;
00209   m_errHdlr = 0;
00210   m_doc = 0;
00211 }
00212 // ----------------------------------------------------------------------------
00214 std::string XMLFileCatalog::createFID()  const {
00215   return createGuidAsString();
00216 }
00217 // ----------------------------------------------------------------------------
00218 DOMDocument* XMLFileCatalog::getDoc(bool throw_if_no_exists)  const  {
00219   if ( !m_doc && throw_if_no_exists )
00220     printError("The XML catalog was not started.",true);
00221   return m_doc;
00222 }
00223 // ----------------------------------------------------------------------------
00224 void XMLFileCatalog::printError(CSTR msg, bool rethrow)  const  {
00225   MsgStream log(m_msgSvc,"XMLCatalog");
00226   log << MSG::FATAL << msg << endmsg;
00227   if ( rethrow )  {
00228     throw runtime_error("XMLFileCatalog> "+msg);
00229   }
00230 }
00231 // ----------------------------------------------------------------------------
00232 void XMLFileCatalog::init()   {
00233   string xmlFile = getfile(false);
00234   try{
00235     if ( m_parser ) delete m_parser;
00236     m_parser = new XercesDOMParser;
00237     m_parser->setValidationScheme(XercesDOMParser::Val_Auto);
00238     m_parser->setDoNamespaces(false);
00239     DTDRedirect dtdinmem;
00240     m_parser->setEntityResolver(&dtdinmem);
00241     if ( ! m_errHdlr ) m_errHdlr = new ErrHandler(m_msgSvc);
00242     m_parser->setErrorHandler(m_errHdlr);
00243     if ( !xmlFile.empty() )  {
00244       m_parser->parse(xmlFile.c_str());
00245     }
00246     else  {
00247       const std::string& s = EmptyCatalog;
00248       MemBufInputSource src((const XMLByte*)s.c_str(),s.length(),"MemCatalog");
00249       m_parser->parse(src);
00250     }
00251     m_doc = m_parser->getDocument();
00252   }
00253   catch (const XMLException& e) {
00254     printError("XML parse error["+xmlFile+"]: "+_toString(e.getMessage()));
00255   }
00256   catch (const DOMException& e) {
00257     printError("XML parse error["+xmlFile+"]: "+_toString(e.getMessage()));
00258   }
00259   catch (...)  {
00260     printError("UNKNOWN XML parse error in file "+xmlFile);
00261   }
00262 }
00263 // ----------------------------------------------------------------------------
00264 string XMLFileCatalog::lookupFID(const std::string& fid)  const  {
00265   std::string result;
00266   DOMNode* e = element(fid,false);
00267   e = e ? e->getParentNode() : 0;    // Mode up to <logical>
00268   e = e ? e->getParentNode() : 0;    // Mode up to <File>
00269   if ( e ) {
00270     if ( e->getAttributes() ) { // Need to check this. The node may be no DOMElement
00271       char* nam = XMLString::transcode(((DOMElement*)e)->getAttribute(Attr_ID));
00272       if ( nam ) result = nam;
00273       XMLString::release(&nam);
00274     }
00275   }
00276   return result;
00277 }
00278 // ----------------------------------------------------------------------------
00279 void XMLFileCatalog::getFID(Strings& fids) const {
00280   fids.clear();
00281   DOMNode* fde = getDoc(true)->getElementsByTagName(XMLStr("*"))->item(0);
00282   for(XMLCollection c(child(fde,"File"), false); c; ++c)
00283     fids.push_back(c.attr(Attr_ID));
00284 }
00285 // ----------------------------------------------------------------------------
00286 void XMLFileCatalog::getPFN(CSTR fid, Files& files)  const {
00287   files.clear();
00288   for(XMLCollection c(child(child(element(fid,false),PFNCOLL),PFNNODE), false); c; ++c)
00289     files.push_back(make_pair(c.attr(Attr_name),c.attr(Attr_ftype)));
00290 }
00291 // ----------------------------------------------------------------------------
00292 void XMLFileCatalog::getLFN(CSTR fid, Files& files) const  {
00293   files.clear();
00294   for(XMLCollection c(child(child(element(fid,false),LFNCOLL),LFNNODE), false); c; ++c)
00295     files.push_back(make_pair(c.attr(Attr_name),fid));
00296 }
00297 // ----------------------------------------------------------------------------
00298 void XMLFileCatalog::getMetaData(CSTR fid, Attributes& attr)  const  {
00299   attr.clear();
00300   for(XMLCollection c(child(element(fid),MetaNode), false); c; ++c)
00301     attr.push_back(make_pair(c.attr(Attr_metaName),c.attr(Attr_metaValue)));
00302   if ( attr.size() > 0 )
00303     attr.push_back(make_pair("guid",fid));
00304 }
00305 // ----------------------------------------------------------------------------
00306 DOMNode* XMLFileCatalog::child(DOMNode* par,CSTR tag,CSTR attr,CSTR val) const {
00307   for(XMLCollection c(par); c; ++c ) {
00308     if( c.tag() == tag )  {
00309       if( !attr.empty() && c.attr(attr) != val) continue;
00310       return c;
00311     }
00312   }
00313   return 0;
00314 }
00315 // ----------------------------------------------------------------------------
00316 void XMLFileCatalog::setMetaData(CSTR fid, CSTR attr, CSTR val)  const  {
00317   if ( !readOnly() )  {
00318     DOMNode*    node = element(fid);
00319     DOMElement* mnod = (DOMElement*)child(node,MetaNode,Attr_metaName,attr);
00320     if (!mnod){
00321       mnod = getDoc(true)->createElement(MetaNode);
00322       node->appendChild(mnod);
00323       mnod->setAttribute(Attr_metaName,XMLStr(attr));
00324     }
00325     mnod->setAttribute(Attr_metaValue,XMLStr(val));
00326     m_update = true;
00327     return;
00328   }
00329   printError("Cannot update readonly catalog!");
00330 }
00331 // ----------------------------------------------------------------------------
00332 string XMLFileCatalog::getMetaDataItem(CSTR fid,CSTR attr) const  {
00333   XMLCollection c(child(getDoc(true)->getElementById(XMLStr(fid)),MetaNode,Attr_metaName,attr));
00334   return c ? c.attr(attr) : string("");
00335 }
00336 // ----------------------------------------------------------------------------
00337 void XMLFileCatalog::dropMetaData(CSTR fid,CSTR attr) const  {
00338   vector<DOMNode*> gbc;
00339   DOMNode* fn = getDoc(true)->getElementById(XMLStr(fid));
00340   for(XMLCollection c(child(fn,MetaNode)); c; ++c)
00341     if ( attr[0]=='*' || !c.attr(attr).empty() ) gbc.push_back(c);
00342   for(vector<DOMNode*>::iterator i=gbc.begin(); i != gbc.end(); i++)
00343     fn->removeChild(*i);
00344 }
00345 // ----------------------------------------------------------------------------
00346 DOMNode* XMLFileCatalog::element(CSTR element_name,bool print_err) const {
00347   DOMNode* node = getDoc(true)->getElementById(XMLStr(element_name));
00348   if ( !node && print_err ) printError("Cannot find element:"+element_name);
00349   return node;
00350 }
00351 // ----------------------------------------------------------------------------
00352 void XMLFileCatalog::deleteFID(CSTR fid) const {
00353   DOMNode *pn = 0, *fn = element(fid);
00354   if ( fn ) pn = fn->getParentNode();
00355   if ( pn ) pn->removeChild(fn);
00356 }
00357 // ----------------------------------------------------------------------------
00358 void XMLFileCatalog::registerFID(CSTR fid) const {
00359   if ( !fid.empty() ) {
00360     std::pair<DOMElement*, DOMElement*> res = i_registerFID(fid);
00361     if ( res.first == 0 || res.second == 0 )  {
00362       printError("Failed to register FID:"+fid);
00363     }
00364     return;
00365   }
00366   throw runtime_error("XMLFileCatalog> Cannot register LFN for invalid FID:"+fid);
00367 }
00368 // ----------------------------------------------------------------------------
00369 std::pair<DOMElement*,DOMElement*> XMLFileCatalog::i_registerFID(CSTR fid) const {
00370   if ( !readOnly() )  {
00372     DOMElement *file = (DOMElement*)element(fid,false), *phyelem = 0, *logelem = 0;
00373     DOMDocument* doc = getDoc(true);
00374     if ( !file )  {
00375       DOMNode* fde = doc->getElementsByTagName(XMLStr("*"))->item(0);
00376       file = m_doc->createElement(XMLStr("File"));
00377       file->setAttribute(Attr_ID, XMLStr(fid));
00378       file->setIdAttribute(Attr_ID, true);
00379       fde->appendChild(file);
00380       m_update = true;
00381     }
00382     for(XMLCollection c1(file); c1; ++c1 )  {
00383       char* nam = XMLString::transcode(c1->getNodeName());
00384       if ( nam == PFNCOLL ) phyelem = c1;
00385       if ( nam == LFNCOLL ) logelem = c1;
00386       XMLString::release(&nam);
00387     }
00388     if ( !phyelem )  {
00389       phyelem = doc->createElement(PFNCOLL);
00390       file->appendChild(phyelem);
00391       m_update = true;
00392     }
00393     if ( !logelem )  {
00394       logelem = doc->createElement(LFNCOLL);
00395       file->appendChild(logelem);
00396       m_update = true;
00397     }
00398     return std::make_pair(logelem,phyelem);
00399   }
00400   printError("Cannot update readonly catalog!");
00401   return std::pair<DOMElement*, DOMElement*>(0,0);
00402 }
00403 // ----------------------------------------------------------------------------
00404 void XMLFileCatalog::registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const {
00405   if ( !fid.empty() )  {
00406     std::pair<DOMElement*,DOMElement*> res = i_registerFID(fid);
00407     DOMElement* phyelem = res.second, *fnelem = 0;
00408     for(XMLCollection c(phyelem); c; ++c )  {
00409       char* nam = XMLString::transcode(c->getNodeName());
00410       if ( nam == PFNNODE )  {
00411         XMLString::release(&nam);
00412         nam = XMLString::transcode(c->getAttribute(Attr_name));
00413         if ( nam == pfn )  {
00414           XMLString::release(&nam);
00415           fnelem = c;
00416           break;
00417         }
00418       }
00419       XMLString::release(&nam);
00420     }
00421     if ( !fnelem )  {
00422       fnelem = getDoc(true)->createElement(PFNNODE);
00423       phyelem->appendChild(fnelem);
00424       fnelem->setAttribute(Attr_ftype,XMLStr(ftype));
00425       fnelem->setAttribute(Attr_name,XMLStr(pfn));
00426       fnelem->setIdAttribute(Attr_name, true);
00427       m_update = true;
00428     }
00429     return;
00430   }
00431   throw runtime_error("XMLFileCatalog> Cannot register PFN for invalid FID:"+fid);
00432 }
00433 // ----------------------------------------------------------------------------
00434 void XMLFileCatalog::registerLFN(CSTR fid, CSTR lfn) const {
00435   if ( !fid.empty() )  {
00436     std::pair<DOMElement*, DOMElement*> res = i_registerFID(fid);
00437     DOMElement* logelem = res.first, *fnelem = 0;
00438     for(XMLCollection c(logelem); c; ++c )  {
00439       char* nam = XMLString::transcode(c->getNodeName());
00440       if ( nam == LFNNODE )  {
00441         XMLString::release(&nam);
00442         nam = XMLString::transcode(c->getAttribute(Attr_name));
00443         if ( nam == lfn )  {
00444           XMLString::release(&nam);
00445           fnelem = c;
00446           break;
00447         }
00448       }
00449     }
00450     if ( !fnelem )  {
00451       fnelem = getDoc(true)->createElement(LFNNODE);
00452       logelem->appendChild(fnelem);
00453       fnelem->setAttribute(Attr_name,XMLStr(lfn));
00454       fnelem->setIdAttribute(Attr_name, true);
00455       m_update = true;
00456     }
00457     return;
00458   }
00459   throw runtime_error("XMLFileCatalog> Cannot register LFN for invalid FID:"+fid);
00460 }
00461 // ----------------------------------------------------------------------------
00462 void XMLFileCatalog::commit()    {
00463   try {
00464     if ( dirty() && !readOnly() )  {
00465       string xmlfile = getfile(true);
00466       XMLStr ii("LS");
00467       DOMImplementation *imp = DOMImplementationRegistry::getDOMImplementation(ii);
00468       XMLFormatTarget   *tar = new LocalFileFormatTarget(xmlfile.c_str());
00469 #if _XERCES_VERSION <= 30000
00470       DOMWriter         *wr  = imp->createDOMWriter();
00471       wr->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
00472       wr->writeNode(tar, *m_doc);
00473       wr->release();
00474 #else
00475       DOMLSOutput       *output = imp->createLSOutput();
00476       output->setByteStream(tar);
00477       DOMLSSerializer   *wr     = imp->createLSSerializer();
00478       wr->getDomConfig()->setParameter(XMLStr("format-pretty-print"), true);
00479       wr->write(m_doc, output);
00480       output->release();
00481       wr->release();
00482 #endif
00483       delete  tar;
00484     }
00485   }
00486   catch ( exception& e )  {
00487     printError(string("Cannot open output file:")+e.what());
00488   }
00489   catch (...)  {
00490     printError("Unknown IO rrror.");
00491   }
00492 }
00493 // ----------------------------------------------------------------------------
00494 string XMLFileCatalog::getfile(bool create)   {
00495   string protocol, path;
00496   XMLURL xerurl;
00497   try{
00498     xerurl   = (const XMLCh*)XMLStr(m_file);
00499     protocol = _toString(xerurl.getProtocolName());
00500     path     = _toString(xerurl.getPath());
00501   }
00502   catch (const XMLException& e ) {
00503     printError(_toString(e.getMessage()));
00504   }
00505   if ( protocol.empty() )    {
00506     printError("Missing protocol.");
00507   }
00508   else if ( protocol == "http" || protocol == "ftp" )  {
00509     m_rdOnly = true;
00510   }
00511   else if ( protocol == "file" ) {
00512     m_rdOnly = false;
00513     struct stat buff;
00514     int exist = ::stat(path.c_str(),&buff) != -1;
00515     if ( create && !exist )  {
00516       MsgStream log(m_msgSvc,"XMLCatalog");
00517       log << MSG::INFO << "File '" << path << "' does not exist. New file created." << endmsg;
00518       ofstream out(path.c_str());
00519       if( !m_rdOnly && out.is_open() ) {
00520         out << (CSTR)EmptyCatalog << endl;
00521       }
00522       else     {
00523         printError("Problem creating file "+path);
00524       }
00525       out.close();
00526     }
00527     else if ( exist )  {
00528       return path;
00529     }
00530     else if ( !create )  {
00531       return "";
00532     }
00533   }
00534   else  {
00535     printError(protocol + ": protocol not supported.");
00536   }
00537   return path;
00538 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Wed Feb 9 16:25:05 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004