Gaudi Framework, version v20r4

Generated: 8 Jan 2009

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 }

Generated at Thu Jan 8 17:44:24 2009 for Gaudi Framework, version v20r4 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004