All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PluginManager.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/plugin/PluginManager.cpp
22 
23  \brief A singleton for managing plugins.
24 */
25 
26 // TerraLib
27 #include "../common/STLUtils.h"
28 #include "../common/TerraLib.h"
29 #include "../common/Translator.h"
30 #include "AbstractFinder.h"
31 #include "AbstractPlugin.h"
32 #include "AbstractPluginEngine.h"
33 #include "DefaultFinder.h"
34 #include "PluginEngineFactory.h"
35 #include "PluginInfo.h"
36 #include "PluginManager.h"
37 
38 // STL
39 #include <algorithm>
40 #include <cassert>
41 #include <memory>
42 
43 // Boost
44 #include <boost/graph/adjacency_list.hpp>
45 #include <boost/graph/properties.hpp>
46 #include <boost/graph/exception.hpp>
47 #include <boost/graph/topological_sort.hpp>
48 #include <boost/format.hpp>
49 #include <boost/filesystem.hpp>
50 
51 std::vector<std::string>
53 {
54  std::vector<std::string> plugins;
55 
56 // retrieve the list of loaded plugins
57  for(std::vector<AbstractPlugin*>::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
58  plugins.push_back((*it)->getInfo().m_name);
59 
60 // retrieve the list of unloaded plugins
61  for(boost::ptr_vector<PluginInfo>::const_iterator it = m_unloadedPlugins.begin(); it != m_unloadedPlugins.end(); ++it)
62  plugins.push_back(it->m_name);
63 
64 // retrieve the list of broken plugins
65  for(boost::ptr_vector<PluginInfo>::const_iterator it = m_brokenPlugins.begin(); it != m_brokenPlugins.end(); ++it)
66  plugins.push_back(it->m_name);
67 
68  return plugins;
69 }
70 
71 const te::plugin::PluginInfo& te::plugin::PluginManager::getPlugin(const std::string& name) const
72 {
73 // check in the loaded list first
74  {
75  std::map<std::string, AbstractPlugin*>::const_iterator it = m_pluginsMap.find(name);
76 
77  if(it != m_pluginsMap.end())
78  return it->second->getInfo();
79  }
80 
81 // check in not-loaded list
82  for(boost::ptr_vector<PluginInfo>::const_iterator it = m_unloadedPlugins.begin(); it != m_unloadedPlugins.end(); ++it)
83  if(it->m_name == name)
84  return *it;
85 
86 // check in the broken list
87  for(boost::ptr_vector<PluginInfo>::const_iterator it = m_brokenPlugins.begin(); it != m_brokenPlugins.end(); ++it)
88  if(it->m_name == name)
89  return *it;
90 
91  throw Exception((boost::format("Could not find plugin %1%") % name).str());
92 }
93 
94 const boost::ptr_vector<te::plugin::PluginInfo>& te::plugin::PluginManager::getUnloadedPlugins() const
95 {
96  return m_unloadedPlugins;
97 }
98 
99 void te::plugin::PluginManager::setUnloadedPlugins(const boost::ptr_vector<te::plugin::PluginInfo> unloadedPlugins)
100 {
101  m_unloadedPlugins = unloadedPlugins;
102 }
103 
104 const boost::ptr_vector<te::plugin::PluginInfo>& te::plugin::PluginManager::getBrokenPlugins() const
105 {
106  return m_brokenPlugins;
107 }
108 
109 void te::plugin::PluginManager::setBrokenPlugins(const boost::ptr_vector<te::plugin::PluginInfo> brokenPlugins)
110 {
111  m_brokenPlugins = brokenPlugins;
112 }
113 
114 bool te::plugin::PluginManager::isBrokenPlugin(const std::string& pluginName) const
115 {
116  for(boost::ptr_vector<PluginInfo>::const_iterator it = m_brokenPlugins.begin(); it != m_brokenPlugins.end(); ++it)
117  if(it->m_name == pluginName)
118  return true;
119 
120  return false;
121 }
122 
123 bool te::plugin::PluginManager::isUnloadedPlugin(const std::string& pluginName) const
124 {
125  for(boost::ptr_vector<PluginInfo>::const_iterator it = m_unloadedPlugins.begin(); it != m_unloadedPlugins.end(); ++it)
126  if(it->m_name == pluginName)
127  return true;
128 
129  return false;
130 }
131 
132 bool te::plugin::PluginManager::isLoaded(const std::string& pname) const
133 {
134  return m_pluginsMap.find(pname) != m_pluginsMap.end();
135 }
136 
138 {
139 // unload all plugins before loading all again!
140  unloadAll();
141 
142  boost::ptr_vector<PluginInfo> plugins;
143 
144 // have we already load plugins?
145  if(m_unloadedPlugins.empty())
146  {
147 // if yes, then we can find and load new plugins
148  if(m_finders.empty())
149  {
150  DefaultFinder f;
151  f.getPlugins(plugins);
152  }
153  else
154  {
155  const std::size_t nfinders = m_finders.size();
156 
157  for(std::size_t i = 0; i < nfinders; ++i)
158  m_finders[i]->getPlugins(plugins);
159  }
160  }
161  else
162  {
163 // use last unloaded list
164  plugins = m_unloadedPlugins;
165  }
166 
167  load(plugins, start);
168 }
169 
171 {
172 // start by the last loaded plugin
173  std::vector<AbstractPlugin*>::reverse_iterator it = m_plugins.rbegin();
174 
175  while(it != m_plugins.rend())
176  {
177  std::auto_ptr<PluginInfo> pinfo(new PluginInfo((*it)->getInfo()));
178  unload(*it);
179  m_unloadedPlugins.push_back(pinfo.release());
180  it = m_plugins.rbegin(); // always get last loaded plugin
181  }
182 
183 // some assertions
184  assert(m_pluginCategoryMap.empty());
185  assert(m_plugins.empty());
186  assert(m_pluginsMap.empty());
187 }
188 
190 {
191  unloadAll();
192  m_unloadedPlugins.clear();
193  m_brokenPlugins.clear();
194 }
195 
196 void te::plugin::PluginManager::load(boost::ptr_vector<PluginInfo>& plugins, const bool start)
197 {
198  sort(plugins);
199 
200  bool hasException = false;
201 
202  const std::size_t nplugins = plugins.size();
203 
204  std::string exceptionPlugins;
205 
206  for(std::size_t i = 0; i < nplugins; ++i)
207  {
208  const PluginInfo& pInfo = plugins[i];
209 
210  try
211  {
212  load(pInfo, start);
213  }
214  catch(...)
215  {
216  hasException = true;
217  exceptionPlugins += "\n" + pInfo.m_name;
218  }
219  }
220 
221  if(hasException || !m_brokenPlugins.empty())
222  throw Exception(TE_TR("\n\nPlugins not loaded:" ) + exceptionPlugins);
223 }
224 
225 void te::plugin::PluginManager::load(const PluginInfo& pInfo, const bool start)
226 {
227  if(isLoaded(pInfo.m_name))
228  throw Exception((boost::format("Plugin %1% is already loaded") % pInfo.m_name).str());
229 
230 // check if required plugins is already loaded
231  if(!isLoaded(pInfo.m_requiredPlugins))
232  {
233  moveToBrokenList(pInfo);
234  throw Exception(TE_TR("A required plugin is not loaded!"));
235  }
236 
237  std::auto_ptr<AbstractPlugin> plugin;
238 
239 /////////////////////////////
240 // how many modules were loaded before the plugin?
241  std::size_t nmodules = TerraLib::getInstance().getNumRegModules();
242 /////////////////////////////
243 
244  try
245  {
246 // if everything is ready for loading the plugin let's call its engine
247  std::auto_ptr<AbstractPluginEngine> engine(PluginEngineFactory::make(pInfo.m_engine));
248 
249  if(engine.get() == 0)
250  throw Exception((boost::format("Could not determine plugin's language type for %1%!") % pInfo.m_name).str());
251 
252  plugin.reset(engine->load(pInfo));
253 
254  if(plugin.get() == 0)
255  throw Exception((boost::format("Could not load plugin %1%!") % pInfo.m_name).str());
256  }
257  catch(const std::exception& e)
258  {
259  moveToBrokenList(pInfo);
260  Exception ee(e.what());
261  throw ee;
262  }
263  catch(...)
264  {
265  moveToBrokenList(pInfo);
266  throw;
267  }
268 
269  try
270  {
271 /////////////////////////////
272 // if after loading the plugin there are more modules than before we need to initilize the new loaded modules
273  if(TerraLib::getInstance().getNumRegModules() > nmodules)
274  {
275  std::size_t nnmodules = TerraLib::getInstance().getNumRegModules();
276 
277  for(std::size_t i = nmodules; i < nnmodules; ++i)
279  }
280 /////////////////////////////
281 
282  if(start)
283  plugin->startup();
284 
285  std::string plg_name = plugin->getInfo().m_name;
286 // register plugin in the map and add it to its category
287  m_pluginCategoryMap[pInfo.m_category].push_back(plugin.get());
288  m_plugins.push_back(plugin.get());
289  m_pluginsMap[plg_name] = plugin.release();
290 
291 // remove plugin from broken or unloaded list
292  removeFromBrokenList(pInfo);
293  removeFromUnloadedList(pInfo);
294 
295  updateDependents(plg_name);
296  }
297  catch(const std::exception& e)
298  {
299  moveToBrokenList(pInfo);
300  Exception ee(e.what());
301  throw ee;
302  }
303  catch(...)
304  {
305  moveToBrokenList(pInfo);
306  throw; // sorry, but maybe this will cause the code to crash due to the unload of plugin module!
307  }
308 }
309 
310 void te::plugin::PluginManager::load(const std::string& pluginName)
311 {
312  load(getPlugin(pluginName));
313 }
314 
315 void te::plugin::PluginManager::unload(const std::string& name)
316 {
317  std::map<std::string, AbstractPlugin*>::iterator it = m_pluginsMap.find(name);
318 
319  if(it == m_pluginsMap.end())
320  throw Exception((boost::format("Plugin %1% is not loaded!") % name).str());
321 
322  AbstractPlugin* plugin = it->second;
323 
324  if(plugin == 0)
325  throw Exception((boost::format("Plugin %1% is NULL!") % name).str());
326 
327  unload(plugin);
328 }
329 
331 {
332  const std::string pluginName = plugin->getInfo().m_name;
333  const std::string pluginCategory = plugin->getInfo().m_category;
334 
335 // check dependency
336  if(hasDependents(pluginName))
337  moveDependentsToBrokenList(pluginName);
338 // throw Exception((boost::format("Could not unload plugin %1% because other plugins depends on it!") % pluginName).str());
339 
340 // shutdown plugin!
341  if(plugin->isStarted())
342  plugin->shutdown();
343 
344 // locate plugin engine and unload it!
345  std::auto_ptr<AbstractPluginEngine> engine(PluginEngineFactory::make(plugin->getInfo().m_engine));
346 
347  if(engine.get() == 0)
348  throw Exception((boost::format("Could not determine plugin %1% language type!") % pluginName).str());
349 
350  std::auto_ptr<PluginInfo> pInfo(new PluginInfo(plugin->getInfo()));
351 
352  engine->unload(plugin); // the plugin pointer is already invalidated!
353 
354  m_unloadedPlugins.push_back(pInfo);
355 
356 // remove plugin from manager if it is managed by it
357  removeFromCategory(plugin, pluginCategory);
358 
359  {
360  std::vector<AbstractPlugin*>::iterator it = std::find(m_plugins.begin(), m_plugins.end(), plugin);
361 
362  if(it != m_plugins.end())
363  m_plugins.erase(it);
364  }
365 
366  {
367  std::map<std::string, AbstractPlugin*>::iterator it = m_pluginsMap.find(pluginName);
368 
369  if(it != m_pluginsMap.end())
370  m_pluginsMap.erase(it);
371  }
372 }
373 
375 {
376 // start by the last loaded plugin
377  std::vector<AbstractPlugin*>::reverse_iterator it = m_plugins.rbegin();
378 
379  while(it != m_plugins.rend())
380  {
381  if((*it)->isStarted())
382  (*it)->shutdown();
383 
384  ++it;
385  }
386 }
387 
389 {
390  return m_pluginsMap.size() + m_unloadedPlugins.size() + m_brokenPlugins.size();
391 }
392 
393 bool te::plugin::PluginManager::isLoaded(const std::vector<std::string>& plugins) const
394 {
395  const std::size_t size = plugins.size();
396 
397  for(std::size_t i = 0; i < size; ++i)
398  if(!isLoaded(plugins[i]))
399  return false; // there is a missing plugin!
400 
401  return true;
402 }
403 
405 {
406  add(new PluginInfo(plugin));
407 }
408 
410 {
411  //try
412  //{
413  // if(!isLoaded(plugin->m_requiredPlugins))
414  // throw Exception("Missing requirement");
415 
416  m_unloadedPlugins.push_back(plugin);
417  //}
418  //catch(Exception&)
419  //{
420  // m_brokenPlugins.push_back(plugin);
421  //}
422 }
423 
424 void te::plugin::PluginManager::remove(const std::string& plugin)
425 {
426  PluginInfo info = getPlugin(plugin);
427 
428  if(isLoaded(plugin))
429  {
430  AbstractPlugin* plg = detach(plugin);
431  plg->shutdown();
432  delete plg;
433 
434  return;
435  }
436 
437  if(isUnloadedPlugin(plugin))
438  {
439  removeFromUnloadedList(info);
440  return;
441  }
442 
443  removeFromBrokenList(info);
444 }
445 
446 std::vector<std::string> te::plugin::PluginManager::getDependents(const std::string& pluginName) const
447 {
448  std::vector<std::string> dependents;
449 
450  const std::size_t nplugins = m_plugins.size();
451 
452  for(std::size_t i = 0; i < nplugins; ++i)
453  {
454  if(pluginName == m_plugins[i]->getInfo().m_name)
455  continue;
456 
457  const std::vector<std::string>& requiredPlugins = m_plugins[i]->getInfo().m_requiredPlugins;
458 
459  const std::size_t size = requiredPlugins.size();
460 
461  for(std::size_t j = 0; j < size; ++j)
462  {
463 // is the checked plugin a required plugin?
464  if(pluginName == requiredPlugins[j])
465  {
466  dependents.push_back(m_plugins[i]->getInfo().m_name); // it->first contains the name of the plugin that requires pluginName!
467  break;
468  }
469  }
470  }
471 
472  return dependents;
473 }
474 
475 bool te::plugin::PluginManager::hasDependents(const std::string& pluginName) const
476 {
477  return getDependents(pluginName).empty() ? false : true;
478 }
479 
481 {
482 // find plugin
483  std::map<std::string, AbstractPlugin*>::iterator it = m_pluginsMap.find(name);
484 
485  if(it == m_pluginsMap.end())
486  throw Exception((boost::format(TE_TR("Could not find the given plugin (%1%) in order to detach it from PluginManager!")) % name).str());
487 
488  AbstractPlugin* p = it->second;
489 
490  if(p == 0)
491  throw Exception((boost::format(TE_TR("Could not detach a NULL plugin (%1%) from PluginManager!")) % name).str());
492 
493 // check if it doesn't have dependents plugins
494  if(hasDependents(name))
495  moveDependentsToBrokenList(name);
496 // throw Exception((boost::format(TE_TR("There are some plugins that depends on %1%!")) % name).str());
497 
498 // see if we must destroy the plugin category index: in the case the detached plugin being the only plugin in its category
499  removeFromCategory(p, p->getInfo().m_category);
500 
501 // remove plugin from manager
502  std::vector<AbstractPlugin*>::iterator itv = std::find(m_plugins.begin(), m_plugins.end(), p);
503 
504  if(itv == m_plugins.end())
505  throw Exception(TE_TR("PluginManager has lost the synchronization between its internal indexes!"));
506 
507  m_plugins.erase(itv);
508 
509  m_pluginsMap.erase(name);
510 
511 // finally... just return the plugin pointer and loose its ownership
512  return p;
513 }
514 
515 void te::plugin::PluginManager::getCategories(std::vector<std::string>& categories) const
516 {
517  std::map<std::string, std::vector<AbstractPlugin*> >::const_iterator it = m_pluginCategoryMap.begin();
518 
519  while(it != m_pluginCategoryMap.end())
520  {
521  categories.push_back(it->first);
522 
523  ++it;
524  }
525 }
526 
527 void te::plugin::PluginManager::addCategory(const std::string& name)
528 {
529  std::map<std::string, std::vector<AbstractPlugin*> >::iterator it = m_pluginCategoryMap.find(name);
530 
531  if(it == m_pluginCategoryMap.end())
532  {
533  std::vector<AbstractPlugin*> vec;
534  m_pluginCategoryMap.insert(std::map<std::string, std::vector<AbstractPlugin*> >::value_type(name, vec));
535  }
536 }
537 
538 void te::plugin::PluginManager::sort(boost::ptr_vector<PluginInfo>& plugins) const
539 {
540 // let's create an auxiliary index to make a topological sort on the plugin list
541  std::map<std::string, std::size_t> newPluginsMap;
542 
543  const std::size_t nplugins = plugins.size();
544 
545  for(std::size_t i = 0; i < nplugins; ++i)
546  newPluginsMap.insert(std::make_pair(plugins[i].m_name, i));
547 
548 // let's cache the iterator to the end of the map
549  std::map<std::string, std::size_t>::const_iterator itend = newPluginsMap.end();
550 
551 // let's make a graph with the plugins dependency
552  typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> Graph;
553  typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
554 
555  Graph dgraph; // The dependency graph must be a DAG - when we make a topological sort this will be assured.
556 
557  for(std::size_t i = 0; i < nplugins; ++i) // add all vertex, maybe there aren't dependencies!
558  boost::add_vertex(dgraph);
559 
560  for(std::size_t i = 0; i < nplugins; ++i)
561  {
562  const std::vector<std::string>& requiredPlugins = plugins[i].m_requiredPlugins;
563 
564  const std::size_t nrequiredplugins = requiredPlugins.size();
565 
566  for(std::size_t j = 0; j < nrequiredplugins; ++j)
567  {
568  std::map<std::string, std::size_t>::const_iterator it = newPluginsMap.find(requiredPlugins[j]);
569 
570  if(it != itend)
571  {
572 // if plugin A (it->second) is required for plugin B (i) then there must be a directed edge from A to B (A must come first then B!)
573  boost::add_edge(it->second, i, dgraph);
574  }
575  }
576  }
577 
578 // now let's make a topological sort in order to be possible to traverse an load the plugins in the right order
579  std::vector<Vertex> toposortResult;
580 
581  boost::topological_sort(dgraph, std::back_inserter(toposortResult));
582 
583 // now let's load the plugins traversing the output result from topological sort in reverse-order (!!!topo sort output is not cool!!!)
584  boost::ptr_vector<PluginInfo> pluginsTemp;
585 
586  for(std::vector<Vertex>::reverse_iterator it = toposortResult.rbegin(); it != toposortResult.rend(); ++it)
587  pluginsTemp.push_back(new PluginInfo(plugins[*it]));
588 
589  plugins = pluginsTemp;
590 }
591 
592 void te::plugin::PluginManager::removeFromCategory(AbstractPlugin* plugin, const std::string& category)
593 {
594  std::map<std::string, std::vector<AbstractPlugin*> >::iterator it = m_pluginCategoryMap.find(category);
595 
596  if(it == m_pluginCategoryMap.end())
597  return;
598 
599  std::vector<AbstractPlugin*>& plugins = it->second;
600 
601  const std::size_t size = plugins.size();
602 
603  for(std::size_t i = 0; i < size; ++i)
604  {
605  if(plugin == plugins[i])
606  {
607  plugins.erase(plugins.begin() + i);
608 
609  if(plugins.empty())
610  m_pluginCategoryMap.erase(it);
611 
612  return;
613  }
614  }
615 }
616 
618 {
619  removeFromUnloadedList(pInfo);
620  removeFromBrokenList(pInfo);
621 
622 // add it to the end of the broken list
623  m_brokenPlugins.push_back(new PluginInfo(pInfo));
624 }
625 
627 {
628  for(boost::ptr_vector<PluginInfo>::iterator it = m_brokenPlugins.begin(); it != m_brokenPlugins.end(); ++it)
629  {
630  if(pInfo.m_name == it->m_name)
631  {
632  m_brokenPlugins.erase(it);
633  break;
634  }
635  }
636 }
637 
639 {
640  for(boost::ptr_vector<PluginInfo>::iterator it = m_unloadedPlugins.begin(); it != m_unloadedPlugins.end(); ++it)
641  {
642  if(pInfo.m_name == it->m_name)
643  {
644  m_unloadedPlugins.erase(it);
645  break;
646  }
647  }
648 }
649 
650 void te::plugin::PluginManager::moveDependentsToBrokenList(const std::string& plugin, const bool& unloadPlugin)
651 {
652  if(isBrokenPlugin(plugin))
653  return;
654 
655  std::vector<std::string> deps = getDependents(plugin);
656 
657  if(!deps.empty())
658  {
659  std::vector<std::string>::iterator it;
660 
661  for(it=deps.begin(); it!=deps.end(); ++it)
662  moveDependentsToBrokenList(*it, true);
663  }
664 
665  te::plugin::PluginInfo info(getPlugin(plugin));
666 
667  if(unloadPlugin)
668  {
669  if(isLoaded(info.m_name))
670  unload(info.m_name);
671 
672  moveToBrokenList(info);
673  }
674 }
675 
676 void te::plugin::PluginManager::updateDependents(const std::string& plugin)
677 {
678  boost::ptr_vector<PluginInfo> deps = getBrokenPlugins();
679 
680  if(!deps.empty())
681  {
682  boost::ptr_vector<PluginInfo>::iterator it;
683  std::vector<PluginInfo*> toUpdate;
684 
685  for(it=deps.begin(); it!=deps.end(); ++it)
686  if(isLoaded((*it).m_requiredPlugins))
687  toUpdate.push_back(new PluginInfo(*it));
688 
689  std::vector<PluginInfo*>::iterator it2;
690  for(it2=toUpdate.begin(); it2 != toUpdate.end(); ++it2)
691  {
692  removeFromBrokenList(*(*it2));
693  m_unloadedPlugins.push_back(*it2);
694  }
695  }
696 }
697 
699 {
700 }
701 
703 {
704  te::common::FreeContents(m_finders);
705  te::common::FreeContents(m_plugins);
706 }
707 
This is the abstract factory for plugin engines.
void moveDependentsToBrokenList(const std::string &plugin, const bool &unloadPlugin=false)
void moveToBrokenList(const PluginInfo &pInfo)
std::string m_name
The plugin name: an internal value used to identify the plugin in the system. Must be a unique value...
Definition: PluginInfo.h:66
virtual const PluginInfo & getInfo() const =0
It return the information associated to the plugin.
void shutdownAll()
It try to shutdown all plugins.
std::vector< std::string > m_requiredPlugins
The list of required plugins in order to lunch the plugin.
Definition: PluginInfo.h:78
void remove(const std::string &plugin)
PluginManager()
It creates a new plugin.
void setUnloadedPlugins(boost::ptr_vector< te::plugin::PluginInfo > unloadedPlugins)
An abstract class for TerraLib Plugins.
A plugin finder that search for plugins in some special directories defined by compile time macros...
Definition: DefaultFinder.h:48
void addCategory(const std::string &name)
Add a new category type.
virtual bool isStarted() const =0
It tells if the plugin was started or not.
void removeFromCategory(AbstractPlugin *plugin, const std::string &category)
It removes the given plugin from the category and then updates the internal category index...
void unloadAll()
It try to unload all plugins.
bool hasDependents(const std::string &pluginName) const
If there is a plugin that depends on the informed plugin it returns true, otherwise, if no plugin depends on it, return false.
void add(const PluginInfo &plugin)
Adds plug-in to unload list.
boost::ptr_vector< PluginInfo > m_brokenPlugins
The list of plugins that could not be loaded.
std::vector< AbstractPlugin * > m_plugins
The list of managed plugins: this will be need to unload accordinly the plugins!
~PluginManager()
Singleton destructor.
void updateDependents(const std::string &plugin)
The AbstractFinder class allows applications to extend how PluginManager can search for plugins...
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
void load(boost::ptr_vector< PluginInfo > &plugins, const bool start=true)
It tries to load all informed plugins.
void removeFromUnloadedList(const PluginInfo &pInfo)
boost::ptr_vector< PluginInfo > m_unloadedPlugins
The list of plugins that are not loaded.
An abstract class for TerraLib Plugins.
std::string m_engine
The type of plugin execution engine: C++, JAVA.
Definition: PluginInfo.h:71
std::size_t getNumRegModules() const
It returns the number of registered modules.
Definition: TerraLib.cpp:128
static TerraLib & getInstance()
It returns a reference to the singleton instance.
void removeFromBrokenList(const PluginInfo &pInfo)
An abstract class for plugin engines.
const boost::ptr_vector< PluginInfo > & getUnloadedPlugins() const
It returns the list of plugins that are not loaded.
virtual void shutdown()=0
This method will be called by TerraLib to shutdown plugin's functionality.
void clear()
Unload all plugins and them clear the internal list.
void sort(boost::ptr_vector< PluginInfo > &plugins) const
It sorts the plugins according to their dependency.
void getCategories(std::vector< std::string > &categories) const
Get plugins category types.
std::vector< std::string > getPlugins() const
It returns the list of plugins managed by PluginManager.
AbstractPlugin * detach(const std::string &pluginName)
It detaches the given plugin from the list of loaded plugins.
bool isUnloadedPlugin(const std::string &pluginName) const
It returns true if the plugin is in the not-loaded list of plugins.
static AbstractPluginEngine * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
void initialize()
It initializes the TerraLib Platform.
Definition: TerraLib.cpp:33
A plugin finder that search for plugins in some special directories defined by compile time macros...
const boost::ptr_vector< PluginInfo > & getBrokenPlugins() const
It returns the list of plugins that could not be loaded.
std::size_t getNumPlugins() const
It returns the number of plugins kept in the manager.
const PluginInfo & getPlugin(const std::string &name) const
It returns the plugin identified by the given name.
void loadAll(const bool start=true)
It loads all the plugins in the not-loaded list or searchs for installed plugin with installed finder...
A singleton for managing plugins.
bool isBrokenPlugin(const std::string &pluginName) const
It returns true if the plugin is in the broken list of plugins.
bool isLoaded(const std::string &pname) const
It returns true if the plugin is loaded otherwise returns false.
void setBrokenPlugins(boost::ptr_vector< te::plugin::PluginInfo > brokenPlugins)
std::vector< std::string > getDependents(const std::string &pluginName) const
It searches for all plugins that depends on the given plugin.
The basic information about a plugin.
Definition: PluginInfo.h:61
The basic information about a plugin.
void getPlugins(boost::ptr_vector< PluginInfo > &plugins)
This method searches for installed plugins and output the plugins information in the PluginInfo vecto...
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
std::string m_category
The plugin category.
Definition: PluginInfo.h:75
void unload(const std::string &name)
It tries to unload a given plugin.