Tulip  4.3.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 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  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 informations about one specific plug-in.
161  *
162  * @param name The name of the plugin to retrieve informations for.
163  * @return :const Plugin& The informations on the plugin.
164  **/
165  static const Plugin& pluginInformations(const std::string& name);
166 
167  /**
168  * @brief Checks if a given name is registered in this factory.
169  *
170  * @param pluginName The name of the plug-in to look for.
171  * @return bool Whether there is a plug-in with the given name registered in this factory.
172  **/
173  static bool pluginExists(const std::string& pluginName);
174 
175  /**
176  * @brief Gets the list of parameters for the given plug-in.
177  *
178  * @param name The name of the plug-in to retrieve the parameters of.
179  * @return :ParameterDescriptionList The parameters of the plug-in.
180  **/
181  static const ParameterDescriptionList& getPluginParameters(const std::string& name);
182 
183  /**
184  * @brief Gets the dependencies of a plug-in.
185  *
186  * @param name The name of the plug-in to retrieve the dependencies of.
187  * @return :list< tlp::Dependency, std::allocator< tlp::Dependency > > The list of dependencies of the plug-in.
188  **/
189  static const std::list<tlp::Dependency>& getPluginDependencies(const std::string& name);
190 
191  /**
192  * @brief Gets the library from which a plug-in has been loaded.
193  *
194  * @param name The name of the plug-in to retrieve the library of.
195  * @return std::string The library from which the plug-in was loaded.
196  **/
197  static std::string getPluginLibrary(const std::string& name);
198 
199  /**
200  * @brief Removes a plug-in from this factory.
201  * This is usefull when a plug-in has unmet dependencies, or appears more than once.
202  *
203  * @param name The name of the plug-in to remove.
204  * @return void
205  **/
206  static void removePlugin(const std::string& name);
207 
208  /**
209  * @brief Registers a plugin into Tulip
210  *
211  * @warning This method should only be called by tlp::FactoryInterface subclasses
212  * @see PLUGIN
213  */
214  static void registerPlugin(FactoryInterface* objectFactory);
215 
216 protected:
217 
218 
219  void sendPluginAddedEvent(const std::string &pluginName);
220  void sendPluginRemovedEvent(const std::string &pluginName);
221 
222  static PluginLister* _instance;
223 
224  /**
225  * @brief Stores the factory, dependencies, and parameters of all the plugins that register into this factory.
226  **/
227  std::map<std::string , PluginDescription> _plugins;
228 
229  /**
230  * @brief Gets the release number of the given plug-in.
231  *
232  * @param name The name of the plug-in to retrieve the version number of.
233  * @return :string The version number, ussually formatted as X[.Y], where X is the major, and Y the minor.
234  **/
235  static std::string getPluginRelease(const std::string& name);
236 };
237 
238 class TLP_SCOPE PluginEvent : public Event {
239 public:
240 
241  enum PluginEventType {
242  TLP_ADD_PLUGIN = 0,
243  TLP_REMOVE_PLUGIN = 1
244  };
245 
246  // constructor for node/edge events
247  PluginEvent(PluginEventType pluginEvtType, std::string pluginName)
248  : Event(*(tlp::PluginLister::instance()), Event::TLP_MODIFICATION),
249  evtType(pluginEvtType), pluginName(pluginName) {}
250 
251  PluginEventType getType() const {
252  return evtType;
253  }
254 
255  std::string getPluginName() const {
256  return pluginName;
257  }
258 
259 protected:
260 
261  PluginEventType evtType;
262  std::string pluginName;
263 
264 };
265 
266 }
267 
268 #endif //TULIP_PLUGINLISTER_H