![]() |
|
|
Generated: 8 Jan 2009 |
00001 #include "GaudiKernel/DeclareFactoryEntries.h" 00002 #include "GaudiKernel/strcasecmp.h" 00003 #include "GaudiKernel/MsgStream.h" 00004 #include "Reflex/PluginService.h" 00005 #include "MultiFileCatalog.h" 00006 #include <stdexcept> 00007 #include <algorithm> 00008 00009 namespace Gaudi { std::string createGuidAsString(); } 00010 00011 using ROOT::Reflex::PluginService; 00012 using namespace Gaudi; 00013 using namespace std; 00014 DECLARE_NAMESPACE_SERVICE_FACTORY(Gaudi,MultiFileCatalog); 00015 00016 namespace { 00017 template <class V,class F> 00018 bool _findX0Bool(V& array, F pmf, bool invert) { 00019 for(typename V::const_iterator i=array.begin(); i != array.end(); ++i) { 00020 bool res = invert ? !((*i)->*pmf)() : ((*i)->*pmf)(); 00021 if ( !res ) return false; 00022 } 00023 return true; 00024 } 00025 } 00026 // ---------------------------------------------------------------------------- 00027 MultiFileCatalog::MultiFileCatalog(const std::string& nam, ISvcLocator* svc) 00028 : Service(nam, svc), m_started(false), m_oldNames() 00029 { 00030 declareProperty("Catalogs", m_catalogNames, "The list of Catalogs") 00031 -> declareUpdateHandler ( &Gaudi::MultiFileCatalog::propHandler, this ) ; 00032 m_catalogNames.push_back("xmlcatalog_file:test_catalog.xml"); 00033 } 00034 // ---------------------------------------------------------------------------- 00035 MultiFileCatalog::~MultiFileCatalog() { 00036 } 00037 // ---------------------------------------------------------------------------- 00038 StatusCode MultiFileCatalog::initialize() { 00039 CatalogNames::const_iterator i; 00040 std::string current = ""; 00041 if ( !Service::initialize().isSuccess() ) { 00042 printError("Failed to initialize service base class.",false); 00043 return StatusCode::SUCCESS; 00044 } 00045 try { 00046 for(i=m_catalogNames.begin(); i != m_catalogNames.end(); ++i) { 00047 current = *i; 00048 addCatalog(*i); 00049 } 00050 init(); 00051 return StatusCode::SUCCESS; 00052 } 00053 catch(const std::exception& /* e */) { 00054 printError("Cannot add file catalog:"+current,false); 00055 } 00056 return StatusCode::FAILURE; 00057 } 00058 // ---------------------------------------------------------------------------- 00059 StatusCode MultiFileCatalog::finalize() { 00060 commit(); 00061 _exec(&IFileCatalog::release); 00062 m_catalogs.clear(); 00063 m_started = false; 00064 return Service::finalize(); 00065 } 00066 // ---------------------------------------------------------------------------- 00067 StatusCode MultiFileCatalog::queryInterface(const InterfaceID& riid, void** ppv) { 00068 if ( riid.versionMatch(IFileCatalog::interfaceID()) ) 00069 *ppv = (IFileCatalog*)this; 00070 else if ( riid.versionMatch(IFileCatalogMgr::interfaceID()) ) 00071 *ppv = (IFileCatalogMgr*)this; 00072 else 00073 return Service::queryInterface(riid,ppv); 00074 *ppv = (IFileCatalog*)this; 00075 addRef(); 00076 return StatusCode::SUCCESS; 00077 } 00079 std::string MultiFileCatalog::createFID() const { 00080 return createGuidAsString(); 00081 } 00082 // ---------------------------------------------------------------------------- 00083 MultiFileCatalog::CSTR MultiFileCatalog::connectInfo() const { 00084 static string s("MultiCatalog"); 00085 return s; 00086 } 00087 // ---------------------------------------------------------------------------- 00088 IFileCatalog* MultiFileCatalog::getCatalog(CSTR fid, 00089 bool throw_if_not, 00090 bool writable, 00091 bool prt) const 00092 { 00093 for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) { 00094 IFileCatalog* c = *i; 00095 if ( c ) { 00096 if ( writable && c->readOnly() ) 00097 continue; 00098 else if ( fid.empty() ) 00099 return c; 00100 else if ( !fid.empty() && c->existsFID(fid) ) 00101 return c; 00102 } 00103 } 00104 if ( prt ) { 00105 printError("No writable file catalog found which contains FID:"+fid,throw_if_not); 00106 } 00107 else { 00108 MsgStream log(msgSvc(),name()); 00109 log << MSG::DEBUG << "No writable file catalog found which contains FID:" << fid << endmsg; 00110 } 00111 return 0; 00112 } 00113 // ---------------------------------------------------------------------------- 00114 IFileCatalog* MultiFileCatalog::findCatalog(CSTR connect, bool must_be_writable) const { 00115 for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) { 00116 if ( connect == (*i)->connectInfo() ) 00117 return (must_be_writable && (*i)->readOnly()) ? 0 : *i; 00118 } 00119 return 0; 00120 } 00121 // ---------------------------------------------------------------------------- 00122 MultiFileCatalog::Catalogs::iterator 00123 MultiFileCatalog::i_findCatalog(CSTR connect, bool must_be_writable) { 00124 for(Catalogs::iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) { 00125 if ( connect == (*i)->connectInfo() ) { 00126 return (must_be_writable && (*i)->readOnly()) ? m_catalogs.end() : i; 00127 } 00128 } 00129 return m_catalogs.end(); 00130 } 00131 // ---------------------------------------------------------------------------- 00132 void MultiFileCatalog::printError(CSTR msg, bool rethrow) const { 00133 MsgStream log(msgSvc(),name()); 00134 if ( rethrow ) { 00135 log << MSG::FATAL << msg << endmsg; 00136 throw runtime_error("Catalog> "+msg); 00137 } 00138 log << MSG::ERROR << msg << endmsg; 00139 } 00140 // ---------------------------------------------------------------------------- 00141 void MultiFileCatalog::addCatalog(CSTR con) { 00142 if ( !con.empty() ) { 00143 if ( 0 == findCatalog(con,false) ) { 00144 static string xml_typ = "Gaudi::XMLFileCatalog"; 00145 string::size_type id0 = con.find("_"); 00146 string typ = con.substr(0,id0); 00147 string url = con.substr(id0+1); 00148 IInterface* cat = 0; 00149 if ( strncasecmp("xml",typ.c_str(),3) == 0 ) { 00150 cat = PluginService::Create<IInterface*>(xml_typ,url,msgSvc()); 00151 } 00152 else { 00153 cat = PluginService::Create<IInterface*>(typ,url,serviceLocator()); 00154 if ( !cat ) { 00155 cat = PluginService::Create<IInterface*>(typ,url,msgSvc()); 00156 } 00157 } 00158 if ( cat ) { 00159 IFileCatalog* fileCat = 0; 00160 if ( cat->queryInterface(IFileCatalog::interfaceID(),pp_cast<void>(&fileCat)).isSuccess() ) { 00161 addCatalog(fileCat); 00162 cat->release(); 00163 return; 00164 } 00165 } 00166 printError("Failed to create catalog connection:"+con,true); 00167 } 00169 return; 00170 } 00171 printError("Got invalid (empty) catalog connection string.",true); 00172 } 00173 // ---------------------------------------------------------------------------- 00174 void MultiFileCatalog::addCatalog(IFileCatalog* cat) { 00175 if ( cat ) { 00176 cat->addRef(); 00177 m_catalogs.push_back(cat); 00178 return; 00179 } 00180 printError("Got invalid catalog to be added to multi catalog.",true); 00181 } 00182 // ---------------------------------------------------------------------------- 00183 void MultiFileCatalog::removeCatalog(CSTR con) { 00184 if ( con.empty() || con == "*" ) { 00185 _exec(&IFileCatalog::release); 00186 m_catalogs.clear(); 00187 return; 00188 } 00189 removeCatalog(findCatalog(con,false)); 00190 } 00191 // ---------------------------------------------------------------------------- 00192 void MultiFileCatalog::removeCatalog(const IFileCatalog* cat) { 00193 if ( cat ) { 00194 Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat); 00195 if ( i != m_catalogs.end() ) { 00196 (*i)->release(); 00197 m_catalogs.erase(i); 00198 return; 00199 } 00200 printError("Unknown file catalog -- cannot be removed.",true); 00201 } 00202 printError("Invalid file catalog.",true); 00203 } 00204 // ---------------------------------------------------------------------------- 00205 void MultiFileCatalog::setWriteCatalog(IFileCatalog* cat) { 00206 if ( cat ) { 00207 if ( !cat->readOnly() ) { 00208 Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat); 00209 if ( i != m_catalogs.end() ) { 00210 m_catalogs.erase(i); 00211 m_catalogs.insert(m_catalogs.begin(),cat); 00212 return; 00213 } 00214 printError("The catalog "+cat->connectInfo()+" is not known.",true); 00215 } 00216 printError("The catalog "+cat->connectInfo()+" is not writable.",true); 00217 } 00218 printError("Invalid file catalog.",true); 00219 } 00220 // ---------------------------------------------------------------------------- 00221 void MultiFileCatalog::setWriteCatalog(CSTR connect) { 00222 Catalogs::iterator i = i_findCatalog(connect,true); 00223 if ( i == m_catalogs.end() ) { 00224 addCatalog(connect); 00225 setWriteCatalog(findCatalog(connect,true)); 00226 return; 00227 } 00228 setWriteCatalog(*i); 00229 } 00230 // ---------------------------------------------------------------------------- 00231 string MultiFileCatalog::getMetaDataItem(CSTR fid,CSTR attr) const { 00232 std::string result; 00233 for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) 00234 if ( !(result= (*i)->getMetaDataItem(fid,attr)).empty() ) break; 00235 return result; 00236 } 00238 void MultiFileCatalog::registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const { 00239 IFileCatalog* c = getCatalog(fid,false,true,false); 00240 if ( !c ) c = getCatalog("",true,true,true); 00241 c->registerPFN(fid, pfn, ftype); 00242 } 00244 void MultiFileCatalog::registerLFN(CSTR fid, CSTR lfn) const { 00245 IFileCatalog* c = getCatalog(fid,false,true,false); 00246 if ( !c ) c = getCatalog("",true,true,true); 00247 c->registerLFN(fid, lfn); 00248 } 00249 // ---------------------------------------------------------------------------- 00250 bool MultiFileCatalog::readOnly() const 00251 { return _findX0Bool(m_catalogs,&IFileCatalog::readOnly,false); } 00252 // ---------------------------------------------------------------------------- 00253 bool MultiFileCatalog::dirty() const 00254 { return _findX0Bool(m_catalogs,&IFileCatalog::dirty,true); } 00255 // ---------------------------------------------------------------------------- 00256 void MultiFileCatalog::propHandler(Property& /* p */) 00257 { 00258 // not yet initialized 00259 if ( !m_started ) { m_oldNames = m_catalogNames; return; } // RETURN 00260 // no real change - no action 00261 if ( m_catalogNames == m_oldNames ) { return; } 00262 m_oldNames = m_catalogNames ; 00263 // remove ALL catalogs 00264 removeCatalog("") ; 00265 // add new catalogs 00266 for ( CatalogNames::const_iterator inew = m_catalogNames.begin() ; 00267 m_catalogNames.end() != inew ; ++inew ) { addCatalog ( *inew ) ; } 00268 // start 00269 init() ; 00270 // 00271 MsgStream log ( msgSvc() , name() ) ; 00272 log << MSG::DEBUG 00273 << "New catalogs to be used: " 00274 << Gaudi::Utils::toString ( m_catalogNames ) << endreq ; 00275 }