All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MultiFileCatalog.cpp
Go to the documentation of this file.
3 #include <Gaudi/PluginService.h>
4 #include "MultiFileCatalog.h"
5 #include <stdexcept>
6 #include <algorithm>
7 
8 namespace Gaudi { std::string createGuidAsString(); }
9 
10 using namespace Gaudi;
11 using namespace std;
12 
14 
15 namespace {
16  template <class V,class F>
17  bool _findX0Bool(V& array, F pmf, bool invert) {
18  for(typename V::const_iterator i=array.begin(); i != array.end(); ++i) {
19  bool res = invert ? !((*i)->*pmf)() : ((*i)->*pmf)();
20  if ( !res ) return false;
21  }
22  return true;
23  }
24 }
25 // ----------------------------------------------------------------------------
26 MultiFileCatalog::MultiFileCatalog(const std::string& nam, ISvcLocator* svc)
27  : base_class(nam, svc), m_started(false), m_oldNames()
28 {
29  declareProperty("Catalogs", m_catalogNames, "The list of Catalogs")
30  -> declareUpdateHandler ( &Gaudi::MultiFileCatalog::propHandler, this ) ;
31  m_catalogNames.push_back("xmlcatalog_file:test_catalog.xml");
32 }
33 // ----------------------------------------------------------------------------
35 }
36 // ----------------------------------------------------------------------------
38  CatalogNames::const_iterator i;
39  std::string current = "";
40  if ( !Service::initialize().isSuccess() ) {
41  printError("Failed to initialize service base class.",false);
42  return StatusCode::SUCCESS;
43  }
44  try {
45  for(i=m_catalogNames.begin(); i != m_catalogNames.end(); ++i) {
46  current = *i;
47  addCatalog(*i);
48  }
49  init();
50  return StatusCode::SUCCESS;
51  }
52  catch(const std::exception& /* e */) {
53  printError("Cannot add file catalog:"+current,false);
54  }
55  return StatusCode::FAILURE;
56 }
57 // ----------------------------------------------------------------------------
59  commit();
61  m_catalogs.clear();
62  m_started = false;
63  return Service::finalize();
64 }
65 // ----------------------------------------------------------------------------
67 std::string MultiFileCatalog::createFID() const {
68  return createGuidAsString();
69 }
70 // ----------------------------------------------------------------------------
72  static string s("MultiCatalog");
73  return s;
74 }
75 // ----------------------------------------------------------------------------
77  bool throw_if_not,
78  bool writable,
79  bool prt) const
80 {
81  for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) {
82  IFileCatalog* c = *i;
83  if ( c ) {
84  if ( writable && c->readOnly() )
85  continue;
86  else if ( fid.empty() )
87  return c;
88  else if ( !fid.empty() && c->existsFID(fid) )
89  return c;
90  }
91  }
92  if ( prt ) {
93  printError("No writable file catalog found which contains FID:"+fid,throw_if_not);
94  }
95  else {
96  MsgStream log(msgSvc(),name());
97  log << MSG::DEBUG << "No writable file catalog found which contains FID:" << fid << endmsg;
98  }
99  return 0;
100 }
101 // ----------------------------------------------------------------------------
102 IFileCatalog* MultiFileCatalog::findCatalog(CSTR connect, bool must_be_writable) const {
103  for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) {
104  if ( connect == (*i)->connectInfo() )
105  return (must_be_writable && (*i)->readOnly()) ? 0 : *i;
106  }
107  return 0;
108 }
109 // ----------------------------------------------------------------------------
110 MultiFileCatalog::Catalogs::iterator
111 MultiFileCatalog::i_findCatalog(CSTR connect, bool must_be_writable) {
112  for(Catalogs::iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) {
113  if ( connect == (*i)->connectInfo() ) {
114  return (must_be_writable && (*i)->readOnly()) ? m_catalogs.end() : i;
115  }
116  }
117  return m_catalogs.end();
118 }
119 // ----------------------------------------------------------------------------
120 void MultiFileCatalog::printError(CSTR msg, bool rethrow) const {
121  MsgStream log(msgSvc(),name());
122  if ( rethrow ) {
123  log << MSG::FATAL << msg << endmsg;
124  throw runtime_error("Catalog> "+msg);
125  }
126  log << MSG::ERROR << msg << endmsg;
127 }
128 // ----------------------------------------------------------------------------
130  if ( !con.empty() ) {
131  if ( 0 == findCatalog(con,false) ) {
132  static const string xml_typ = "Gaudi::XMLFileCatalog";
133  string::size_type id0 = con.find("_");
134  string typ = con.substr(0,id0);
135  string url = con.substr(id0+1);
136  IInterface* cat = 0;
137  if ( strncasecmp("xml",typ.c_str(),3) == 0 ) {
138  cat = IFileCatalog::Factory::create(xml_typ,url,msgSvc().get());
139  }
140  else {
142  Registry& registry = Registry::instance();
143  if (registry.getInfo(typ).type ==
144  typeid(Service::Factory::FuncType).name()) {
145  cat = Service::Factory::create(typ,url,serviceLocator().get());
146  } else if (registry.getInfo(typ).type ==
147  typeid(IFileCatalog::Factory::FuncType).name()) {
148  cat = IFileCatalog::Factory::create(typ,url,msgSvc().get());
149  }
150  }
151  if ( cat ) {
152  IFileCatalog* fileCat = 0;
153  if ( cat->queryInterface(IFileCatalog::interfaceID(),pp_cast<void>(&fileCat)).isSuccess() ) {
154  addCatalog(fileCat);
155  cat->release();
156  return;
157  }
158  }
159  printError("Failed to create catalog connection:"+con,true);
160  }
162  return;
163  }
164  printError("Got invalid (empty) catalog connection string.",true);
165 }
166 // ----------------------------------------------------------------------------
168  if ( cat ) {
169  cat->addRef();
170  m_catalogs.push_back(cat);
171  return;
172  }
173  printError("Got invalid catalog to be added to multi catalog.",true);
174 }
175 // ----------------------------------------------------------------------------
177  if ( con.empty() || con == "*" ) {
179  m_catalogs.clear();
180  return;
181  }
182  removeCatalog(findCatalog(con,false));
183 }
184 // ----------------------------------------------------------------------------
186  if ( cat ) {
187  Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat);
188  if ( i != m_catalogs.end() ) {
189  (*i)->release();
190  m_catalogs.erase(i);
191  return;
192  }
193  printError("Unknown file catalog -- cannot be removed.",true);
194  }
195  printError("Invalid file catalog.",true);
196 }
197 // ----------------------------------------------------------------------------
199  if ( cat ) {
200  if ( !cat->readOnly() ) {
201  Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat);
202  if ( i != m_catalogs.end() ) {
203  m_catalogs.erase(i);
204  m_catalogs.insert(m_catalogs.begin(),cat);
205  return;
206  }
207  printError("The catalog "+cat->connectInfo()+" is not known.",true);
208  }
209  printError("The catalog "+cat->connectInfo()+" is not writable.",true);
210  }
211  printError("Invalid file catalog.",true);
212 }
213 // ----------------------------------------------------------------------------
215  Catalogs::iterator i = i_findCatalog(connect,true);
216  if ( i == m_catalogs.end() ) {
217  addCatalog(connect);
218  setWriteCatalog(findCatalog(connect,true));
219  return;
220  }
221  setWriteCatalog(*i);
222 }
223 // ----------------------------------------------------------------------------
225  std::string result;
226  for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i)
227  if ( !(result= (*i)->getMetaDataItem(fid,attr)).empty() ) break;
228  return result;
229 }
231 void MultiFileCatalog::registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const {
232  IFileCatalog* c = getCatalog(fid,false,true,false);
233  if ( !c ) c = getCatalog("",true,true,true);
234  c->registerPFN(fid, pfn, ftype);
235 }
238  IFileCatalog* c = getCatalog(fid,false,true,false);
239  if ( !c ) c = getCatalog("",true,true,true);
240  c->registerLFN(fid, lfn);
241 }
242 // ----------------------------------------------------------------------------
244 { return _findX0Bool(m_catalogs,&IFileCatalog::readOnly,false); }
245 // ----------------------------------------------------------------------------
247 { return _findX0Bool(m_catalogs,&IFileCatalog::dirty,true); }
248 // ----------------------------------------------------------------------------
250 {
251  // not yet initialized
252  if ( !m_started ) { m_oldNames = m_catalogNames; return; } // RETURN
253  // no real change - no action
254  if ( m_catalogNames == m_oldNames ) { return; }
256  // remove ALL catalogs
257  removeCatalog("") ;
258  // add new catalogs
259  for ( CatalogNames::const_iterator inew = m_catalogNames.begin() ;
260  m_catalogNames.end() != inew ; ++inew ) { addCatalog ( *inew ) ; }
261  // start
262  init() ;
263  //
264  MsgStream log ( msgSvc() , name() ) ;
265  log << MSG::DEBUG
266  << "New catalogs to be used: "
268 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
MultiFileCatalog(const std::string &nam, ISvcLocator *svc)
Create a catalog file, initialization of XercesC.
virtual bool existsFID(const std::string &fid) const =0
Return the status of a FileID.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:26
bool m_started
Flag to indicate if catalog is started.
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 commit()
Save DOM catalog to file.
virtual StatusCode initialize()
IService implementation.
SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:62
virtual std::string getMetaDataItem(CSTR fid, CSTR name) const
Access metadata item.
tuple c
Definition: gaudirun.py:341
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:367
virtual ~MultiFileCatalog()
Destructor,.
void printError(CSTR msg, bool throw_exc=true) const
virtual void removeCatalog(CSTR connect)
Remove catalog identified by name from the existing ones.
void propHandler(Property &)
simple property handle to allow interactive modification of list of the file catalogs ...
virtual StatusCode finalize()
Finalize service object.
virtual const std::string & connectInfo() const =0
Access to connect string.
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
virtual void setWriteCatalog(IFileCatalog *cat)
Define the writable catalog identified by reference.
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.
CatalogNames m_catalogNames
Property : Container with catalog names.
Catalogs m_catalogs
Container with references to known catalogs.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
Definition of the basic interface.
Definition: IInterface.h:160
virtual IFileCatalog * findCatalog(CSTR connect, bool must_be_writable) const
Catalog management.
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.
const std::string & CSTR
virtual const std::string & name() const
Retrieve name of the service.
Definition: Service.cpp:331
File catalog interface.
Definition: IFileCatalog.h:24
virtual bool dirty() const
Check if the catalog should be updated.
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:43
struct GAUDI_API array
Parametrisation class for redirection array - like implementation.
virtual unsigned long release()=0
Release Interface instance.
virtual StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
Definition: Service.cpp:74
std::string createGuidAsString()
Create file identifier using UUID mechanism.
virtual void addCatalog(CSTR connect)
Add new catalog identified by name to the existing ones.
virtual CSTR connectInfo() const
Access to connect string.
CatalogNames m_oldNames
BACKUP:: Container with catalog names.
virtual bool readOnly() const
Check if the catalog is read-only.
string s
Definition: gaudirun.py:210
Templated class to add the standard messaging functionalities.
virtual std::string createFID() const
Catalog interface.
In-memory database of the loaded factories.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
virtual bool readOnly() const =0
Check if the catalog is read-only.
virtual void init()
Parse the DOM tree of the XML catalog.
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: Service.h:211
This is a number of static methods for bootstrapping the Gaudi framework.
Definition: Bootstrap.h:14
virtual void registerLFN(CSTR fid, CSTR lfn) const
Create a FileID and DOM Node of the LFN with all the attributes.
void _exec(T pmf) const
list i
Definition: ana.py:128
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:171
virtual void registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const
Create a FileID and DOM Node of the PFN with all the attributes.
virtual bool dirty() const =0
Check if the catalog should be updated.
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
Definition: Service.cpp:199
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.
Definition: Service.cpp:336
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
This class constitutes the core of the XML based FileCatalog API for using POOL within Gaudi...