| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

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

- Search for |

- File List
- File Members

# MultiFileCatalog.cpp

Go to the documentation of this file.

    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);                  }