Back to index

nordugrid-arc-nox  1.1.0~rc6
Plugin.h
Go to the documentation of this file.
00001 #ifndef __ARC_PLUGIN_H__
00002 
00003 #define __ARC_PLUGIN_H__
00004 
00005 #include <string>
00006 #include <map>
00007 #include <typeinfo>
00008 #include <inttypes.h>
00009 #include <sys/types.h>
00010 #ifdef HAVE_STDINT_H
00011 #include <stdint.h>
00012 #endif
00013 
00014 #include <arc/Thread.h>
00015 #include <arc/Logger.h>
00016 #include <arc/XMLNode.h>
00017 #include <arc/loader/ModuleManager.h>
00018 
00019 namespace Arc {
00020 
00021   class PluginsFactory;
00022 
00024 
00026   class Plugin {
00027     protected:
00028       Plugin(void);
00029     public:
00030       virtual ~Plugin(void);
00031   };
00032 
00034 
00037   class PluginArgument {
00038     friend class PluginsFactory;
00039     private:
00040       PluginsFactory* factory_;
00041       Glib::Module* module_;
00042       void set_factory(PluginsFactory* factory);
00043       void set_module(Glib::Module* module);
00044     protected:
00045       PluginArgument(void);
00046     public:
00047       virtual ~PluginArgument(void);
00049 
00052       PluginsFactory* get_factory(void);
00054 
00059       Glib::Module* get_module(void);
00060   };
00061 
00063 
00067   extern const char* plugins_table_name;
00068 
00069   #define PLUGINS_TABLE_NAME __arc_plugins_table__
00070   #define PLUGINS_TABLE_SYMB "__arc_plugins_table__"
00071 
00073 
00078   typedef Plugin* (*get_plugin_instance)(PluginArgument* arg);
00079 
00081   typedef struct {
00082     const char* name; // Unique name of plugin in scope of its kind
00083     const char* kind; // Type/kind of plugin
00084     uint32_t version; // Version of plugin (0 if not applicable)
00085     get_plugin_instance instance; // Pointer to constructor function
00086   } PluginDescriptor;
00087 
00088 
00090 
00091   class PluginDesc {
00092    public:
00093     std::string name;
00094     std::string kind;
00095     uint32_t version;
00096   };
00097 
00099 
00100   class ModuleDesc {
00101    public:
00102     std::string name;
00103     std::list<PluginDesc> plugins;
00104   };
00105 
00107 
00115   class PluginsFactory: public ModuleManager {
00116     private:
00117       Glib::Mutex lock_;
00118       typedef std::map<std::string,PluginDescriptor*> descriptors_t_;
00119       typedef std::map<std::string,Glib::Module*> modules_t_;
00120       descriptors_t_ descriptors_;
00121       modules_t_ modules_;
00122       bool try_load_;
00123       static Logger logger;
00124       bool load(const std::string& name,const std::list<std::string>& kinds,const std::list<std::string>& pnames);
00125     public:
00128       PluginsFactory(XMLNode cfg);
00145       void TryLoad(bool v = true) { try_load_ = v; };
00146       bool TryLoad(void) { return try_load_; };
00147       Plugin* get_instance(const std::string& kind,PluginArgument* arg,bool search = true);
00148       Plugin* get_instance(const std::string& kind,int version,PluginArgument* arg,bool search = true);
00149       Plugin* get_instance(const std::string& kind,int min_version,int max_version,PluginArgument* arg,bool search = true);
00150       Plugin* get_instance(const std::string& kind,const std::string& name,PluginArgument* arg,bool search = true);
00151       Plugin* get_instance(const std::string& kind,const std::string& name,int version,PluginArgument* arg,bool search = true);
00152       Plugin* get_instance(const std::string& kind,const std::string& name,int min_version,int max_version,PluginArgument* arg,bool search = true);
00160       bool load(const std::string& name);
00161       bool load(const std::string& name,const std::string& kind);
00162       bool load(const std::string& name,const std::string& kind,const std::string& pname);
00163       bool load(const std::string& name,const std::list<std::string>& kinds);
00164       bool load(const std::list<std::string>& names,const std::string& kind);
00165       bool load(const std::list<std::string>& names,const std::string& kind,const std::string& pname);
00166       bool load(const std::list<std::string>& names,const std::list<std::string>& kinds);
00167 
00171       bool scan(const std::string& name, ModuleDesc& desc);
00172       bool scan(const std::list<std::string>& names, std::list<ModuleDesc>& descs);
00174       void report(std::list<ModuleDesc>& descs);
00175       template<class P>
00176       P* GetInstance(const std::string& kind,PluginArgument* arg,bool search = true) {
00177         Plugin* plugin = get_instance(kind,arg,search);
00178         if(!plugin) return NULL;
00179         P* p = dynamic_cast<P*>(plugin);
00180         if(!p) delete plugin;
00181         return p;
00182       };
00183       template<class P>
00184       P* GetInstance(const std::string& kind,const std::string& name,PluginArgument* arg,bool search = true) {
00185         Plugin* plugin = get_instance(kind,name,arg,search);
00186         if(!plugin) return NULL;
00187         P* p = dynamic_cast<P*>(plugin);
00188         if(!p) delete plugin;
00189         return p;
00190       };
00191   };
00192 
00193   template<class P>
00194   P* PluginCast(PluginArgument* p) {
00195     if(p == NULL) return NULL;
00196     P* pp = dynamic_cast<P*>(p);
00197     if(pp != NULL) return pp;
00198     // Workaround for g++ and loadable modules
00199     if(strcmp(typeid(P).name(),typeid(*p).name()) != 0) return NULL;
00200     return static_cast<P*>(p);
00201   }
00202 
00203   template<class P>
00204   P* PluginCast(Plugin* p) {
00205     if(p == NULL) return NULL;
00206     P* pp = dynamic_cast<P*>(p);
00207     if(pp != NULL) return pp;
00208     // Workaround for g++ and loadable modules
00209     if(strcmp(typeid(P).name(),typeid(*p).name()) != 0) return NULL;
00210     return static_cast<P*>(p);
00211   }
00212 
00213 } // namespace Arc
00214 
00215 #endif /* __ARC_PLUGIN_H__ */
00216