The Gaudi Framework  v29r0 (ff2e7097)
XMLFileCatalog.cpp
Go to the documentation of this file.
1 #include "xercesc/dom/DOM.hpp"
2 #include "xercesc/framework/LocalFileFormatTarget.hpp"
3 #include "xercesc/framework/MemBufInputSource.hpp"
4 #include "xercesc/parsers/XercesDOMParser.hpp"
5 #include "xercesc/sax/EntityResolver.hpp"
6 #include "xercesc/sax/InputSource.hpp"
7 #include "xercesc/sax/SAXParseException.hpp"
8 #include "xercesc/util/PlatformUtils.hpp"
9 #include "xercesc/util/XMLString.hpp"
10 #include "xercesc/util/XMLURL.hpp"
11 #include "xercesc/util/XMLUni.hpp"
12 #include "xercesc/util/XercesDefs.hpp"
13 
14 #include "GaudiKernel/MsgStream.h"
15 #include "GaudiKernel/Service.h"
16 #include <Gaudi/PluginService.h>
17 
18 #include "XMLFileCatalog.h"
19 #include "createGuidAsString.h"
20 
21 #include <fstream>
22 #include <iostream>
23 #include <stdexcept>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 
27 using namespace xercesc;
28 using namespace Gaudi;
29 using namespace std;
30 
31 #if _XERCES_VERSION <= 30000
32 // API change between XercesC 2 and 3
33 #define setIdAttribute( a, b ) setIdAttribute( a )
34 #endif
35 
37 
38 namespace
39 {
40 
41  typedef const string& CSTR;
42  inline string _toString( const XMLCh* toTranscode )
43  {
44  char* buff = XMLString::transcode( toTranscode );
45  string tmp( buff == 0 ? "" : buff );
46  XMLString::release( &buff );
47  return tmp;
48  }
49  struct __Init {
50  __Init()
51  {
52  try {
53  XMLPlatformUtils::Initialize();
54  } catch ( const XMLException& e ) {
55  cout << "Xerces-c error in initialization:" << _toString( e.getMessage() ) << endl;
56  }
57  }
58  ~__Init() { XMLPlatformUtils::Terminate(); }
59  };
60  __Init __In__;
61 
62  struct XMLStr {
63  XMLCh* m_xml;
64  XMLStr( CSTR c ) { m_xml = XMLString::transcode( c.c_str() ); }
65  ~XMLStr()
66  {
67  if ( m_xml ) XMLString::release( &m_xml );
68  }
69  operator const XMLCh*() const { return m_xml; }
70  };
71  struct XMLTag : public XMLStr {
72  string m_str;
73  XMLTag( CSTR s ) : XMLStr( s ), m_str( s ) {}
74  ~XMLTag() {}
75  operator CSTR() const { return m_str; }
76  };
77  // bool operator==(const XMLTag& b, CSTR c) { return c==b.m_str; }
78  bool operator==( CSTR c, const XMLTag& b ) { return c == b.m_str; }
79  struct XMLCollection {
80  DOMElement* m_node;
81  XMLCollection( DOMNode* n, bool use_children = true ) : m_node( (DOMElement*)n )
82  {
83  if ( use_children ) {
84  if ( m_node ) m_node = (DOMElement*)m_node->getFirstChild();
85  if ( m_node && m_node->getNodeType() != DOMNode::ELEMENT_NODE ) ++( *this );
86  }
87  }
88  operator bool() const { return m_node; }
89  operator DOMNode*() const { return m_node; }
90  operator DOMElement*() const { return m_node; }
91  DOMElement* operator->() const { return m_node; }
92  string attr( const XMLTag& tag ) const { return _toString( m_node->getAttribute( tag ) ); }
93  string attr( CSTR tag ) const { return attr( XMLTag( tag ) ); }
94  string tag() const { return _toString( m_node->getTagName() ); }
95  void operator++()
96  {
97  while ( m_node ) {
98  m_node = (DOMElement*)m_node->getNextSibling();
99  if ( m_node && m_node->getNodeType() == DOMNode::ELEMENT_NODE ) {
100  return;
101  }
102  }
103  }
104  };
105  struct ErrHandler : public ErrorHandler {
107  IMessageSvc* m_msg;
109  ErrHandler( IMessageSvc* m ) : m_msg( m ) {}
111  void resetErrors() override {}
113  void warning( const SAXParseException& /* e */ ) override {}
115  void error( const SAXParseException& e ) override;
117  void fatalError( const SAXParseException& e ) override;
118  ~ErrHandler() override {}
119  };
120  struct DTDRedirect : public EntityResolver {
121  InputSource* resolveEntity( const XMLCh* const /* pubId */, const XMLCh* const /* sysId */ ) override
122  {
123  static const char* dtdID = "redirectinmem.dtd";
124  static const char* dtd = "\
125  <!ELEMENT POOLFILECATALOG (META*,File*)>\
126  <!ELEMENT META EMPTY>\
127  <!ELEMENT File (physical,logical,metadata*)>\
128  <!ATTLIST META name CDATA #REQUIRED>\
129  <!ATTLIST META type CDATA #REQUIRED>\
130  <!ELEMENT physical (pfn)+>\
131  <!ELEMENT logical (lfn)*>\
132  <!ELEMENT metadata EMPTY>\
133  <!ELEMENT lfn EMPTY>\
134  <!ELEMENT pfn EMPTY>\
135  <!ATTLIST File ID ID #REQUIRED>\
136  <!ATTLIST pfn name ID #REQUIRED>\
137  <!ATTLIST pfn filetype CDATA #IMPLIED>\
138  <!ATTLIST pfn se CDATA #IMPLIED>\
139  <!ATTLIST lfn name ID #REQUIRED>\
140  <!ATTLIST metadata att_name CDATA #REQUIRED>\
141  <!ATTLIST metadata att_value CDATA #REQUIRED>\
142  ";
143  static const size_t len = strlen( dtd );
144  return new MemBufInputSource( (const XMLByte*)dtd, len, dtdID, false );
145  }
146  ~DTDRedirect() override = default;
147  };
148 
149  void ErrHandler::error( const SAXParseException& e )
150  {
151  string m( _toString( e.getMessage() ) );
152  if ( m.find( "The values for attribute 'name' must be names or name tokens" ) != string::npos ||
153  m.find( "The values for attribute 'ID' must be names or name tokens" ) != string::npos ||
154  m.find( "for attribute 'name' must be Name or Nmtoken" ) != string::npos ||
155  m.find( "for attribute 'ID' must be Name or Nmtoken" ) != string::npos ||
156  m.find( "for attribute 'name' is invalid Name or NMTOKEN value" ) != string::npos ||
157  m.find( "for attribute 'ID' is invalid Name or NMTOKEN value" ) != string::npos )
158  return;
159  string sys( _toString( e.getSystemId() ) );
160  MsgStream log( m_msg, "XMLCatalog" );
161  log << MSG::ERROR << "Error at file \"" << sys << "\", line " << e.getLineNumber() << ", column "
162  << e.getColumnNumber() << endmsg << "Message: " << m << endmsg;
163  }
164  void ErrHandler::fatalError( const SAXParseException& e )
165  {
166  MsgStream log( m_msg, "XMLCatalog" );
167  string m( _toString( e.getMessage() ) );
168  string sys( _toString( e.getSystemId() ) );
169  log << MSG::ERROR << "Fatal Error at file \"" << sys << "\", line " << e.getLineNumber() << ", column "
170  << e.getColumnNumber() << endmsg << "Message: " << m << endmsg;
171  throw runtime_error( "Standard pool exception : Fatal Error on the DOM Parser" );
172  }
173 
174  const XMLTag EmptyCatalog( "<!-- Edited By POOL -->\n"
175  "<!DOCTYPE POOLFILECATALOG SYSTEM \"InMemory\">\n"
176  "<POOLFILECATALOG>\n"
177  "</POOLFILECATALOG>\n" );
178  const XMLTag PFNCOLL( "physical" );
179  const XMLTag LFNCOLL( "logical" );
180  const XMLTag PFNNODE( "pfn" );
181  const XMLTag LFNNODE( "lfn" );
182  const XMLTag Attr_type( "type" );
183  const XMLTag Attr_ID( "ID" );
184  const XMLTag Attr_name( "name" );
185  const XMLTag Attr_ftype( "filetype" );
186  const XMLTag MetaNode( "metadata" );
187  const XMLTag Attr_metaName( "att_name" );
188  const XMLTag Attr_metaValue( "att_value" );
189 }
190 
191 // ----------------------------------------------------------------------------
192 XMLFileCatalog::XMLFileCatalog( CSTR uri, IMessageSvc* m )
193  : m_rdOnly( false ), m_update( false ), m_doc( 0 ), m_file( uri ), m_msgSvc( m )
194 {
195 }
196 // ----------------------------------------------------------------------------
199 // ----------------------------------------------------------------------------
200 DOMDocument* XMLFileCatalog::getDoc( bool throw_if_no_exists ) const
201 {
202  if ( !m_doc && throw_if_no_exists ) printError( "The XML catalog was not started.", true );
203  return m_doc;
204 }
205 // ----------------------------------------------------------------------------
206 void XMLFileCatalog::printError( CSTR msg, bool rethrow ) const
207 {
208  MsgStream log( m_msgSvc, "XMLCatalog" );
209  log << MSG::FATAL << msg << endmsg;
210  if ( rethrow ) {
211  throw runtime_error( "XMLFileCatalog> " + msg );
212  }
213 }
214 // ----------------------------------------------------------------------------
216 {
217  string xmlFile = getfile( false );
218  try {
219  m_parser.reset( new XercesDOMParser );
220  m_parser->setValidationScheme( XercesDOMParser::Val_Auto );
221  m_parser->setDoNamespaces( false );
222  DTDRedirect dtdinmem;
223  m_parser->setEntityResolver( &dtdinmem );
224  if ( !m_errHdlr ) m_errHdlr.reset( new ErrHandler( m_msgSvc ) );
225  m_parser->setErrorHandler( m_errHdlr.get() );
226  if ( !xmlFile.empty() ) {
227  m_parser->parse( xmlFile.c_str() );
228  } else {
229  const std::string& s = EmptyCatalog;
230  MemBufInputSource src( (const XMLByte*)s.c_str(), s.length(), "MemCatalog" );
231  m_parser->parse( src );
232  }
233  m_doc = m_parser->getDocument();
234  } catch ( const XMLException& e ) {
235  printError( "XML parse error[" + xmlFile + "]: " + _toString( e.getMessage() ) );
236  } catch ( const DOMException& e ) {
237  printError( "XML parse error[" + xmlFile + "]: " + _toString( e.getMessage() ) );
238  } catch ( ... ) {
239  printError( "UNKNOWN XML parse error in file " + xmlFile );
240  }
241 }
242 // ----------------------------------------------------------------------------
243 string XMLFileCatalog::lookupFID( const std::string& fid ) const
244 {
245  std::string result;
246  DOMNode* e = element( fid, false );
247  e = e ? e->getParentNode() : 0; // Mode up to <logical>
248  e = e ? e->getParentNode() : 0; // Mode up to <File>
249  if ( e ) {
250  if ( e->getAttributes() ) { // Need to check this. The node may be no DOMElement
251  char* nam = XMLString::transcode( ( (DOMElement*)e )->getAttribute( Attr_ID ) );
252  if ( nam ) result = nam;
253  XMLString::release( &nam );
254  }
255  }
256  return result;
257 }
258 // ----------------------------------------------------------------------------
259 void XMLFileCatalog::getFID( Strings& fids ) const
260 {
261  fids.clear();
262  DOMNode* fde = getDoc( true )->getElementsByTagName( XMLStr( "*" ) )->item( 0 );
263  for ( XMLCollection c( child( fde, "File" ), false ); c; ++c ) fids.push_back( c.attr( Attr_ID ) );
264 }
265 // ----------------------------------------------------------------------------
266 void XMLFileCatalog::getPFN( CSTR fid, Files& files ) const
267 {
268  files.clear();
269  for ( XMLCollection c( child( child( element( fid, false ), PFNCOLL ), PFNNODE ), false ); c; ++c )
270  files.emplace_back( c.attr( Attr_name ), c.attr( Attr_ftype ) );
271 }
272 // ----------------------------------------------------------------------------
273 void XMLFileCatalog::getLFN( CSTR fid, Files& files ) const
274 {
275  files.clear();
276  for ( XMLCollection c( child( child( element( fid, false ), LFNCOLL ), LFNNODE ), false ); c; ++c )
277  files.emplace_back( c.attr( Attr_name ), fid );
278 }
279 // ----------------------------------------------------------------------------
280 void XMLFileCatalog::getMetaData( CSTR fid, Attributes& attr ) const
281 {
282  attr.clear();
283  for ( XMLCollection c( child( element( fid ), MetaNode ), false ); c; ++c )
284  attr.emplace_back( c.attr( Attr_metaName ), c.attr( Attr_metaValue ) );
285  if ( attr.size() > 0 ) attr.emplace_back( "guid", fid );
286 }
287 // ----------------------------------------------------------------------------
288 DOMNode* XMLFileCatalog::child( DOMNode* par, CSTR tag, CSTR attr, CSTR val ) const
289 {
290  for ( XMLCollection c( par ); c; ++c ) {
291  if ( c.tag() == tag ) {
292  if ( !attr.empty() && c.attr( attr ) != val ) continue;
293  return c;
294  }
295  }
296  return 0;
297 }
298 // ----------------------------------------------------------------------------
299 void XMLFileCatalog::setMetaData( CSTR fid, CSTR attr, CSTR val ) const
300 {
301  if ( !readOnly() ) {
302  DOMNode* node = element( fid );
303  DOMElement* mnod = (DOMElement*)child( node, MetaNode, Attr_metaName, attr );
304  if ( !mnod ) {
305  mnod = getDoc( true )->createElement( MetaNode );
306  node->appendChild( mnod );
307  mnod->setAttribute( Attr_metaName, XMLStr( attr ) );
308  }
309  mnod->setAttribute( Attr_metaValue, XMLStr( val ) );
310  m_update = true;
311  return;
312  }
313  printError( "Cannot update readonly catalog!" );
314 }
315 // ----------------------------------------------------------------------------
316 string XMLFileCatalog::getMetaDataItem( CSTR fid, CSTR attr ) const
317 {
318  XMLCollection c( child( getDoc( true )->getElementById( XMLStr( fid ) ), MetaNode, Attr_metaName, attr ) );
319  return c ? c.attr( attr ) : string( "" );
320 }
321 // ----------------------------------------------------------------------------
322 void XMLFileCatalog::dropMetaData( CSTR fid, CSTR attr ) const
323 {
324  vector<DOMNode*> gbc;
325  DOMNode* fn = getDoc( true )->getElementById( XMLStr( fid ) );
326  for ( XMLCollection c{child( fn, MetaNode )}; c; ++c )
327  if ( attr[0] == '*' || !c.attr( attr ).empty() ) gbc.push_back( c );
328  for ( const auto& i : gbc ) fn->removeChild( i );
329 }
330 // ----------------------------------------------------------------------------
331 DOMNode* XMLFileCatalog::element( CSTR element_name, bool print_err ) const
332 {
333  DOMNode* node = getDoc( true )->getElementById( XMLStr( element_name ) );
334  if ( !node && print_err ) printError( "Cannot find element:" + element_name );
335  return node;
336 }
337 // ----------------------------------------------------------------------------
339 {
340  DOMNode *pn = nullptr, *fn = element( fid );
341  if ( fn ) pn = fn->getParentNode();
342  if ( pn ) pn->removeChild( fn );
343 }
344 // ----------------------------------------------------------------------------
346 {
347  if ( !fid.empty() ) {
349  if ( res.first == 0 || res.second == 0 ) {
350  printError( "Failed to register FID:" + fid );
351  }
352  return;
353  }
354  throw runtime_error( "XMLFileCatalog> Cannot register LFN for invalid FID:" + fid );
355 }
356 // ----------------------------------------------------------------------------
358 {
359  if ( readOnly() ) {
360  printError( "Cannot update readonly catalog!" );
361  return {nullptr, nullptr};
362  }
363 
365  DOMElement *file = (DOMElement *)element( fid, false ), *phyelem = 0, *logelem = 0;
366  DOMDocument* doc = getDoc( true );
367  if ( !file ) {
368  DOMNode* fde = doc->getElementsByTagName( XMLStr( "*" ) )->item( 0 );
369  file = m_doc->createElement( XMLStr( "File" ) );
370  file->setAttribute( Attr_ID, XMLStr( fid ) );
371  file->setIdAttribute( Attr_ID, true );
372  fde->appendChild( file );
373  m_update = true;
374  }
375  for ( XMLCollection c1( file ); c1; ++c1 ) {
376  char* nam = XMLString::transcode( c1->getNodeName() );
377  if ( nam == PFNCOLL ) phyelem = c1;
378  if ( nam == LFNCOLL ) logelem = c1;
379  XMLString::release( &nam );
380  }
381  if ( !phyelem ) {
382  phyelem = doc->createElement( PFNCOLL );
383  file->appendChild( phyelem );
384  m_update = true;
385  }
386  if ( !logelem ) {
387  logelem = doc->createElement( LFNCOLL );
388  file->appendChild( logelem );
389  m_update = true;
390  }
391  return {logelem, phyelem};
392 }
393 // ----------------------------------------------------------------------------
394 void XMLFileCatalog::registerPFN( CSTR fid, CSTR pfn, CSTR ftype ) const
395 {
396  if ( !fid.empty() ) {
398  DOMElement *phyelem = res.second, *fnelem = 0;
399  for ( XMLCollection c( phyelem ); c; ++c ) {
400  char* nam = XMLString::transcode( c->getNodeName() );
401  if ( nam == PFNNODE ) {
402  XMLString::release( &nam );
403  nam = XMLString::transcode( c->getAttribute( Attr_name ) );
404  if ( nam == pfn ) {
405  XMLString::release( &nam );
406  fnelem = c;
407  break;
408  }
409  }
410  XMLString::release( &nam );
411  }
412  if ( !fnelem ) {
413  fnelem = getDoc( true )->createElement( PFNNODE );
414  phyelem->appendChild( fnelem );
415  fnelem->setAttribute( Attr_ftype, XMLStr( ftype ) );
416  fnelem->setAttribute( Attr_name, XMLStr( pfn ) );
417  fnelem->setIdAttribute( Attr_name, true );
418  m_update = true;
419  }
420  return;
421  }
422  throw runtime_error( "XMLFileCatalog> Cannot register PFN for invalid FID:" + fid );
423 }
424 // ----------------------------------------------------------------------------
425 void XMLFileCatalog::registerLFN( CSTR fid, CSTR lfn ) const
426 {
427  if ( !fid.empty() ) {
429  DOMElement *logelem = res.first, *fnelem = 0;
430  for ( XMLCollection c( logelem ); c; ++c ) {
431  char* nam = XMLString::transcode( c->getNodeName() );
432  if ( nam == LFNNODE ) {
433  XMLString::release( &nam );
434  nam = XMLString::transcode( c->getAttribute( Attr_name ) );
435  if ( nam == lfn ) {
436  XMLString::release( &nam );
437  fnelem = c;
438  break;
439  }
440  }
441  }
442  if ( !fnelem ) {
443  fnelem = getDoc( true )->createElement( LFNNODE );
444  logelem->appendChild( fnelem );
445  fnelem->setAttribute( Attr_name, XMLStr( lfn ) );
446  fnelem->setIdAttribute( Attr_name, true );
447  m_update = true;
448  }
449  return;
450  }
451  throw runtime_error( "XMLFileCatalog> Cannot register LFN for invalid FID:" + fid );
452 }
453 // ----------------------------------------------------------------------------
455 {
456  try {
457  if ( dirty() && !readOnly() ) {
458  string xmlfile = getfile( true );
459  XMLStr ii( "LS" );
460  DOMImplementation* imp = DOMImplementationRegistry::getDOMImplementation( ii );
461  std::unique_ptr<XMLFormatTarget> tar{new LocalFileFormatTarget( xmlfile.c_str() )};
462 #if _XERCES_VERSION <= 30000
463  DOMWriter* wr = imp->createDOMWriter();
464  wr->setFeature( XMLUni::fgDOMWRTFormatPrettyPrint, true );
465  wr->writeNode( tar.get(), *m_doc );
466  wr->release();
467 #else
468  DOMLSOutput* output = imp->createLSOutput();
469  output->setByteStream( tar.get() );
470  DOMLSSerializer* wr = imp->createLSSerializer();
471  wr->getDomConfig()->setParameter( XMLStr( "format-pretty-print" ), true );
472  wr->write( m_doc, output );
473  output->release();
474  wr->release();
475 #endif
476  }
477  } catch ( exception& e ) {
478  printError( string( "Cannot open output file:" ) + e.what() );
479  } catch ( ... ) {
480  printError( "Unknown IO rrror." );
481  }
482 }
483 // ----------------------------------------------------------------------------
484 string XMLFileCatalog::getfile( bool create )
485 {
486  string protocol, path;
487  XMLURL xerurl;
488  try {
489  xerurl = (const XMLCh*)XMLStr( m_file );
490  protocol = _toString( xerurl.getProtocolName() );
491  path = _toString( xerurl.getPath() );
492  } catch ( const XMLException& e ) {
493  printError( _toString( e.getMessage() ) );
494  }
495  if ( protocol.empty() ) {
496  printError( "Missing protocol." );
497  } else if ( protocol == "http" || protocol == "ftp" ) {
498  m_rdOnly = true;
499  } else if ( protocol == "file" ) {
500  m_rdOnly = false;
501  struct stat buff;
502  int exist = ::stat( path.c_str(), &buff ) != -1;
503  if ( create && !exist ) {
504  MsgStream log( m_msgSvc, "XMLCatalog" );
505  log << MSG::INFO << "File '" << path << "' does not exist. New file created." << endmsg;
506  ofstream out{path};
507  if ( !m_rdOnly && out.is_open() ) {
508  out << (CSTR)EmptyCatalog << endl;
509  } else {
510  printError( "Problem creating file " + path );
511  }
512  out.close();
513  } else if ( exist ) {
514  return path;
515  } else if ( !create ) {
516  return "";
517  }
518  } else {
519  printError( protocol + ": protocol not supported." );
520  }
521  return path;
522 }
std::string getMetaDataItem(CSTR fid, CSTR name) const override
Access metadata item.
bool readOnly() const override
Check if the catalog is read-only.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
T empty(T...args)
void registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const override
Create a FileID and Node of the physical file name with all the attributes.
T endl(T...args)
std::string lookupFID(CSTR lfn) const
Gaudi::PluginService::Factory< IInterface *, const std::string &, IMessageSvc * > Factory
Definition: IFileCatalog.h:33
STL namespace.
std::string getfile(bool create)
xercesc::DOMNode * element(CSTR fid, bool print_err=true) const
std::unique_ptr< xercesc::XercesDOMParser > m_parser
T release(T...args)
STL class.
T push_back(T...args)
STL class.
const std::string & CSTR
T what(T...args)
T strlen(T...args)
xercesc::DOMNode * child(xercesc::DOMNode *par, CSTR tag, CSTR attr="", CSTR val="") const
bool operator==(const GaudiUtils::Allocator< T1 > &, const GaudiUtils::Allocator< T2 > &)
Definition: Allocator.h:246
constexpr double m
Definition: SystemOfUnits.h:94
void getMetaData(CSTR fid, Attributes &attr) const override
Dump all MetaData of the catalog for a given file ID.
void printError(CSTR msg, bool throw_exc=true) const
std::unique_ptr< xercesc::ErrorHandler > m_errHdlr
The IMessage is the interface implemented by the message service.
Definition: IMessageSvc.h:38
xercesc::DOMDocument * m_doc
xercesc::DOMDocument * getDoc(bool throw_if_no_exists=true) const
const std::string CSTR
T reset(T...args)
void getLFN(CSTR fid, Files &files) const override
Dump all logical file names of the catalog associate to the FileID.
#define DECLARE_FACTORY(type, factory)
Definition: PluginService.h:24
STL class.
T get(T...args)
T find(T...args)
T length(T...args)
void setMetaData(CSTR fid, CSTR name, CSTR value) const override
Insert/update metadata item.
STL class.
STL class.
std::string createGuidAsString()
Helper function creating file identifier using the UUID mechanism.
void registerLFN(CSTR fid, CSTR lfn) const override
Create a FileID and Node of the logical file name with all the attributes.
T c_str(T...args)
void commit() override
Save DOM catalog to file.
string s
Definition: gaudirun.py:253
std::pair< xercesc::DOMElement *, xercesc::DOMElement * > i_registerFID(CSTR fid) const
void init() override
Parse the DOM tree of the XML catalog.
IMessageSvc * m_msgSvc
void registerFID(CSTR fid) const override
Create a FileID and Node.
void getPFN(CSTR fid, Files &files) const override
Dump all physical file names of the catalog and their attributes associate to the FileID...
This class constitutes the core of the XML based FileCatalog API for POOL.
bool dirty() const override
Check if the catalog should be updated.
std::string createFID() const override
Catalog interface.
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
void getFID(Strings &fids) const override
Dump all file Identifiers.
void dropMetaData(CSTR fid) const override
Drop all metadata of one FID.
void deleteFID(CSTR FileID) const override
Delete FileID Node from the catalog.