| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# 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), 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 }