Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 2012

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

Generated at Mon Sep 17 2012 13:49:37 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004