Tulip  4.2.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
PluginLister.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef TULIP_PLUGINLISTER_H
21 #define TULIP_PLUGINLISTER_H
22 
23 #include <list>
24 #include <string>
25 #include <set>
26 
27 #include <tulip/Plugin.h>
28 #include <tulip/TlpTools.h>
29 #include <tulip/PluginLibraryLoader.h>
30 #include <tulip/Observable.h>
31 
32 namespace tlp {
33 class PluginContext;
34 
35 /**
36  * @ingroup Plugins
37  * @brief The base class for plugin factories.
38  *
39  * A plugin factory handles the creation process of a tlp::Plugin subclass. This class should never be used directly. See the PLUGIN macro for additional informations.
40  * @see PLUGIN
41  **/
43 public:
44  virtual tlp::Plugin* createPluginObject(tlp::PluginContext* context) = 0;
45 };
46 
47 /**
48  * @ingroup Plugins
49  *
50  * @brief The PluginLister class is a singleton used to list plugins currently loaded into Tulip and retrieve informations about them.
51  *
52  * This class holds various methods to check informations about plugins currently loaded into Tulip. You can use it to list plugins, get dependencies informations or create an instance of a plugin.
53  *
54  * @note Since a plugin name is unique, Plugins are mainly identified by their name (tlp::Plugin::name()) when interfaced with the plugin lister.
55  *
56  * @see tlp::Plugin
57  * @see tlp::PluginLoader
58  * @see tlp::PluginLibraryLoader
59  */
60 class TLP_SCOPE PluginLister : public Observable {
61 private:
62  struct PluginDescription {
63  FactoryInterface* factory;
64  std::string library;
65  Plugin* infos;
66 
67  PluginDescription(): factory(NULL), infos(NULL) {}
68  ~PluginDescription() {
69  if (infos)
70  delete infos;
71  }
72  };
73 
74 public:
75  static PluginLoader *currentLoader;
76 
77  /**
78  * @brief Checks if all registered plug-ins have their dependencies met.
79  *
80  * @param loader If there are errors, the loader is informed about them so they can be displayed.
81  * @return void
82  **/
83  static void checkLoadedPluginsDependencies(tlp::PluginLoader* loader);
84 
85  /**
86  * @brief Gets the static instance of this class. If not already done, creates it beforehand.
87  *
88  * @return PluginLister< ObjectType, Context >* The only instance of this object that exists in the whole program.
89  **/
90  static tlp::PluginLister* instance();
91 
92  /**
93  * @brief Constructs a plug-in.
94  *
95  * @param name The name of the plug-in to instantiate.
96  * @param p The context to give to the plug-in.
97  * @return ObjectType* The newly constructed plug-in.
98  **/
99  static tlp::Plugin* getPluginObject(const std::string& name, tlp::PluginContext* context);
100 
101  /**
102  * @brief Checks if a plugin of a given type is loaded
103  * This method checks the plugin "pluginName" is currently loaded into Tulip and if it's of type PluginType.
104  * @param PluginType the class type of the plugin
105  * @param pluginName the name of the plugin
106  * @return true if a matching plugin is currently loaded into Tulip.
107  */
108  template<typename PluginType>
109  bool pluginExists(const std::string &pluginName) {
110  std::map<std::string, PluginDescription>::const_iterator it =
111  _plugins.find(pluginName);
112  return (it != _plugins.end() &&
113  (dynamic_cast<const PluginType*>(it->second.infos) != NULL));
114  }
115 
116  /**
117  * @brief Similar to tlp::PluginLister::getPluginObject() but returns a typed instance
118  *
119  * This method instantiate a plugin from its name and returns it casted into the given type.
120  *
121  * @param name The plugin's name
122  * @param context The context to give to the plugin
123  *
124  * @return The plugin instance. If there is no such plugin or if the plugin does not match the required type, this method returns NULL
125  */
126  template<typename PluginType>
127  PluginType* getPluginObject(const std::string& name,
128  tlp::PluginContext* context) {
129  std::map<std::string, PluginDescription>::const_iterator it =
130  _plugins.find(name);
131  return (it != _plugins.end() &&
132  (dynamic_cast<const PluginType*>(it->second.infos) != NULL))
133  ? static_cast<PluginType*>(it->second.factory->createPluginObject(context))
134  : NULL;
135  }
136 
137 
138  /**
139  * @brief Gets the list of plug-ins that registered themselves in this factory.
140  *
141  * @return :Iterator< std::string >* An iterator over the names of the plug-ins registered in this factory.
142  **/
143  static std::list<std::string> availablePlugins();
144 
145  template<typename PluginType>
146  std::list<std::string> availablePlugins() {
147  std::list<std::string> keys;
148 
149  for(std::map<std::string, PluginDescription>::const_iterator it = _plugins.begin(); it != _plugins.end(); ++it) {
150  PluginType* plugin = dynamic_cast<PluginType*>(it->second.infos);
151 
152  if(plugin != NULL) {
153  keys.push_back(it->first);
154  }
155  }
156 
157  return keys;
158  }
159 
160  /**
161  * @brief Gets more detailed informations about one specific plug-in.
162  *
163  * @param name The name of the plugin to retrieve informations for.
164  * @return :const Plugin& The informations on the plugin.
165  **/
166  static const Plugin& pluginInformations(const std::string& name);
167 
168  /**
169  * @brief Checks if a given name is registered in this factory.
170  *
171  * @param pluginName The name of the plug-in to look for.
172  * @return bool Whether there is a plug-in with the given name registered in this factory.
173  **/
174  static bool pluginExists(const std::string& pluginName);
175 
176  /**
177  * @brief Gets the list of parameters for the given plug-in.
178  *
179  * @param name The name of the plug-in to retrieve the parameters of.
180  * @return :ParameterDescriptionList The parameters of the plug-in.
181  **/
182  static const ParameterDescriptionList& getPluginParameters(const std::string& name);
183 
184  /**
185  * @brief Gets the dependencies of a plug-in.
186  *
187  * @param name The name of the plug-in to retrieve the dependencies of.
188  * @return :list< tlp::Dependency, std::allocator< tlp::Dependency > > The list of dependencies of the plug-in.
189  **/
190  static const std::list<tlp::Dependency>& getPluginDependencies(const std::string& name);
191 
192  /**
193  * @brief Gets the library from which a plug-in has been loaded.
194  *
195  * @param name The name of the plug-in to retrieve the library of.
196  * @return std::string The library from which the plug-in was loaded.
197  **/
198  static std::string getPluginLibrary(const std::string& name);
199 
200  /**
201  * @brief Removes a plug-in from this factory.
202  * This is usefull when a plug-in has unmet dependencies, or appears more than once.
203  *
204  * @param name The name of the plug-in to remove.
205  * @return void
206  **/
207  static void removePlugin(const std::string& name);
208 
209  /**
210  * @brief Registers a plugin into Tulip
211  *
212  * @warning This method should only be called by tlp::FactoryInterface subclasses
213  * @see PLUGIN
214  */
215  static void registerPlugin(FactoryInterface* objectFactory);
216 
217 protected:
218 
219 
220  void sendPluginAddedEvent(const std::string &pluginName);
221  void sendPluginRemovedEvent(const std::string &pluginName);
222 
223  static PluginLister* _instance;
224 
225  /**
226  * @brief Stores the factory, dependencies, and parameters of all the plugins that register into this factory.
227  **/
228  std::map<std::string , PluginDescription> _plugins;
229 
230  /**
231  * @brief Gets the release number of the given plug-in.
232  *
233  * @param name The name of the plug-in to retrieve the version number of.
234  * @return :string The version number, ussually formatted as X[.Y], where X is the major, and Y the minor.
235  **/
236  static std::string getPluginRelease(const std::string& name);
237 };
238 
239 class TLP_SCOPE PluginEvent : public Event {
240 public:
241 
242  enum PluginEventType {
243  TLP_ADD_PLUGIN = 0,
244  TLP_REMOVE_PLUGIN = 1
245  };
246 
247  // constructor for node/edge events
248  PluginEvent(PluginEventType pluginEvtType, std::string pluginName)
249  : Event(*(tlp::PluginLister::instance()), Event::TLP_MODIFICATION),
250  evtType(pluginEvtType), pluginName(pluginName) {}
251 
252  PluginEventType getType() const {
253  return evtType;
254  }
255 
256  std::string getPluginName() const {
257  return pluginName;
258  }
259 
260 protected:
261 
262  PluginEventType evtType;
263  std::string pluginName;
264 
265 };
266 
267 }
268 
269 #endif //TULIP_PLUGINLISTER_H