27 #include "../common/STLUtils.h" 28 #include "../common/TerraLib.h" 29 #include "../core/translator/Translator.h" 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> 51 std::vector<std::string>
54 std::vector<std::string> 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);
62 plugins.push_back(it->m_name);
66 plugins.push_back(it->m_name);
75 std::map<std::string, AbstractPlugin*>::const_iterator it =
m_pluginsMap.find(name);
78 return it->second->getInfo();
83 if(it->m_name == name)
88 if(it->m_name == name)
91 throw Exception((boost::format(
"Could not find plugin %1%") % name).str());
117 if(it->m_name == pluginName)
126 if(it->m_name == pluginName)
142 boost::ptr_vector<PluginInfo> plugins;
155 const std::size_t nfinders =
m_finders.size();
157 for(std::size_t i = 0; i < nfinders; ++i)
167 load(plugins, start);
173 std::vector<AbstractPlugin*>::reverse_iterator it =
m_plugins.rbegin();
177 std::auto_ptr<PluginInfo> pinfo(
new PluginInfo((*it)->getInfo()));
200 bool hasException =
false;
202 const std::size_t nplugins = plugins.size();
204 std::string exceptionPlugins;
206 for(std::size_t i = 0; i < nplugins; ++i)
217 exceptionPlugins +=
"\n" + pInfo.
m_name;
222 throw Exception(
TE_TR(
"\n\nPlugins not loaded:" ) + exceptionPlugins);
228 throw Exception((boost::format(
"Plugin %1% is already loaded") % pInfo.
m_name).str());
237 std::auto_ptr<AbstractPlugin> plugin;
249 if(engine.get() == 0)
250 throw Exception((boost::format(
"Could not determine plugin's language type for %1%!") % pInfo.
m_name).str());
252 plugin.reset(engine->load(pInfo));
254 if(plugin.get() == 0)
255 throw Exception((boost::format(
"Could not load plugin %1%!") % pInfo.
m_name).str());
257 catch(
const std::exception& e)
277 for(std::size_t i = nmodules; i < nnmodules; ++i)
285 std::string plg_name = plugin->getInfo().m_name;
297 catch(
const std::exception& e)
318 std::map<std::string, AbstractPlugin*>::iterator it =
m_pluginsMap.find(name);
321 throw Exception((boost::format(
"Plugin %1% is not loaded!") % name).str());
326 throw Exception((boost::format(
"Plugin %1% is NULL!") % name).str());
348 if(engine.get() == 0)
349 throw Exception((boost::format(
"Could not determine plugin %1% language type!") % pluginName).str());
353 engine->unload(plugin);
361 std::vector<AbstractPlugin*>::iterator it = std::find(
m_plugins.begin(),
m_plugins.end(), plugin);
368 std::map<std::string, AbstractPlugin*>::iterator it =
m_pluginsMap.find(pluginName);
378 std::vector<AbstractPlugin*>::reverse_iterator it =
m_plugins.rbegin();
382 if((*it)->isStarted())
396 const std::size_t size = plugins.size();
398 for(std::size_t i = 0; i < size; ++i)
449 std::vector<std::string> dependents;
451 const std::size_t nplugins =
m_plugins.size();
453 for(std::size_t i = 0; i < nplugins; ++i)
455 if(pluginName ==
m_plugins[i]->getInfo().m_name)
458 const std::vector<std::string>& requiredPlugins =
m_plugins[i]->getInfo().m_requiredPlugins;
460 const std::size_t size = requiredPlugins.size();
462 for(std::size_t j = 0; j < size; ++j)
465 if(pluginName == requiredPlugins[j])
467 dependents.push_back(
m_plugins[i]->getInfo().m_name);
484 std::map<std::string, AbstractPlugin*>::iterator it =
m_pluginsMap.find(name);
487 throw Exception((boost::format(
TE_TR(
"Could not find the given plugin (%1%) in order to detach it from PluginManager!")) % name).str());
492 throw Exception((boost::format(
TE_TR(
"Could not detach a NULL plugin (%1%) from PluginManager!")) % name).str());
503 std::vector<AbstractPlugin*>::iterator itv = std::find(
m_plugins.begin(),
m_plugins.end(),
p);
506 throw Exception(
TE_TR(
"PluginManager has lost the synchronization between its internal indexes!"));
518 std::map<std::string, std::vector<AbstractPlugin*> >::const_iterator it =
m_pluginCategoryMap.begin();
522 categories.push_back(it->first);
530 std::map<std::string, std::vector<AbstractPlugin*> >::iterator it =
m_pluginCategoryMap.find(name);
534 std::vector<AbstractPlugin*> vec;
535 m_pluginCategoryMap.insert(std::map<std::string, std::vector<AbstractPlugin*> >::value_type(name, vec));
542 std::map<std::string, std::size_t> newPluginsMap;
544 const std::size_t nplugins = plugins.size();
546 for(std::size_t i = 0; i < nplugins; ++i)
547 newPluginsMap.insert(std::make_pair(plugins[i].m_name, i));
550 std::map<std::string, std::size_t>::const_iterator itend = newPluginsMap.end();
553 typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> Graph;
554 typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
558 for(std::size_t i = 0; i < nplugins; ++i)
559 boost::add_vertex(dgraph);
561 for(std::size_t i = 0; i < nplugins; ++i)
563 const std::vector<std::string>& requiredPlugins = plugins[i].m_requiredPlugins;
565 const std::size_t nrequiredplugins = requiredPlugins.size();
567 for(std::size_t j = 0; j < nrequiredplugins; ++j)
569 std::map<std::string, std::size_t>::const_iterator it = newPluginsMap.find(requiredPlugins[j]);
574 boost::add_edge(it->second, i, dgraph);
580 std::vector<Vertex> toposortResult;
582 boost::topological_sort(dgraph, std::back_inserter(toposortResult));
585 boost::ptr_vector<PluginInfo> pluginsTemp;
587 for(std::vector<Vertex>::reverse_iterator it = toposortResult.rbegin(); it != toposortResult.rend(); ++it)
588 pluginsTemp.push_back(
new PluginInfo(plugins[*it]));
590 plugins = pluginsTemp;
595 std::map<std::string, std::vector<AbstractPlugin*> >::iterator it =
m_pluginCategoryMap.find(category);
600 std::vector<AbstractPlugin*>& plugins = it->second;
602 const std::size_t size = plugins.size();
604 for(std::size_t i = 0; i < size; ++i)
606 if(plugin == plugins[i])
608 plugins.erase(plugins.begin() + i);
631 if(pInfo.
m_name == it->m_name)
643 if(pInfo.
m_name == it->m_name)
660 std::vector<std::string>::iterator it;
662 for(it=deps.begin(); it!=deps.end(); ++it)
683 boost::ptr_vector<PluginInfo>::iterator it;
684 std::vector<PluginInfo*> toUpdate;
686 for(it=deps.begin(); it!=deps.end(); ++it)
687 if(
isLoaded((*it).m_requiredPlugins))
690 std::vector<PluginInfo*>::iterator it2;
691 for(it2=toUpdate.begin(); it2 != toUpdate.end(); ++it2)
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...
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.
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...
void addCategory(const std::string &name)
Add a new category type.
Base exception class for plugin module.
virtual const PluginInfo & getInfo() const =0
It return the information associated to the plugin.
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)
#define TE_TR(message)
It marks a string in order to get translated.
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.
std::string m_engine
The type of plugin execution engine: C++, JAVA.
std::size_t getNumRegModules() const
It returns the number of registered modules.
static TerraLib & getInstance()
It returns a reference to the singleton instance.
void removeFromBrokenList(const PluginInfo &pInfo)
std::map< std::string, AbstractPlugin * > m_pluginsMap
A map from (plugin's name) to (plugin instance).
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.
virtual bool isStarted() const =0
It tells if the plugin was started or not.
AbstractPlugin * detach(const std::string &pluginName)
It detaches the given plugin from the list of loaded plugins.
std::vector< AbstractFinder * > m_finders
The list of plugin finders.
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.
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...
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.
std::map< std::string, std::vector< AbstractPlugin * > > m_pluginCategoryMap
A map from (plugin category) to (plugins in category)
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...
std::string m_category
The plugin category.
void unload(const std::string &name)
It tries to unload a given plugin.