| # Gaudi Framework, version v21r8 |

Home |  | Generated: 17 Mar 2010

# 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   : base_class(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 // ----------------------------------------------------------------------------
    00068 std::string MultiFileCatalog::createFID()  const {
    00069   return createGuidAsString();
    00070 }
    00071 // ----------------------------------------------------------------------------
    00072 MultiFileCatalog::CSTR MultiFileCatalog::connectInfo() const {
    00073   static string s("MultiCatalog");
    00074   return s;
    00075 }
    00076 // ----------------------------------------------------------------------------
    00077 IFileCatalog* MultiFileCatalog::getCatalog(CSTR fid,
    00078                                            bool throw_if_not,
    00079                                            bool writable,
    00080                                            bool prt) const
    00081 {
    00082   for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i)  {
    00083     IFileCatalog* c = *i;
    00084     if ( c )  {
    00085       if ( writable && c->readOnly() )
    00086         continue;
    00087       else if ( fid.empty() )
    00088         return c;
    00089       else if ( !fid.empty() && c->existsFID(fid) )
    00090         return c;
    00091     }
    00092   }
    00093   if ( prt )  {
    00094     printError("No writable file catalog found which contains FID:"+fid,throw_if_not);
    00095   }
    00096   else  {
    00097     MsgStream log(msgSvc(),name());
    00098     log << MSG::DEBUG << "No writable file catalog found which contains FID:" << fid << endmsg;
    00099   }
    00100   return 0;
    00101 }
    00102 // ----------------------------------------------------------------------------
    00103 IFileCatalog* MultiFileCatalog::findCatalog(CSTR connect, bool must_be_writable) const  {
    00104   for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) {
    00105     if ( connect == (*i)->connectInfo() )
    00106       return (must_be_writable && (*i)->readOnly()) ? 0 : *i;
    00107   }
    00108   return 0;
    00109 }
    00110 // ----------------------------------------------------------------------------
    00111 MultiFileCatalog::Catalogs::iterator
    00112 MultiFileCatalog::i_findCatalog(CSTR connect, bool must_be_writable)  {
    00113   for(Catalogs::iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i) {
    00114     if ( connect == (*i)->connectInfo() ) {
    00115       return (must_be_writable && (*i)->readOnly()) ? m_catalogs.end() : i;
    00116     }
    00117   }
    00118   return m_catalogs.end();
    00119 }
    00120 // ----------------------------------------------------------------------------
    00121 void MultiFileCatalog::printError(CSTR msg, bool rethrow)  const  {
    00122   MsgStream log(msgSvc(),name());
    00123   if ( rethrow )  {
    00124     log << MSG::FATAL << msg << endmsg;
    00125     throw runtime_error("Catalog> "+msg);
    00126   }
    00127   log << MSG::ERROR << msg << endmsg;
    00128 }
    00129 // ----------------------------------------------------------------------------
    00130 void MultiFileCatalog::addCatalog(CSTR con)  {
    00131   if ( !con.empty() )  {
    00132     if ( 0 == findCatalog(con,false) )  {
    00133       static string xml_typ = "Gaudi::XMLFileCatalog";
    00134       string::size_type id0 = con.find("_");
    00135       string typ = con.substr(0,id0);
    00136       string url = con.substr(id0+1);
    00137       IInterface* cat = 0;
    00138       if ( strncasecmp("xml",typ.c_str(),3) == 0 )    {
    00139         cat = PluginService::Create<IInterface*>(xml_typ,url,msgSvc().get());
    00140       }
    00141       else    {
    00142         cat = PluginService::Create<IInterface*>(typ,url,serviceLocator().get());
    00143         if ( !cat )  {
    00144           cat = PluginService::Create<IInterface*>(typ,url,msgSvc().get());
    00145         }
    00146       }
    00147       if ( cat )  {
    00148         IFileCatalog* fileCat = 0;
    00149         if ( cat->queryInterface(IFileCatalog::interfaceID(),pp_cast<void>(&fileCat)).isSuccess() ) {
    00150           addCatalog(fileCat);
    00151           cat->release();
    00152           return;
    00153         }
    00154       }
    00155       printError("Failed to create catalog connection:"+con,true);
    00156     }
    00158     return;
    00159   }
    00160   printError("Got invalid (empty) catalog connection string.",true);
    00161 }
    00162 // ----------------------------------------------------------------------------
    00163 void MultiFileCatalog::addCatalog(IFileCatalog* cat)  {
    00164   if ( cat )  {
    00165     cat->addRef();
    00166     m_catalogs.push_back(cat);
    00167     return;
    00168   }
    00169   printError("Got invalid catalog to be added to multi catalog.",true);
    00170 }
    00171 // ----------------------------------------------------------------------------
    00172 void MultiFileCatalog::removeCatalog(CSTR con)  {
    00173   if ( con.empty() || con == "*" )  {
    00174     _exec(&IFileCatalog::release);
    00175     m_catalogs.clear();
    00176     return;
    00177   }
    00178   removeCatalog(findCatalog(con,false));
    00179 }
    00180 // ----------------------------------------------------------------------------
    00181 void MultiFileCatalog::removeCatalog(const IFileCatalog* cat)  {
    00182   if ( cat )  {
    00183     Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat);
    00184     if ( i != m_catalogs.end() )  {
    00185       (*i)->release();
    00186       m_catalogs.erase(i);
    00187       return;
    00188     }
    00189     printError("Unknown file catalog -- cannot be removed.",true);
    00190   }
    00191   printError("Invalid file catalog.",true);
    00192 }
    00193 // ----------------------------------------------------------------------------
    00194 void MultiFileCatalog::setWriteCatalog(IFileCatalog* cat)  {
    00195   if ( cat )  {
    00196     if ( !cat->readOnly() )  {
    00197       Catalogs::iterator i=find(m_catalogs.begin(),m_catalogs.end(),cat);
    00198       if ( i != m_catalogs.end() )  {
    00199         m_catalogs.erase(i);
    00200         m_catalogs.insert(m_catalogs.begin(),cat);
    00201         return;
    00202       }
    00203       printError("The catalog "+cat->connectInfo()+" is not known.",true);
    00204     }
    00205     printError("The catalog "+cat->connectInfo()+" is not writable.",true);
    00206   }
    00207   printError("Invalid file catalog.",true);
    00208 }
    00209 // ----------------------------------------------------------------------------
    00210 void MultiFileCatalog::setWriteCatalog(CSTR connect)  {
    00211   Catalogs::iterator i = i_findCatalog(connect,true);
    00212   if ( i == m_catalogs.end() ) {
    00213     addCatalog(connect);
    00214     setWriteCatalog(findCatalog(connect,true));
    00215     return;
    00216   }
    00217   setWriteCatalog(*i);
    00218 }
    00219 // ----------------------------------------------------------------------------
    00220 string MultiFileCatalog::getMetaDataItem(CSTR fid,CSTR attr) const  {
    00221   std::string result;
    00222   for(Catalogs::const_iterator i=m_catalogs.begin(); i != m_catalogs.end(); ++i)
    00223     if ( !(result= (*i)->getMetaDataItem(fid,attr)).empty() ) break;
    00224   return result;
    00225 }
    00227 void MultiFileCatalog::registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const {
    00228   IFileCatalog* c = getCatalog(fid,false,true,false);
    00229   if ( !c ) c = getCatalog("",true,true,true);
    00230   c->registerPFN(fid, pfn, ftype);
    00231 }
    00233 void MultiFileCatalog::registerLFN(CSTR fid, CSTR lfn) const  {
    00234   IFileCatalog* c = getCatalog(fid,false,true,false);
    00235   if ( !c ) c = getCatalog("",true,true,true);
    00236   c->registerLFN(fid, lfn);
    00237 }
    00238 // ----------------------------------------------------------------------------
    00239 bool MultiFileCatalog::readOnly() const
    00240 {  return _findX0Bool(m_catalogs,&IFileCatalog::readOnly,false);              }
    00241 // ----------------------------------------------------------------------------
    00242 bool MultiFileCatalog::dirty() const
    00243 {  return _findX0Bool(m_catalogs,&IFileCatalog::dirty,true);                  }
    00244 // ----------------------------------------------------------------------------
    00245 void MultiFileCatalog::propHandler(Property& /* p */)
    00246 {
    00247   // not yet initialized
    00248   if ( !m_started ) { m_oldNames = m_catalogNames; return; } // RETURN
    00249   // no real change - no action
    00250   if ( m_catalogNames == m_oldNames ) { return; }
    00251   m_oldNames = m_catalogNames ;
    00252   // remove ALL catalogs
    00253   removeCatalog("") ;
    00254   // add new catalogs
    00255   for ( CatalogNames::const_iterator inew = m_catalogNames.begin() ;
    00256         m_catalogNames.end() != inew ; ++inew ) { addCatalog ( *inew ) ; }
    00257   // start
    00258   init() ;
    00259   //
    00260   MsgStream log ( msgSvc() , name() ) ;
    00261   log << MSG::DEBUG
    00262       << "New catalogs to be used: "
    00263       << Gaudi::Utils::toString ( m_catalogNames ) << endmsg ;
    00264 }