The Gaudi Framework  v30r4 (9b837755)
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 {
15  template <typename C, typename F>
16  F for_each( C& c, F&& f )
17  {
18  return std::for_each( std::begin( c ), std::end( c ), std::forward<F>( f ) );
19  }
20 }
21 
23 
24 // ----------------------------------------------------------------------------
26 {
27  if ( !Service::initialize().isSuccess() ) {
28  printError( "Failed to initialize service base class.", false );
29  return StatusCode::SUCCESS;
30  }
31  std::string current;
32  try {
33  for ( const auto& i : m_catalogNames ) {
34  current = i;
35  addCatalog( i );
36  }
37  init();
38  return StatusCode::SUCCESS;
39  } catch ( const std::exception& /* e */ ) {
40  printError( "Cannot add file catalog:" + current, false );
41  }
42  return StatusCode::FAILURE;
43 }
44 // ----------------------------------------------------------------------------
46 {
47  commit();
48  for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
49  m_catalogs.clear();
50  m_started = false;
51  return Service::finalize();
52 }
53 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 {
59  static const string s( "MultiCatalog" );
60  return s;
61 }
62 // ----------------------------------------------------------------------------
63 IFileCatalog* MultiFileCatalog::getCatalog( CSTR fid, bool throw_if_not, bool writable, bool prt ) const
64 {
65  for ( const auto& c : m_catalogs ) {
66  if ( !c || ( writable && c->readOnly() ) ) continue;
67  if ( fid.empty() || ( !fid.empty() && c->existsFID( fid ) ) ) return c;
68  }
69  if ( prt ) {
70  printError( "No writable file catalog found which contains FID:" + fid, throw_if_not );
71  } else {
72  debug() << "No writable file catalog found which contains FID:" << fid << endmsg;
73  }
74  return nullptr;
75 }
76 // ----------------------------------------------------------------------------
77 IFileCatalog* MultiFileCatalog::findCatalog( CSTR connect, bool must_be_writable ) const
78 {
79  auto i = std::find_if( m_catalogs.begin(), m_catalogs.end(),
80  [&]( const IFileCatalog* f ) { return connect == f->connectInfo(); } );
81  return ( i != m_catalogs.end() && ( !must_be_writable || !( *i )->readOnly() ) ) ? *i : nullptr;
82 }
83 // ----------------------------------------------------------------------------
84 MultiFileCatalog::Catalogs::iterator MultiFileCatalog::i_findCatalog( CSTR connect, bool must_be_writable )
85 {
86  auto i = std::find_if( m_catalogs.begin(), m_catalogs.end(),
87  [&]( const IFileCatalog* f ) { return connect == f->connectInfo(); } );
88  if ( i != m_catalogs.end() && must_be_writable && ( *i )->readOnly() ) {
89  i = m_catalogs.end();
90  }
91  return i;
92 }
93 // ----------------------------------------------------------------------------
94 void MultiFileCatalog::printError( CSTR msg, bool rethrow ) const
95 {
96  if ( rethrow ) {
97  fatal() << msg << endmsg;
98  throw runtime_error( "Catalog> " + msg );
99  }
100  error() << msg << endmsg;
101 }
102 // ----------------------------------------------------------------------------
104 {
105  if ( !con.empty() ) {
106  if ( !findCatalog( con, false ) ) {
107  static const string xml_typ = "Gaudi::XMLFileCatalog";
108  auto id0 = con.find( "_" );
109  string typ = con.substr( 0, id0 );
110  string url = con.substr( id0 + 1 );
111  IInterface* cat = nullptr;
112  if ( strncasecmp( "xml", typ.c_str(), 3 ) == 0 ) {
113  cat = IFileCatalog::Factory::create( xml_typ, url, msgSvc().get() ).release();
114  } else {
115  using Gaudi::PluginService::Details::Registry;
116  Registry& registry = Registry::instance();
117  if ( registry.getInfo( typ ).factory.type() == typeid( Service::Factory::FactoryType ) ) {
118  cat = Service::Factory::create( typ, url, serviceLocator().get() ).release();
119  } else if ( registry.getInfo( typ ).factory.type() == typeid( IFileCatalog::Factory::FactoryType ) ) {
120  cat = IFileCatalog::Factory::create( typ, url, msgSvc().get() ).release();
121  }
122  }
123  if ( cat ) {
124  auto fileCat = SmartIF<IFileCatalog>( cat );
125  if ( fileCat ) {
126  addCatalog( fileCat.get() ); // addCatalog will take care of the refCount of fileCat...
127  return;
128  }
129  }
130  printError( "Failed to create catalog connection:" + con, true );
131  }
133  return;
134  }
135  printError( "Got invalid (empty) catalog connection string.", true );
136 }
137 // ----------------------------------------------------------------------------
139 {
140  if ( cat ) {
141  cat->addRef();
142  m_catalogs.push_back( cat );
143  return;
144  }
145  printError( "Got invalid catalog to be added to multi catalog.", true );
146 }
147 // ----------------------------------------------------------------------------
149 {
150  if ( con.empty() || con == "*" ) {
151  for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
152  m_catalogs.clear();
153  return;
154  }
155  removeCatalog( findCatalog( con, false ) );
156 }
157 // ----------------------------------------------------------------------------
159 {
160  if ( cat ) {
161  auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
162  if ( i != m_catalogs.end() ) {
163  ( *i )->release();
164  m_catalogs.erase( i );
165  return;
166  }
167  printError( "Unknown file catalog -- cannot be removed.", true );
168  }
169  printError( "Invalid file catalog.", true );
170 }
171 // ----------------------------------------------------------------------------
173 {
174  if ( cat ) {
175  if ( !cat->readOnly() ) {
176  auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
177  if ( i != m_catalogs.end() ) {
178  m_catalogs.erase( i );
179  m_catalogs.insert( m_catalogs.begin(), cat );
180  return;
181  }
182  printError( "The catalog " + cat->connectInfo() + " is not known.", true );
183  }
184  printError( "The catalog " + cat->connectInfo() + " is not writable.", true );
185  }
186  printError( "Invalid file catalog.", true );
187 }
188 // ----------------------------------------------------------------------------
190 {
191  auto i = i_findCatalog( connect, true );
192  if ( i == m_catalogs.end() ) {
193  addCatalog( connect );
194  setWriteCatalog( findCatalog( connect, true ) );
195  return;
196  }
197  setWriteCatalog( *i );
198 }
199 // ----------------------------------------------------------------------------
200 string MultiFileCatalog::getMetaDataItem( CSTR fid, CSTR attr ) const
201 {
202  std::string result;
203  for ( const auto& i : m_catalogs ) {
204  result = i->getMetaDataItem( fid, attr );
205  if ( !result.empty() ) break;
206  }
207  return result;
208 }
210 void MultiFileCatalog::registerPFN( CSTR fid, CSTR pfn, CSTR ftype ) const
211 {
212  IFileCatalog* c = getCatalog( fid, false, true, false );
213  if ( !c ) c = getCatalog( "", true, true, true );
214  c->registerPFN( fid, pfn, ftype );
215 }
218 {
219  IFileCatalog* c = getCatalog( fid, false, true, false );
220  if ( !c ) c = getCatalog( "", true, true, true );
221  c->registerLFN( fid, lfn );
222 }
223 // ----------------------------------------------------------------------------
225 {
226  return std::all_of( std::begin( m_catalogs ), std::end( m_catalogs ),
227  []( const IFileCatalog* i ) { return i->readOnly(); } );
228 }
229 // ----------------------------------------------------------------------------
231 {
232  return std::any_of( std::begin( m_catalogs ), std::end( m_catalogs ),
233  []( const IFileCatalog* i ) { return i->dirty(); } );
234 }
235 // ----------------------------------------------------------------------------
237 {
238  for_each( m_catalogs, []( IFileCatalog* i ) { i->init(); } );
239  m_started = true;
240 }
241 // ----------------------------------------------------------------------------
243 {
244  for_each( m_catalogs, []( IFileCatalog* i ) { i->commit(); } );
245 }
246 // ----------------------------------------------------------------------------
248 {
249  for_each( m_catalogs, []( IFileCatalog* i ) { i->rollback(); } );
250 }
251 // ----------------------------------------------------------------------------
253 {
254  // not yet initialized
255  if ( !m_started ) {
256  m_oldNames = m_catalogNames;
257  return;
258  } // RETURN
259  // no real change - no action
260  if ( m_catalogNames == m_oldNames ) {
261  return;
262  }
263  m_oldNames = m_catalogNames;
264  // remove ALL catalogs
265  removeCatalog( "" );
266  // add new catalogs
267  for ( const auto& inew : m_catalogNames ) addCatalog( inew );
268  // start
269  init();
270  //
271  debug() << "New catalogs to be used: " << Gaudi::Utils::toString( m_catalogNames ) << endmsg;
272 }
constexpr static const auto FAILURE
Definition: StatusCode.h:88
StatusCode initialize() override
Definition: Service.cpp:63
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:173
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:356
void printError(CSTR msg, bool throw_exc=true) const
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:51
Definition of the basic interface.
Definition: IInterface.h:277
STL class.
CSTR connectInfo() const override
Access to connect string.
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
File catalog interface.
Definition: IFileCatalog.h:27
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:253
virtual void rollback()=0
Save catalog to file.
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:209
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...