Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MultiFileCatalog.cpp
Go to the documentation of this file.
1 #include "MultiFileCatalog.h"
4 #include "createGuidAsString.h"
5 #include <Gaudi/PluginService.h>
6 #include <algorithm>
7 #include <functional>
8 #include <stdexcept>
9 
10 using namespace Gaudi;
11 using namespace std;
12 
13 namespace {
14  template <typename C, typename F>
15  F for_each( C& c, F&& f ) {
16  return std::for_each( std::begin( c ), std::end( c ), std::forward<F>( f ) );
17  }
18 } // namespace
19 
21 
22 // ----------------------------------------------------------------------------
24  if ( !Service::initialize().isSuccess() ) {
25  printError( "Failed to initialize service base class.", false );
26  return StatusCode::SUCCESS;
27  }
28  std::string current;
29  try {
30  for ( const auto& i : m_catalogNames ) {
31  current = i;
32  addCatalog( i );
33  }
34  init();
35  return StatusCode::SUCCESS;
36  } catch ( const std::exception& /* e */ ) { printError( "Cannot add file catalog:" + current, false ); }
37  return StatusCode::FAILURE;
38 }
39 // ----------------------------------------------------------------------------
41  commit();
42  for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
43  m_catalogs.clear();
44  m_started = false;
45  return Service::finalize();
46 }
47 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52  static const string s( "MultiCatalog" );
53  return s;
54 }
55 // ----------------------------------------------------------------------------
56 IFileCatalog* MultiFileCatalog::getCatalog( CSTR fid, bool throw_if_not, bool writable, bool prt ) const {
57  for ( const auto& c : m_catalogs ) {
58  if ( !c || ( writable && c->readOnly() ) ) continue;
59  if ( fid.empty() || ( !fid.empty() && c->existsFID( fid ) ) ) return c;
60  }
61  if ( prt ) {
62  printError( "No writable file catalog found which contains FID:" + fid, throw_if_not );
63  } else {
64  debug() << "No writable file catalog found which contains FID:" << fid << endmsg;
65  }
66  return nullptr;
67 }
68 // ----------------------------------------------------------------------------
69 IFileCatalog* MultiFileCatalog::findCatalog( CSTR connect, bool must_be_writable ) const {
70  auto i = std::find_if( m_catalogs.begin(), m_catalogs.end(),
71  [&]( const IFileCatalog* f ) { return connect == f->connectInfo(); } );
72  return ( i != m_catalogs.end() && ( !must_be_writable || !( *i )->readOnly() ) ) ? *i : nullptr;
73 }
74 // ----------------------------------------------------------------------------
75 MultiFileCatalog::Catalogs::iterator MultiFileCatalog::i_findCatalog( CSTR connect, bool must_be_writable ) {
76  auto i = std::find_if( m_catalogs.begin(), m_catalogs.end(),
77  [&]( const IFileCatalog* f ) { return connect == f->connectInfo(); } );
78  if ( i != m_catalogs.end() && must_be_writable && ( *i )->readOnly() ) { i = m_catalogs.end(); }
79  return i;
80 }
81 // ----------------------------------------------------------------------------
82 void MultiFileCatalog::printError( CSTR msg, bool rethrow ) const {
83  if ( rethrow ) {
84  fatal() << msg << endmsg;
85  throw runtime_error( "Catalog> " + msg );
86  }
87  error() << msg << endmsg;
88 }
89 // ----------------------------------------------------------------------------
91  if ( !con.empty() ) {
92  if ( !findCatalog( con, false ) ) {
93  static const string xml_typ = "Gaudi::XMLFileCatalog";
94  auto id0 = con.find( "_" );
95  string typ = con.substr( 0, id0 );
96  string url = con.substr( id0 + 1 );
97  IInterface* cat = nullptr;
98  if ( strncasecmp( "xml", typ.c_str(), 3 ) == 0 ) {
99  cat = IFileCatalog::Factory::create( xml_typ, url, msgSvc().get() ).release();
100  } else {
101  using Gaudi::PluginService::Details::Registry;
102  Registry& registry = Registry::instance();
103  if ( registry.getInfo( typ ).factory.type() == typeid( Service::Factory::FactoryType ) ) {
104  cat = Service::Factory::create( typ, url, serviceLocator().get() ).release();
105  } else if ( registry.getInfo( typ ).factory.type() == typeid( IFileCatalog::Factory::FactoryType ) ) {
106  cat = IFileCatalog::Factory::create( typ, url, msgSvc().get() ).release();
107  }
108  }
109  if ( cat ) {
110  auto fileCat = SmartIF<IFileCatalog>( cat );
111  if ( fileCat ) {
112  addCatalog( fileCat.get() ); // addCatalog will take care of the refCount of fileCat...
113  return;
114  }
115  }
116  printError( "Failed to create catalog connection:" + con, true );
117  }
119  return;
120  }
121  printError( "Got invalid (empty) catalog connection string.", true );
122 }
123 // ----------------------------------------------------------------------------
125  if ( cat ) {
126  cat->addRef();
127  m_catalogs.push_back( cat );
128  return;
129  }
130  printError( "Got invalid catalog to be added to multi catalog.", true );
131 }
132 // ----------------------------------------------------------------------------
134  if ( con.empty() || con == "*" ) {
135  for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
136  m_catalogs.clear();
137  return;
138  }
139  removeCatalog( findCatalog( con, false ) );
140 }
141 // ----------------------------------------------------------------------------
143  if ( cat ) {
144  auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
145  if ( i != m_catalogs.end() ) {
146  ( *i )->release();
147  m_catalogs.erase( i );
148  return;
149  }
150  printError( "Unknown file catalog -- cannot be removed.", true );
151  }
152  printError( "Invalid file catalog.", true );
153 }
154 // ----------------------------------------------------------------------------
156  if ( cat ) {
157  if ( !cat->readOnly() ) {
158  auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
159  if ( i != m_catalogs.end() ) {
160  m_catalogs.erase( i );
161  m_catalogs.insert( m_catalogs.begin(), cat );
162  return;
163  }
164  printError( "The catalog " + cat->connectInfo() + " is not known.", true );
165  }
166  printError( "The catalog " + cat->connectInfo() + " is not writable.", true );
167  }
168  printError( "Invalid file catalog.", true );
169 }
170 // ----------------------------------------------------------------------------
172  auto i = i_findCatalog( connect, true );
173  if ( i == m_catalogs.end() ) {
174  addCatalog( connect );
175  setWriteCatalog( findCatalog( connect, true ) );
176  return;
177  }
178  setWriteCatalog( *i );
179 }
180 // ----------------------------------------------------------------------------
181 string MultiFileCatalog::getMetaDataItem( CSTR fid, CSTR attr ) const {
182  std::string result;
183  for ( const auto& i : m_catalogs ) {
184  result = i->getMetaDataItem( fid, attr );
185  if ( !result.empty() ) break;
186  }
187  return result;
188 }
190 void MultiFileCatalog::registerPFN( CSTR fid, CSTR pfn, CSTR ftype ) const {
191  IFileCatalog* c = getCatalog( fid, false, true, false );
192  if ( !c ) c = getCatalog( "", true, true, true );
193  c->registerPFN( fid, pfn, ftype );
194 }
196 void MultiFileCatalog::registerLFN( CSTR fid, CSTR lfn ) const {
197  IFileCatalog* c = getCatalog( fid, false, true, false );
198  if ( !c ) c = getCatalog( "", true, true, true );
199  c->registerLFN( fid, lfn );
200 }
201 // ----------------------------------------------------------------------------
203  return std::all_of( std::begin( m_catalogs ), std::end( m_catalogs ),
204  []( const IFileCatalog* i ) { return i->readOnly(); } );
205 }
206 // ----------------------------------------------------------------------------
208  return std::any_of( std::begin( m_catalogs ), std::end( m_catalogs ),
209  []( const IFileCatalog* i ) { return i->dirty(); } );
210 }
211 // ----------------------------------------------------------------------------
213  for_each( m_catalogs, []( IFileCatalog* i ) { i->init(); } );
214  m_started = true;
215 }
216 // ----------------------------------------------------------------------------
218  for_each( m_catalogs, []( IFileCatalog* i ) { i->commit(); } );
219 }
220 // ----------------------------------------------------------------------------
222  for_each( m_catalogs, []( IFileCatalog* i ) { i->rollback(); } );
223 }
224 // ----------------------------------------------------------------------------
226  // not yet initialized
227  if ( !m_started ) {
228  m_oldNames = m_catalogNames;
229  return;
230  } // RETURN
231  // no real change - no action
232  if ( m_catalogNames == m_oldNames ) { return; }
233  m_oldNames = m_catalogNames;
234  // remove ALL catalogs
235  removeCatalog( "" );
236  // add new catalogs
237  for ( const auto& inew : m_catalogNames ) addCatalog( inew );
238  // start
239  init();
240  //
241  debug() << "New catalogs to be used: " << Gaudi::Utils::toString( m_catalogNames ) << endmsg;
242 }
StatusCode initialize() override
Definition: Service.cpp:60
Small smart pointer class with automatic reference counting for IInterface.
Definition: IConverter.h:15
T empty(T...args)
std::string createFID() const override
Catalog interface.
StatusCode finalize() override
Definition: Service.cpp:164
void registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const override
Create a FileID and DOM Node of the PFN with all the attributes.
std::string getMetaDataItem(CSTR fid, CSTR name) const override
Access metadata item.
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:334
void printError(CSTR msg, bool throw_exc=true) const
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
virtual void commit()=0
Save catalog to file.
STL namespace.
virtual const std::string & connectInfo() const =0
Access to connect string.
void setWriteCatalog(IFileCatalog *cat) override
Define the writable catalog identified by reference.
T end(T...args)
STL class.
#define DECLARE_COMPONENT(type)
virtual bool readOnly() const =0
Check if the catalog is read-only.
Catalogs::iterator i_findCatalog(CSTR connect, bool must_be_writable)
Find catalog by connect string.
IFileCatalog * getCatalog(CSTR fid, bool throw_if_not, bool writable=true, bool prt=true) const
Find catalog containing a given file identifier.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
Definition of the basic interface.
Definition: IInterface.h:244
STL class.
CSTR connectInfo() const override
Access to connect string.
File catalog interface.
Definition: IFileCatalog.h:26
void registerLFN(CSTR fid, CSTR lfn) const override
Create a FileID and DOM Node of the LFN with all the attributes.
T find_if(T...args)
IFileCatalog * findCatalog(CSTR connect, bool must_be_writable) const override
Catalog management.
virtual unsigned long release()=0
Release Interface instance.
std::string createGuidAsString()
Helper function creating file identifier using the UUID mechanism.
bool dirty() const override
Check if the catalog should be updated.
T begin(T...args)
void rollback() override
Save DOM catalog to file.
StatusCode finalize() override
Finalize service object.
T all_of(T...args)
T c_str(T...args)
void init() override
Parse the DOM tree of the XML catalog.
void addCatalog(CSTR connect) override
Add new catalog identified by name to the existing ones.
string s
Definition: gaudirun.py:312
virtual void rollback()=0
Save catalog to file.
constexpr static const auto FAILURE
Definition: StatusCode.h:86
void propHandler()
simple property handle to allow interactive modification of list of the file catalogs ...
bool readOnly() const override
Check if the catalog is read-only.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
T substr(T...args)
virtual void registerPFN(const std::string &fid, const std::string &pfn, const std::string &ftype) const =0
Create a Node for a FileID and DOM Node of the PFN with all the attributes.
virtual void init()=0
Parse the DOM tree of the XML catalog.
virtual void registerLFN(const std::string &fid, const std::string &lfn) const =0
Create a Node for a FileID and DOM Node of the LFN with all the attributes.
T for_each(T...args)
void commit() override
Save DOM catalog to file.
void removeCatalog(CSTR connect) override
Remove catalog identified by name from the existing ones.
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:192
virtual bool dirty() const =0
Check if the catalog should be updated.
This class constitutes the core of the XML based FileCatalog API for using POOL within Gaudi...