![]() |
|
|
Generated: 18 Jul 2008 |
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) 00029 { 00030 declareProperty("Catalogs",m_catalogNames); 00031 m_catalogNames.push_back("xmlcatalog_file:test_catalog.xml"); 00032 } 00033 // ---------------------------------------------------------------------------- 00034 MultiFileCatalog::~MultiFileCatalog() { 00035 } 00036 // ---------------------------------------------------------------------------- 00037 StatusCode MultiFileCatalog::initialize() { 00038 CatalogNames::const_iterator i; 00039 std::string current = ""; 00040 if ( !Service::initialize().isSuccess() ) { 00041 printError("Failed to initialize service base class.",false); 00042 return StatusCode::SUCCESS; 00043 } 00044 try { 00045 for(i=m_catalogNames.begin(); i != m_catalogNames.end(); ++i) { 00046 current = *i; 00047 addCatalog(*i); 00048 } 00049 init(); 00050 return StatusCode::SUCCESS; 00051 } 00052 catch(const std::exception& /* e */) { 00053 printError("Cannot add file catalog:"+current,false); 00054 } 00055 return StatusCode::FAILURE; 00056 } 00057 // ---------------------------------------------------------------------------- 00058 StatusCode MultiFileCatalog::finalize() { 00059 commit(); 00060 _exec(&IFileCatalog::release); 00061 m_catalogs.clear(); 00062 m_started = false; 00063 return Service::finalize(); 00064 } 00065 // ---------------------------------------------------------------------------- 00066 StatusCode MultiFileCatalog::queryInterface(const InterfaceID& riid, void** ppv) { 00067 if ( riid.versionMatch(IFileCatalog::interfaceID()) ) 00068 *ppv = (IFileCatalog*)this; 00069 else if ( riid.versionMatch(IFileCatalogMgr::interfaceID()) ) 00070 *ppv = (IFileCatalogMgr*)this; 00071 else 00072 return Service::queryInterface(riid,ppv); 00073 *ppv = (IFileCatalog*)this; 00074 addRef(); 00075 return StatusCode::SUCCESS; 00076 } 00078 std::string MultiFileCatalog::createFID() const { 00079 return createGuidAsString(); 00080 } 00081 // ---------------------------------------------------------------------------- 00082 MultiFileCatalog::CSTR MultiFileCatalog::connectInfo() const { 00083 static string s("MultiCatalog"); 00084 return s; 00085 } 00086 // ---------------------------------------------------------------------------- 00087 IFileCatalog* MultiFileCatalog::getCatalog(CSTR fid, 00088 bool throw_if_not, 00089 bool writable, 00090 bool prt) const 00091 { 00092 for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) { 00093 IFileCatalog* c = *i; 00094 if ( c ) { 00095 if ( writable && c->readOnly() ) 00096 continue; 00097 else if ( fid.empty() ) 00098 return c; 00099 else if ( !fid.empty() && c->existsFID(fid) ) 00100 return c; 00101 } 00102 } 00103 if ( prt ) { 00104 printError("No writable file catalog found which contains FID:"+fid,throw_if_not); 00105 } 00106 else { 00107 MsgStream log(msgSvc(),name()); 00108 log << MSG::DEBUG << "No writable file catalog found which contains FID:" << fid << endmsg; 00109 } 00110 return 0; 00111 } 00112 // ---------------------------------------------------------------------------- 00113 IFileCatalog* MultiFileCatalog::findCatalog(CSTR connect, bool must_be_writable) const { 00114 for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) { 00115 if ( connect == (*i)->connectInfo() ) 00116 return (must_be_writable && (*i)->readOnly()) ? 0 : *i; 00117 } 00118 return 0; 00119 } 00120 // ---------------------------------------------------------------------------- 00121 MultiFileCatalog::Catalogs::iterator 00122 MultiFileCatalog::i_findCatalog(CSTR connect, bool must_be_writable) { 00123 for(Catalogs::iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) { 00124 if ( connect == (*i)->connectInfo() ) { 00125 return (must_be_writable && (*i)->readOnly()) ? m_catalogs.end() : i; 00126 } 00127 } 00128 return m_catalogs.end(); 00129 } 00130 // ---------------------------------------------------------------------------- 00131 void MultiFileCatalog::printError(CSTR msg, bool rethrow) const { 00132 MsgStream log(msgSvc(),name()); 00133 if ( rethrow ) { 00134 log << MSG::FATAL << msg << endmsg; 00135 throw runtime_error("Catalog> "+msg); 00136 } 00137 log << MSG::ERROR << msg << endmsg; 00138 } 00139 // ---------------------------------------------------------------------------- 00140 void MultiFileCatalog::addCatalog(CSTR con) { 00141 if ( !con.empty() ) { 00142 if ( 0 == findCatalog(con,false) ) { 00143 static string xml_typ = "Gaudi::XMLFileCatalog"; 00144 string::size_type id0 = con.find("_"); 00145 string typ = con.substr(0,id0); 00146 string url = con.substr(id0+1); 00147 IInterface* cat = 0; 00148 if ( strncasecmp("xml",typ.c_str(),3) == 0 ) { 00149 cat = PluginService::Create<IInterface*>(xml_typ,url,msgSvc()); 00150 } 00151 else { 00152 cat = PluginService::Create<IInterface*>(typ,url,serviceLocator()); 00153 if ( !cat ) { 00154 cat = PluginService::Create<IInterface*>(typ,url,msgSvc()); 00155 } 00156 } 00157 if ( cat ) { 00158 IFileCatalog* fileCat = 0; 00159 if ( cat->queryInterface(IFileCatalog::interfaceID(),pp_cast<void>(&fileCat)).isSuccess() ) { 00160 addCatalog(fileCat); 00161 cat->release(); 00162 return; 00163 } 00164 } 00165 printError("Failed to create catalog connection:"+con,true); 00166 } 00168 return; 00169 } 00170 printError("Got invalid (empty) catalog connection string.",true); 00171 } 00172 // ---------------------------------------------------------------------------- 00173 void MultiFileCatalog::addCatalog(IFileCatalog* cat) { 00174 if ( cat ) { 00175 cat->addRef(); 00176 m_catalogs.push_back(cat); 00177 return; 00178 } 00179 printError("Got invalid catalog to be added to multi catalog.",true); 00180 } 00181 // ---------------------------------------------------------------------------- 00182 void MultiFileCatalog::removeCatalog(CSTR con) { 00183 if ( con.empty() || con == "*" ) { 00184 _exec(&IFileCatalog::release); 00185 m_catalogs.clear(); 00186 return; 00187 } 00188 removeCatalog(findCatalog(con,false)); 00189 } 00190 // ---------------------------------------------------------------------------- 00191 void MultiFileCatalog::removeCatalog(const IFileCatalog* cat) { 00192 if ( cat ) { 00193 Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat); 00194 if ( i != m_catalogs.end() ) { 00195 (*i)->release(); 00196 m_catalogs.erase(i); 00197 return; 00198 } 00199 printError("Unknown file catalog -- cannot be removed.",true); 00200 } 00201 printError("Invalid file catalog.",true); 00202 } 00203 // ---------------------------------------------------------------------------- 00204 void MultiFileCatalog::setWriteCatalog(IFileCatalog* cat) { 00205 if ( cat ) { 00206 if ( !cat->readOnly() ) { 00207 Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat); 00208 if ( i != m_catalogs.end() ) { 00209 m_catalogs.erase(i); 00210 m_catalogs.insert(m_catalogs.begin(),cat); 00211 return; 00212 } 00213 printError("The catalog "+cat->connectInfo()+" is not known.",true); 00214 } 00215 printError("The catalog "+cat->connectInfo()+" is not writable.",true); 00216 } 00217 printError("Invalid file catalog.",true); 00218 } 00219 // ---------------------------------------------------------------------------- 00220 void MultiFileCatalog::setWriteCatalog(CSTR connect) { 00221 Catalogs::iterator i = i_findCatalog(connect,true); 00222 if ( i == m_catalogs.end() ) { 00223 addCatalog(connect); 00224 setWriteCatalog(findCatalog(connect,true)); 00225 return; 00226 } 00227 setWriteCatalog(*i); 00228 } 00229 // ---------------------------------------------------------------------------- 00230 string MultiFileCatalog::getMetaDataItem(CSTR fid,CSTR attr) const { 00231 std::string result; 00232 for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) 00233 if ( !(result= (*i)->getMetaDataItem(fid,attr)).empty() ) break; 00234 return result; 00235 } 00237 void MultiFileCatalog::registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const { 00238 IFileCatalog* c = getCatalog(fid,false,true,false); 00239 if ( !c ) c = getCatalog("",true,true,true); 00240 c->registerPFN(fid, pfn, ftype); 00241 } 00243 void MultiFileCatalog::registerLFN(CSTR fid, CSTR lfn) const { 00244 IFileCatalog* c = getCatalog(fid,false,true,false); 00245 if ( !c ) c = getCatalog("",true,true,true); 00246 c->registerLFN(fid, lfn); 00247 } 00248 // ---------------------------------------------------------------------------- 00249 bool MultiFileCatalog::readOnly() const 00250 { return _findX0Bool(m_catalogs,&IFileCatalog::readOnly,false); } 00251 // ---------------------------------------------------------------------------- 00252 bool MultiFileCatalog::dirty() const 00253 { return _findX0Bool(m_catalogs,&IFileCatalog::dirty,true); }