Tulip  4.4.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 <map>
26 
27 #include <tulip/Plugin.h>
28 #include <tulip/PluginLoader.h>
29 #include <tulip/Observable.h>
30 
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 information.
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 information about them.
51  *
52  * This class holds various methods to check information about plugins currently loaded into Tulip. You can use it to list plugins, get dependencies information 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  delete infos;
70  }
71  };
72 
73 public:
74  static PluginLoader *currentLoader;
75 
76  /**
77  * @brief Checks if all registered plug-ins have their dependencies met.
78  *
79  * @param loader If there are errors, the loader is informed about them so they can be displayed.
80  * @return void
81  **/
82  static void checkLoadedPluginsDependencies(tlp::PluginLoader* loader);
83 
84  /**
85  * @brief Gets the static instance of this class. If not already done, creates it beforehand.
86  *
87  * @return PluginLister< ObjectType, Context >* The only instance of this object that exists in the whole program.
88  **/
89  static tlp::PluginLister* instance();
90 
91  /**
92  * @brief Constructs a plug-in.
93  *
94  * @param name The name of the plug-in to instantiate.
95  * @param p The context to give to the plug-in.
96  * @return ObjectType* The newly constructed plug-in.
97  **/
98  static tlp::Plugin* getPluginObject(const std::string& name, tlp::PluginContext* context);
99 
100  /**
101  * @brief Checks if a plugin of a given type is loaded
102  * This method checks the plugin "pluginName" is currently loaded into Tulip and if it's of type PluginType.
103  * @param PluginType the class type of the plugin
104  * @param pluginName the name of the plugin
105  * @return true if a matching plugin is currently loaded into Tulip.
106  */
107  template<typename PluginType>
108  bool pluginExists(const std::string &pluginName) {
109  std::map<std::string, PluginDescription>::const_iterator it =
110  _plugins.find(pluginName);
111  return (it != _plugins.end() &&
112  (dynamic_cast<const PluginType*>(it->second.infos) != NULL));
113  }
114 
115  /**
116  * @brief Similar to tlp::PluginLister::getPluginObject() but returns a typed instance
117  *
118  * This method instantiate a plugin from its name and returns it casted into the given type.
119  *
120  * @param name The plugin's name
121  * @param context The context to give to the plugin
122  *
123  * @return The plugin instance. If there is no such plugin or if the plugin does not match the required type, this method returns NULL
124  */
125  template<typename PluginType>
126  PluginType* getPluginObject(const std::string& name,
127  tlp::PluginContext* context) {
128  std::map<std::string, PluginDescription>::const_iterator it =
129  _plugins.find(name);
130  return (it != _plugins.end() &&
131  (dynamic_cast<const PluginType*>(it->second.infos) != NULL))
132  ? static_cast<PluginType*>(it->second.factory->createPluginObject(context))
133  : NULL;
134  }
135 
136 
137  /**
138  * @brief Gets the list of plugins of a given type (template parameter). *
139  * @return A std::list<std::string> containing the names of the plugins.
140  **/
141  static std::list<std::string> availablePlugins();
142 
143 
144  template<typename PluginType>
145  std::list<std::string> availablePlugins() {
146  std::list<std::string> keys;
147 
148  for(std::map<std::string, PluginDescription>::const_iterator it = _plugins.begin(); it != _plugins.end(); ++it) {
149  PluginType* plugin = dynamic_cast<PluginType*>(it->second.infos);
150 
151  if(plugin != NULL) {
152  keys.push_back(it->first);
153  }
154  }
155 
156  return keys;
157  }
158 
159  /**
160  * @brief Gets more detailed information about one specific plug-in.
161  *
162  * @param name The name of the plugin to retrieve information for.
163  * @return :const Plugin& The information on the plugin.
164  **/
165  static const Plugin& pluginInformation(const std::string& name);
166 
167  /**
168  * @brief Gets more detailed information about one specific plug-in.
169  * @deprecated this function should not be used anymore, please use PluginLister::pluginInformation() instead.
170  *
171  * @param name The name of the plugin to retrieve information for.
172  * @return :const Plugin& The information on the plugin.
173  **/
174  static _DEPRECATED const Plugin& pluginInformations(const std::string& name);
175 
176  /**
177  * @brief Checks if a given name is registered in this factory.
178  *
179  * @param pluginName The name of the plug-in to look for.
180  * @return bool Whether there is a plug-in with the given name registered in this factory.
181  **/
182  static bool pluginExists(const std::string& pluginName);
183 
184  /**
185  * @brief Gets the list of parameters for the given plug-in.
186  *
187  * @param name The name of the plug-in to retrieve the parameters of.
188  * @return :ParameterDescriptionList The parameters of the plug-in.
189  **/
190  static const ParameterDescriptionList& getPluginParameters(const std::string& name);
191 
192  /**
193  * @brief Gets the dependencies of a plug-in.
194  *
195  * @param name The name of the plug-in to retrieve the dependencies of.
196  * @return :list< tlp::Dependency, std::allocator< tlp::Dependency > > The list of dependencies of the plug-in.
197  **/
198  static const std::list<tlp::Dependency>& getPluginDependencies(const std::string& name);
199 
200  /**
201  * @brief Gets the library from which a plug-in has been loaded.
202  *
203  * @param name The name of the plug-in to retrieve the library of.
204  * @return std::string The library from which the plug-in was loaded.
205  **/
206  static std::string getPluginLibrary(const std::string& name);
207 
208  /**
209  * @brief Removes a plug-in from this factory.
210  * This is usefull when a plug-in has unmet dependencies, or appears more than once.
211  *
212  * @param name The name of the plug-in to remove.
213  * @return void
214  **/
215  static void removePlugin(const std::string& name);
216 
217  /**
218  * @brief Registers a plugin into Tulip
219  *
220  * @warning This method should only be called by tlp::FactoryInterface subclasses
221  * @see PLUGIN
222  */
223  static void registerPlugin(FactoryInterface* objectFactory);
224 
225 protected:
226 
227 
228  void sendPluginAddedEvent(const std::string &pluginName);
229  void sendPluginRemovedEvent(const std::string &pluginName);
230 
231  static PluginLister* _instance;
232 
233  /**
234  * @brief Stores the factory, dependencies, and parameters of all the plugins that register into this factory.
235  **/
236  std::map<std::string , PluginDescription> _plugins;
237 
238  /**
239  * @brief Gets the release number of the given plug-in.
240  *
241  * @param name The name of the plug-in to retrieve the version number of.
242  * @return :string The version number, ussually formatted as X[.Y], where X is the major, and Y the minor.
243  **/
244  static std::string getPluginRelease(const std::string& name);
245 };
246 
247 class TLP_SCOPE PluginEvent : public Event {
248 public:
249 
250  enum PluginEventType {
251  TLP_ADD_PLUGIN = 0,
252  TLP_REMOVE_PLUGIN = 1
253  };
254 
255  // constructor for node/edge events
256  PluginEvent(PluginEventType pluginEvtType, std::string pluginName)
257  : Event(*(tlp::PluginLister::instance()), Event::TLP_MODIFICATION),
258  evtType(pluginEvtType), pluginName(pluginName) {}
259 
260  PluginEventType getType() const {
261  return evtType;
262  }
263 
264  std::string getPluginName() const {
265  return pluginName;
266  }
267 
268 protected:
269 
270  PluginEventType evtType;
271  std::string pluginName;
272 
273 };
274 
275 }
276 
277 #endif //TULIP_PLUGINLISTER_H