00001 // @(#)root/base:$Id: TPluginManager.h 37497 2010-12-10 12:22:54Z rdm $ 00002 // Author: Fons Rademakers 26/1/2002 00003 00004 /************************************************************************* 00005 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * 00006 * All rights reserved. * 00007 * * 00008 * For the licensing terms see $ROOTSYS/LICENSE. * 00009 * For the list of contributors see $ROOTSYS/README/CREDITS. * 00010 *************************************************************************/ 00011 00012 #ifndef ROOT_TPluginManager 00013 #define ROOT_TPluginManager 00014 00015 00016 ////////////////////////////////////////////////////////////////////////// 00017 // // 00018 // TPluginManager // 00019 // // 00020 // This class implements a plugin library manager. It keeps track of // 00021 // a list of plugin handlers. A plugin handler knows which plugin // 00022 // library to load to get a specific class that is used to extend the // 00023 // functionality of a specific base class and how to create an object // 00024 // of this class. For example, to extend the base class TFile to be // 00025 // able to read RFIO files one needs to load the plugin library // 00026 // libRFIO.so which defines the TRFIOFile class. This loading should // 00027 // be triggered when a given URI contains a regular expression defined // 00028 // by the handler. // 00029 // Plugin handlers can be defined via macros in a list of plugin // 00030 // directories. With $ROOTSYS/etc/plugins the default top plugin // 00031 // directory specified in $ROOTSYS/etc/system.rootrc. Additional // 00032 // directories can be specified by adding them to the end of the list. // 00033 // Macros for identical plugin handlers in later directories will // 00034 // override previous ones (the inverse of normal search path behavior). // 00035 // The macros must have names like <BaseClass>/PX0_<PluginClass>.C, // 00036 // e.g.: // 00037 // TFile/P10_TRFIOFile.C, TSQLServer/P20_TMySQLServer.C, etc. // 00038 // to allow easy sorting and grouping. If the BaseClass is in a // 00039 // namespace the directory must have the name NameSpace@@BaseClass as // 00040 // : is a reserved pathname character on some operating systems. // 00041 // Macros not beginning with 'P' and ending with ".C" are ignored. // 00042 // These macros typically look like: // 00043 // // 00044 // void P10_TDCacheFile() // 00045 // { // 00046 // gPluginMgr->AddHandler("TFile", "^dcache", "TDCacheFile", // 00047 // "DCache", "TDCacheFile(const char*,Option_t*)"); // 00048 // } // 00049 // // 00050 // Plugin handlers can also be defined via resources in the .rootrc // 00051 // file. Although now deprecated this method still works for backward // 00052 // compatibility, e.g.: // 00053 // // 00054 // Plugin.TFile: ^rfio: TRFIOFile RFIO "<constructor>" // 00055 // Plugin.TSQLServer: ^mysql: TMySQLServer MySQL "<constructor>" // 00056 // +Plugin.TSQLServer: ^pgsql: TPgSQLServer PgSQL "<constructor>" // 00057 // Plugin.TVirtualFitter: * TFitter Minuit "TFitter(Int_t)" // 00058 // // 00059 // Where the + in front of Plugin.TSQLServer says that it extends the // 00060 // existing definition of TSQLServer, useful when there is more than // 00061 // one plugin that can extend the same base class. The "<constructor>" // 00062 // should be the constructor or a static method that generates an // 00063 // instance of the specified class. Global methods should start with // 00064 // "::" in their name, like "::CreateFitter()". // 00065 // Instead of being a shared library a plugin can also be a CINT // 00066 // script, so instead of libDialog.so one can have Dialog.C. // 00067 // The * is a placeholder in case there is no need for a URI to // 00068 // differentiate between different plugins for the same base class. // 00069 // For the default plugins see $ROOTSYS/etc/system.rootrc. // 00070 // // 00071 // Plugin handlers can also be registered at run time, e.g.: // 00072 // // 00073 // gPluginMgr->AddHandler("TSQLServer", "^sapdb:", // 00074 // "TSapDBServer", "SapDB", // 00075 // "TSapDBServer(const char*,const char*, const char*)"); // 00076 // // 00077 // A list of currently defined handlers can be printed using: // 00078 // // 00079 // gPluginMgr->Print(); // use option="a" to see ctors // 00080 // // 00081 // The use of the plugin library manager removes all textual references // 00082 // to hard-coded class and library names and the resulting dependencies // 00083 // in the base classes. The plugin manager is used to extend a.o. // 00084 // TFile, TSQLServer, TGrid, etc. functionality. // 00085 // // 00086 ////////////////////////////////////////////////////////////////////////// 00087 00088 #ifndef ROOT_TObject 00089 #include "TObject.h" 00090 #endif 00091 #ifndef ROOT_TString 00092 #include "TString.h" 00093 #endif 00094 00095 class TEnv; 00096 class TList; 00097 class THashTable; 00098 class TFunction; 00099 class TMethodCall; 00100 class TPluginManager; 00101 00102 00103 class TPluginHandler : public TObject { 00104 00105 friend class TPluginManager; 00106 00107 private: 00108 TString fBase; // base class which will be extended by plugin 00109 TString fRegexp; // regular expression which must be matched in URI 00110 TString fClass; // class to be loaded from plugin library 00111 TString fPlugin; // plugin library which should contain fClass 00112 TString fCtor; // ctor used to instantiate object of fClass 00113 TString fOrigin; // origin of plugin handler definition 00114 TMethodCall *fCallEnv; //!ctor method call environment 00115 TFunction *fMethod; //!ctor method or global function 00116 Int_t fCanCall; //!if 1 fCallEnv is ok, -1 fCallEnv is not ok 00117 Bool_t fIsMacro; // plugin is a macro and not a library 00118 Bool_t fIsGlobal; // plugin ctor is a global function 00119 00120 TPluginHandler() : 00121 fBase(), fRegexp(), fClass(), fPlugin(), fCtor(), fOrigin(), 00122 fCallEnv(0), fMethod(0), fCanCall(0), fIsMacro(kTRUE), fIsGlobal(kTRUE) { } 00123 TPluginHandler(const char *base, const char *regexp, 00124 const char *className, const char *pluginName, 00125 const char *ctor, const char *origin); 00126 TPluginHandler(const TPluginHandler&); // not implemented 00127 TPluginHandler& operator=(const TPluginHandler&); // not implemented 00128 00129 ~TPluginHandler(); 00130 00131 const char *GetBase() const { return fBase; } 00132 const char *GetRegexp() const { return fRegexp; } 00133 const char *GetPlugin() const { return fPlugin; } 00134 const char *GetCtor() const { return fCtor; } 00135 const char *GetOrigin() const { return fOrigin; } 00136 00137 Bool_t CanHandle(const char *base, const char *uri); 00138 void SetupCallEnv(); 00139 00140 public: 00141 const char *GetClass() const { return fClass; } 00142 Int_t CheckPlugin() const; 00143 Int_t LoadPlugin(); 00144 Long_t ExecPlugin(Int_t nargs, ...); 00145 00146 void Print(Option_t *opt = "") const; 00147 00148 ClassDef(TPluginHandler,3) // Handler for plugin libraries 00149 }; 00150 00151 00152 class TPluginManager : public TObject { 00153 00154 private: 00155 TList *fHandlers; // list of plugin handlers 00156 THashTable *fBasesLoaded; //! table of base classes already checked or loaded 00157 Bool_t fReadingDirs; //! true if we are running LoadHandlersFromPluginDirs 00158 00159 TPluginManager(const TPluginManager& pm); // not implemented 00160 TPluginManager& operator=(const TPluginManager& pm); // not implemented 00161 void LoadHandlerMacros(const char *path); 00162 00163 public: 00164 TPluginManager() : fHandlers(0), fBasesLoaded(0), fReadingDirs(kFALSE) { } 00165 ~TPluginManager(); 00166 00167 void LoadHandlersFromEnv(TEnv *env); 00168 void LoadHandlersFromPluginDirs(const char *base = 0); 00169 void AddHandler(const char *base, const char *regexp, 00170 const char *className, const char *pluginName, 00171 const char *ctor = 0, const char *origin = 0); 00172 void RemoveHandler(const char *base, const char *regexp = 0); 00173 00174 TPluginHandler *FindHandler(const char *base, const char *uri = 0); 00175 00176 void Print(Option_t *opt = "") const; 00177 Int_t WritePluginMacros(const char *dir, const char *plugin = 0) const; 00178 Int_t WritePluginRecords(const char *envFile, const char *plugin = 0) const; 00179 00180 ClassDef(TPluginManager,1) // Manager for plugin handlers 00181 }; 00182 00183 R__EXTERN TPluginManager *gPluginMgr; 00184 00185 #endif