| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MultiFileCatalog.cpp
Go to the documentation of this file.
1 #include "GaudiKernel/strcasecmp.h"
2 #include "GaudiKernel/MsgStream.h"
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
13 DECLARE_COMPONENT(MultiFileCatalog)
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 // ----------------------------------------------------------------------------
34 MultiFileCatalog::~MultiFileCatalog() {
35 }
36 // ----------------------------------------------------------------------------
37 StatusCode MultiFileCatalog::initialize() {
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 // ----------------------------------------------------------------------------
58 StatusCode MultiFileCatalog::finalize() {
59 commit();
60 _exec(&IFileCatalog::release);
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 // ----------------------------------------------------------------------------
71 MultiFileCatalog::CSTR MultiFileCatalog::connectInfo() const {
72 static string s("MultiCatalog");
73 return s;
74 }
75 // ----------------------------------------------------------------------------
76 IFileCatalog* MultiFileCatalog::getCatalog(CSTR fid,
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 // ----------------------------------------------------------------------------
129 void MultiFileCatalog::addCatalog(CSTR con) {
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 {
141 using Gaudi::PluginService::Details::Registry;
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 // ----------------------------------------------------------------------------
167 void MultiFileCatalog::addCatalog(IFileCatalog* cat) {
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 // ----------------------------------------------------------------------------
176 void MultiFileCatalog::removeCatalog(CSTR con) {
177 if ( con.empty() || con == "*" ) {
178 _exec(&IFileCatalog::release);
179 m_catalogs.clear();
180 return;
181 }
182 removeCatalog(findCatalog(con,false));
183 }
184 // ----------------------------------------------------------------------------
185 void MultiFileCatalog::removeCatalog(const IFileCatalog* cat) {
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 // ----------------------------------------------------------------------------
198 void MultiFileCatalog::setWriteCatalog(IFileCatalog* cat) {
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 // ----------------------------------------------------------------------------
214 void MultiFileCatalog::setWriteCatalog(CSTR connect) {
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 // ----------------------------------------------------------------------------
224 string MultiFileCatalog::getMetaDataItem(CSTR fid,CSTR attr) const {
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 }
237 void MultiFileCatalog::registerLFN(CSTR fid, CSTR lfn) const {
238 IFileCatalog* c = getCatalog(fid,false,true,false);
239 if ( !c ) c = getCatalog("",true,true,true);
240 c->registerLFN(fid, lfn);
241 }
242 // ----------------------------------------------------------------------------
243 bool MultiFileCatalog::readOnly() const
244 { return _findX0Bool(m_catalogs,&IFileCatalog::readOnly,false); }
245 // ----------------------------------------------------------------------------
246 bool MultiFileCatalog::dirty() const
247 { return _findX0Bool(m_catalogs,&IFileCatalog::dirty,true); }
248 // ----------------------------------------------------------------------------
249 void MultiFileCatalog::propHandler(Property& /* p */)
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; }
255 m_oldNames = m_catalogNames ;
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: "
267 << Gaudi::Utils::toString ( m_catalogNames ) << endmsg ;
268 }