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