Skip to content
Snippets Groups Projects
Commit 3b34313a authored by Fons Rademakers's avatar Fons Rademakers
Browse files

This class implements a plugin library manager. It keeps track of

a list of plugin handlers. A plugin handler knows which plugin
library to load to get a specific class that is used to extend the
functionality of a specific base class. For example, to extend the
base class TFile to be able to read RFIO files one needs to load
the plugin library libRFIO.so which defines the TRFIOFile class.
This loading should be triggered when a given URI contains a
regular expression defined by the handler. Handlers can be defined
for example as resources in the .rootrc file, e.g.:

   Plugin.TFile:       ^rfio:    TRFIOFile     RFIO
   Plugin.TSQLServer:  ^mysql:   TMySQLServer  MySQL
   +Plugin.TSQLServer: ^pgsql:   TPgSQLServer  PgSQL

Plugin handlers can also be registered at run time, e.g.:

   gROOT->GetPluginManager()->AddHandler("TSQLServer", "^sapdb:",
                                         "TSapDBServer", "SapDB");

A list of currently defined handlers can be printed using:

   gROOT->GetPluginManager()->Print();

The use of the plugin library manager removes all textual references
to hard-coded class and library names and the resulting dependencies
in the base classes. The plugin manager is used to extend a.o.
TFile, TSQLServer, TGrid, etc. functionality.


git-svn-id: http://root.cern.ch/svn/root/trunk@3789 27541ba8-7e3a-0410-8455-c3a389f83636
parent 21025ed5
No related branches found
No related tags found
No related merge requests found
// @(#)root/base:$Name:$:$Id:$
// Author: Fons Rademakers 26/1/2002
/*************************************************************************
* Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TPluginManager
#define ROOT_TPluginManager
//////////////////////////////////////////////////////////////////////////
// //
// TPluginManager //
// //
// This class implements a plugin library manager. It keeps track of //
// a list of plugin handlers. A plugin handler knows which plugin //
// library to load to get a specific class that is used to extend the //
// functionality of a specific base class. For example, to extend the //
// base class TFile to be able to read RFIO files one needs to load //
// the plugin library libRFIO.so which defines the TRFIOFile class. //
// This loading should be triggered when a given URI contains a //
// regular expression defined by the handler. Handlers can be defined //
// for example as resources in the .rootrc file, e.g.: //
// //
// Plugin.TFile: ^rfio: TRFIOFile RFIO //
// Plugin.TSQLServer: ^mysql: TMySQLServer MySQL //
// +Plugin.TSQLServer: ^pgsql: TPgSQLServer PgSQL //
// //
// Plugin handlers can also be registered at run time, e.g.: //
// //
// gROOT->GetPluginManager()->AddHandler("TSQLServer", "^sapdb:", //
// "TSapDBServer", "SapDB"); //
// //
// A list of currently defined handlers can be printed using: //
// //
// gROOT->GetPluginManager()->Print(); //
// //
// The use of the plugin library manager removes all textual references //
// to hard-coded class and library names and the resulting dependencies //
// in the base classes. The plugin manager is used to extend a.o. //
// TFile, TSQLServer, TGrid, etc. functionality. //
// //
//////////////////////////////////////////////////////////////////////////
#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TString
#include "TString.h"
#endif
class TEnv;
class TList;
class TPluginManager;
class TPluginHandler : public TObject {
friend class TPluginManager;
private:
TString fBase; // base class which will be extended by plugin
TString fRegexp; // regular expression which must be matched in URI
TString fClass; // class to be loaded from plugin library
TString fPlugin; // plugin library which should contain fClass
TPluginHandler() { }
TPluginHandler(const char *base, const char *regexp,
const char *className, const char *pluginName);
~TPluginHandler() { }
const char *GetBase() const { return fBase; }
const char *GetRegexp() const { return fRegexp; }
const char *GetPlugin() const { return fPlugin; }
Bool_t CanHandle(const char *base, const char *uri);
public:
const char *GetClass() const { return fClass; }
Int_t LoadPlugin();
ClassDef(TPluginHandler,1) // Handler for plugin libraries
};
class TPluginManager : public TObject {
private:
TList *fHandlers; // list of plugin handlers
public:
TPluginManager() { fHandlers = 0; }
~TPluginManager();
void LoadHandlersFromEnv(TEnv *env);
void AddHandler(const char *base, const char *regexp,
const char *className, const char *pluginName);
void RemoveHandler(const char *base, const char *regexp = 0);
TPluginHandler *FindHandler(const char *base, const char *uri);
void Print(Option_t *opt = "") const;
ClassDef(TPluginManager,1) // Manager for plugin handlers
};
#endif
// @(#)root/base:$Name:$:$Id:$
// Author: Fons Rademakers 26/1/2002
/*************************************************************************
* Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// TPluginManager //
// //
// This class implements a plugin library manager. It keeps track of //
// a list of plugin handlers. A plugin handler knows which plugin //
// library to load to get a specific class that is used to extend the //
// functionality of a specific base class. For example, to extend the //
// base class TFile to be able to read RFIO files one needs to load //
// the plugin library libRFIO.so which defines the TRFIOFile class. //
// This loading should be triggered when a given URI contains a //
// regular expression defined by the handler. Handlers can be defined //
// for example as resources in the .rootrc file, e.g.: //
// //
// Plugin.TFile: ^rfio: TRFIOFile RFIO //
// Plugin.TSQLServer: ^mysql: TMySQLServer MySQL //
// +Plugin.TSQLServer: ^pgsql: TPgSQLServer PgSQL //
// //
// Plugin handlers can also be registered at run time, e.g.: //
// //
// gROOT->GetPluginManager()->AddHandler("TSQLServer", "^sapdb:", //
// "TSapDBServer", "SapDB"); //
// //
// A list of currently defined handlers can be printed using: //
// //
// gROOT->GetPluginManager()->Print(); //
// //
// The use of the plugin library manager removes all textual references //
// to hard-coded class and library names and the resulting dependencies //
// in the base classes. The plugin manager is used to extend a.o. //
// TFile, TSQLServer, TGrid, etc. functionality. //
// //
//////////////////////////////////////////////////////////////////////////
#include "TPluginManager.h"
#include "TEnv.h"
#include "TRegexp.h"
#include "TROOT.h"
#include "TList.h"
#include "TOrdCollection.h"
ClassImp(TPluginHandler)
ClassImp(TPluginManager)
//______________________________________________________________________________
TPluginHandler::TPluginHandler(const char *base, const char *regexp,
const char *className, const char *pluginName)
{
// Create a plugin handler. Called by TPluginManager.
fBase = base;
fRegexp = regexp;
fClass = className;
fPlugin = pluginName;
}
//______________________________________________________________________________
Bool_t TPluginHandler::CanHandle(const char *base, const char *uri)
{
// Check if regular expression appears in the URI, if so return kTRUE.
if (fBase != base)
return kFALSE;
TRegexp re(fRegexp, kFALSE);
TString ruri = uri;
if (ruri.Index(re) != kNPOS)
return kTRUE;
return kFALSE;
}
//______________________________________________________________________________
Int_t TPluginHandler::LoadPlugin()
{
// Load the plugin library for this handler. Returns 0 on successful loading
// and -1 in case the library does not exist or in case of error.
return gROOT->LoadClass(fClass, fPlugin);
}
//______________________________________________________________________________
TPluginManager::~TPluginManager()
{
// Clean up the plugin manager.
delete fHandlers;
}
//______________________________________________________________________________
void TPluginManager::LoadHandlersFromEnv(TEnv *env)
{
// Load plugin handlers specified in config file, like:
// Plugin.TFile: ^rfio: TRFIOFile RFIO
// Plugin.TSQLServer: ^mysql: TMySQLServer MySQL
// +Plugin.TSQLServer: ^pgsql: TPgSQLServer PgSQL
// The + allows the extension of an already defined resource (see TEnv).
if (!env) return;
TIter next(env->GetTable());
TEnvRec *er;
while ((er = (TEnvRec*) next())) {
char *s;
if ((s = strstr(er->GetName(), "Plugin."))) {
const char *val = env->GetValue(er->GetName(), (const char*)0);
if (val) {
Int_t cnt = 0;
char *v = StrDup(val);
s += 7;
while (1) {
TString regexp = strtok(!cnt ? v : 0, ",; ");
if (regexp.IsNull()) break;
TString clss = strtok(0, ",; ");
if (clss.IsNull()) break;
TString plugin = strtok(0, ",; ");
if (plugin.IsNull()) break;
AddHandler(s, regexp, clss, plugin);
cnt++;
}
delete [] v;
}
}
}
}
//______________________________________________________________________________
void TPluginManager::AddHandler(const char *base, const char *regexp,
const char *className, const char *pluginName)
{
// Add plugin handler to the list of handlers. If there is already a
// handler defined for the same base and regexp it will be replaced.
if (!fHandlers) {
fHandlers = new TList;
fHandlers->IsOwner();
}
// make sure there is no previous handler for the same case
RemoveHandler(base, regexp);
TPluginHandler *h = new TPluginHandler(base, regexp, className, pluginName);
fHandlers->Add(h);
}
//______________________________________________________________________________
void TPluginManager::RemoveHandler(const char *base, const char *regexp)
{
// Remove handler for the specified base class and the specified
// regexp. If regexp=0 remove all handlers for the specified base.
if (!fHandlers) return;
TIter next(fHandlers);
TPluginHandler *h;
while ((h = (TPluginHandler*) next())) {
if (h->fBase == base) {
if (!regexp || h->fRegexp == regexp) {
fHandlers->Remove(h);
delete h;
}
}
}
}
//______________________________________________________________________________
TPluginHandler *TPluginManager::FindHandler(const char *base, const char *uri)
{
// Returns the handler if there exists a handler for the specified URI.
// Returns 0 in case handler is not found.
if (!fHandlers) return kFALSE;
TIter next(fHandlers);
TPluginHandler *h;
while ((h = (TPluginHandler*) next())) {
if (h->CanHandle(base, uri)) {
if (gDebug > 0)
Printf("<TPluginManager::FindHandler>: found plugin for %s",
h->GetClass());
return h;
}
}
if (gDebug > 0)
Printf("<TPluginManager::FindHandler>: did not find plugin for handling %s",
uri);
return 0;
}
//______________________________________________________________________________
void TPluginManager::Print(Option_t *) const
{
// Print list of registered plugin handlers.
if (!fHandlers) return;
TIter next(fHandlers);
TPluginHandler *h;
printf("=====================================================================\n");
printf("Base Regexp Class Plugin\n");
printf("=====================================================================\n");
while ((h = (TPluginHandler*) next())) {
printf("%-18s %-15s %-18s %s\n", h->fBase.Data(), h->fRegexp.Data(),
h->fClass.Data(), h->fPlugin.Data());
}
printf("=====================================================================\n\n");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment