The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
MultiFileCatalog.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#include "MultiFileCatalog.h"
12#include "createGuidAsString.h"
13#include <Gaudi/PluginService.h>
15#include <algorithm>
16#include <functional>
17#include <stdexcept>
18#include <strings.h>
19
20using namespace Gaudi;
21using namespace std;
22
23namespace {
24 template <typename C, typename F>
25 F for_each( C& c, F&& f ) {
26 return std::for_each( std::begin( c ), std::end( c ), std::forward<F>( f ) );
27 }
28} // namespace
29
31
32// ----------------------------------------------------------------------------
34 if ( !Service::initialize().isSuccess() ) {
35 printError( "Failed to initialize service base class.", false );
37 }
38 std::string current;
39 try {
40 for ( const auto& i : m_catalogNames ) {
41 current = i;
42 addCatalog( i );
43 }
44 init();
46 } catch ( const std::exception& /* e */ ) { printError( "Cannot add file catalog:" + current, false ); }
48}
49// ----------------------------------------------------------------------------
51 commit();
52 for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
53 m_catalogs.clear();
54 m_started = false;
55 return Service::finalize();
56}
57// ----------------------------------------------------------------------------
59std::string MultiFileCatalog::createFID() const { return createGuidAsString(); }
60// ----------------------------------------------------------------------------
62 static const string s( "MultiCatalog" );
63 return s;
64}
65// ----------------------------------------------------------------------------
66IFileCatalog* MultiFileCatalog::getCatalog( CSTR fid, bool throw_if_not, bool writable, bool prt ) const {
67 for ( const auto& c : m_catalogs ) {
68 if ( !c || ( writable && c->readOnly() ) ) continue;
69 if ( fid.empty() || ( !fid.empty() && c->existsFID( fid ) ) ) return c;
70 }
71 if ( prt ) {
72 printError( "No writable file catalog found which contains FID:" + fid, throw_if_not );
73 } else {
74 debug() << "No writable file catalog found which contains FID:" << fid << endmsg;
75 }
76 return nullptr;
77}
78// ----------------------------------------------------------------------------
79IFileCatalog* MultiFileCatalog::findCatalog( CSTR connect, bool must_be_writable ) const {
80 auto i = std::find_if( m_catalogs.begin(), m_catalogs.end(),
81 [&]( const IFileCatalog* f ) { return connect == f->connectInfo(); } );
82 return ( i != m_catalogs.end() && ( !must_be_writable || !( *i )->readOnly() ) ) ? *i : nullptr;
83}
84// ----------------------------------------------------------------------------
85MultiFileCatalog::Catalogs::iterator MultiFileCatalog::i_findCatalog( CSTR connect, bool must_be_writable ) {
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() ) { i = m_catalogs.end(); }
89 return i;
90}
91// ----------------------------------------------------------------------------
92void MultiFileCatalog::printError( CSTR msg, bool rethrow ) const {
93 if ( rethrow ) {
94 fatal() << msg << endmsg;
95 throw runtime_error( "Catalog> " + msg );
96 }
97 error() << msg << endmsg;
98}
99// ----------------------------------------------------------------------------
101 if ( !con.empty() ) {
102 if ( !findCatalog( con, false ) ) {
103 static const string xml_typ = "Gaudi::XMLFileCatalog";
104 auto id0 = con.find( "_" );
105 string typ = con.substr( 0, id0 );
106 string url = con.substr( id0 + 1 );
107 IInterface* cat = nullptr;
108 if ( strncasecmp( "xml", typ.c_str(), 3 ) == 0 ) {
109 cat = IFileCatalog::Factory::create( xml_typ, url, msgSvc().get() ).release();
110 } else {
111 using Gaudi::PluginService::Details::Registry;
112 Registry& registry = Registry::instance();
113 if ( registry.getInfo( typ ).factory.type() == typeid( Service::Factory::FactoryType ) ) {
114 cat = Service::Factory::create( typ, url, serviceLocator().get() ).release();
115 } else if ( registry.getInfo( typ ).factory.type() == typeid( IFileCatalog::Factory::FactoryType ) ) {
116 cat = IFileCatalog::Factory::create( typ, url, msgSvc().get() ).release();
117 }
118 }
119 if ( cat ) {
120 auto fileCat = SmartIF<IFileCatalog>( cat );
121 if ( fileCat ) {
122 addCatalog( fileCat.get() ); // addCatalog will take care of the refCount of fileCat...
123 return;
124 }
125 }
126 printError( "Failed to create catalog connection:" + con, true );
127 }
129 return;
130 }
131 printError( "Got invalid (empty) catalog connection string.", true );
132}
133// ----------------------------------------------------------------------------
135 if ( cat ) {
136 cat->addRef();
137 m_catalogs.push_back( cat );
138 return;
139 }
140 printError( "Got invalid catalog to be added to multi catalog.", true );
141}
142// ----------------------------------------------------------------------------
144 if ( con.empty() || con == "*" ) {
145 for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
146 m_catalogs.clear();
147 return;
148 }
149 removeCatalog( findCatalog( con, false ) );
150}
151// ----------------------------------------------------------------------------
153 if ( cat ) {
154 auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
155 if ( i != m_catalogs.end() ) {
156 ( *i )->release();
157 m_catalogs.erase( i );
158 return;
159 }
160 printError( "Unknown file catalog -- cannot be removed.", true );
161 }
162 printError( "Invalid file catalog.", true );
163}
164// ----------------------------------------------------------------------------
166 if ( cat ) {
167 if ( !cat->readOnly() ) {
168 auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
169 if ( i != m_catalogs.end() ) {
170 m_catalogs.erase( i );
171 m_catalogs.insert( m_catalogs.begin(), cat );
172 return;
173 }
174 printError( "The catalog " + cat->connectInfo() + " is not known.", true );
175 }
176 printError( "The catalog " + cat->connectInfo() + " is not writable.", true );
177 }
178 printError( "Invalid file catalog.", true );
179}
180// ----------------------------------------------------------------------------
182 auto i = i_findCatalog( connect, true );
183 if ( i == m_catalogs.end() ) {
184 addCatalog( connect );
185 setWriteCatalog( findCatalog( connect, true ) );
186 return;
187 }
188 setWriteCatalog( *i );
189}
190// ----------------------------------------------------------------------------
191string MultiFileCatalog::getMetaDataItem( CSTR fid, CSTR attr ) const {
192 std::string result;
193 for ( const auto& i : m_catalogs ) {
194 result = i->getMetaDataItem( fid, attr );
195 if ( !result.empty() ) break;
196 }
197 return result;
198}
199
200void MultiFileCatalog::registerPFN( CSTR fid, CSTR pfn, CSTR ftype ) const {
201 IFileCatalog* c = getCatalog( fid, false, true, false );
202 if ( !c ) c = getCatalog( "", true, true, true );
203 c->registerPFN( fid, pfn, ftype );
204}
205
207 IFileCatalog* c = getCatalog( fid, false, true, false );
208 if ( !c ) c = getCatalog( "", true, true, true );
209 c->registerLFN( fid, lfn );
210}
211// ----------------------------------------------------------------------------
213 return std::all_of( std::begin( m_catalogs ), std::end( m_catalogs ),
214 []( const IFileCatalog* i ) { return i->readOnly(); } );
215}
216// ----------------------------------------------------------------------------
218 return std::any_of( std::begin( m_catalogs ), std::end( m_catalogs ),
219 []( const IFileCatalog* i ) { return i->dirty(); } );
220}
221// ----------------------------------------------------------------------------
223 for_each( m_catalogs, []( IFileCatalog* i ) { i->init(); } );
224 m_started = true;
225}
226// ----------------------------------------------------------------------------
228 for_each( m_catalogs, []( IFileCatalog* i ) { i->commit(); } );
229}
230// ----------------------------------------------------------------------------
232 for_each( m_catalogs, []( IFileCatalog* i ) { i->rollback(); } );
233}
234// ----------------------------------------------------------------------------
236 // not yet initialized
237 if ( !m_started ) {
239 return;
240 } // RETURN
241 // no real change - no action
242 if ( m_catalogNames == m_oldNames ) { return; }
244 // remove ALL catalogs
245 removeCatalog( "" );
246 // add new catalogs
247 for ( const auto& inew : m_catalogNames ) addCatalog( inew );
248 // start
249 init();
250 //
251 debug() << "New catalogs to be used: " << Gaudi::Utils::toString( m_catalogNames ) << endmsg;
252}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
File catalog interface.
virtual void rollback()=0
Save catalog to file.
virtual bool readOnly() const =0
Check if the catalog is read-only.
virtual bool dirty() const =0
Check if the catalog should be updated.
virtual void commit()=0
Save catalog to file.
virtual void init()=0
Parse the DOM tree of the XML catalog.
virtual const std::string & connectInfo() const =0
Access to connect string.
This class constitutes the core of the XML based FileCatalog API for using POOL within Gaudi.
void removeCatalog(CSTR connect) override
Remove catalog identified by name from the existing ones.
void registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const override
Create a FileID and DOM Node of the PFN with all the attributes.
bool dirty() const override
Check if the catalog should be updated.
Catalogs::iterator i_findCatalog(CSTR connect, bool must_be_writable)
Find catalog by connect string.
bool m_started
Flag to indicate if catalog is started.
std::string createFID() const override
Catalog interface.
void propHandler()
simple property handle to allow interactive modification of list of the file catalogs
Catalogs m_catalogs
Container with references to known catalogs.
CSTR connectInfo() const override
Access to connect string.
StatusCode finalize() override
Finalize service object.
void setWriteCatalog(IFileCatalog *cat) override
Define the writable catalog identified by reference.
bool readOnly() const override
Check if the catalog is read-only.
IFileCatalog * getCatalog(CSTR fid, bool throw_if_not, bool writable=true, bool prt=true) const
Find catalog containing a given file identifier.
IFileCatalog * findCatalog(CSTR connect, bool must_be_writable) const override
Catalog management.
void rollback() override
Save DOM catalog to file.
Gaudi::Property< CatalogNames > m_catalogNames
void addCatalog(CSTR connect) override
Add new catalog identified by name to the existing ones.
void commit() override
Save DOM catalog to file.
const std::string & CSTR
void registerLFN(CSTR fid, CSTR lfn) const override
Create a FileID and DOM Node of the LFN with all the attributes.
StatusCode initialize() override
IService implementation.
CatalogNames m_oldNames
BACKUP:: Container with catalog names.
void init() override
Parse the DOM tree of the XML catalog.
std::string getMetaDataItem(CSTR fid, CSTR name) const override
Access metadata item.
void printError(CSTR msg, bool throw_exc=true) const
Definition of the basic interface.
Definition IInterface.h:225
virtual unsigned long addRef() const =0
Increment the reference count of Interface instance.
virtual unsigned long release() const =0
Release Interface instance.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition Service.cpp:336
StatusCode finalize() override
Definition Service.cpp:223
StatusCode initialize() override
Definition Service.cpp:118
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition ToStream.h:326
void for_each(ContainerOfSynced &c, Fun &&f)
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
std::string createGuidAsString()
Helper function creating file identifier using the UUID mechanism.
STL namespace.