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