27 #include "../common/STLUtils.h" 
   28 #include "../common/TerraLib.h" 
   29 #include "../common/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);
 
   77     if(it != m_pluginsMap.end())
 
   78       return it->second->getInfo();
 
   82   for(boost::ptr_vector<PluginInfo>::const_iterator it = m_unloadedPlugins.begin(); it != m_unloadedPlugins.end(); ++it)
 
   83     if(it->m_name == name)
 
   87   for(boost::ptr_vector<PluginInfo>::const_iterator it = m_brokenPlugins.begin(); it != m_brokenPlugins.end(); ++it)
 
   88     if(it->m_name == name)
 
   91   throw Exception((boost::format(
"Could not find plugin %1%") % name).str());
 
   96   return m_unloadedPlugins;
 
  101   m_unloadedPlugins = unloadedPlugins;
 
  106   return m_brokenPlugins;
 
  111   m_brokenPlugins = brokenPlugins;
 
  116   for(boost::ptr_vector<PluginInfo>::const_iterator it = m_brokenPlugins.begin(); it != m_brokenPlugins.end(); ++it)
 
  117     if(it->m_name == pluginName)
 
  125   for(boost::ptr_vector<PluginInfo>::const_iterator it = m_unloadedPlugins.begin(); it != m_unloadedPlugins.end(); ++it)
 
  126     if(it->m_name == pluginName)
 
  134   return m_pluginsMap.find(pname) != m_pluginsMap.end();
 
  142   boost::ptr_vector<PluginInfo> plugins;
 
  145   if(m_unloadedPlugins.empty())
 
  148     if(m_finders.empty())
 
  155       const std::size_t nfinders = m_finders.size();
 
  157       for(std::size_t i = 0; i < nfinders; ++i)
 
  158         m_finders[i]->getPlugins(plugins);
 
  164     plugins = m_unloadedPlugins;
 
  167   load(plugins, start);
 
  173   std::vector<AbstractPlugin*>::reverse_iterator it = m_plugins.rbegin();
 
  175   while(it != m_plugins.rend())
 
  177     std::auto_ptr<PluginInfo> pinfo(
new PluginInfo((*it)->getInfo()));
 
  179     m_unloadedPlugins.push_back(pinfo.release());
 
  180     it = m_plugins.rbegin();  
 
  184   assert(m_pluginCategoryMap.empty());
 
  185   assert(m_plugins.empty());
 
  186   assert(m_pluginsMap.empty());
 
  192   m_unloadedPlugins.clear();
 
  193   m_brokenPlugins.clear();
 
  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;
 
  221   if(hasException || !m_brokenPlugins.empty())
 
  222     throw Exception(
TE_TR(
"\n\nPlugins not loaded:" ) + exceptionPlugins);
 
  227   if(isLoaded(pInfo.
m_name))
 
  228     throw Exception((boost::format(
"Plugin %1% is already loaded") % pInfo.
m_name).str());
 
  233     moveToBrokenList(pInfo);
 
  234     throw Exception(
TE_TR(
"A required plugin is not loaded!"));
 
  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)
 
  259     moveToBrokenList(pInfo);
 
  260     Exception ee(e.what());
 
  265     moveToBrokenList(pInfo);
 
  277       for(std::size_t i = nmodules; i < nnmodules; ++i)
 
  285     std::string plg_name = plugin->getInfo().m_name;
 
  287     m_pluginCategoryMap[pInfo.
m_category].push_back(plugin.get());
 
  288     m_plugins.push_back(plugin.get());
 
  289     m_pluginsMap[plg_name] = plugin.release();
 
  292     removeFromBrokenList(pInfo);
 
  293     removeFromUnloadedList(pInfo);
 
  295     updateDependents(plg_name);
 
  297   catch(
const std::exception& e)
 
  299     moveToBrokenList(pInfo);
 
  300     Exception ee(e.what());
 
  305     moveToBrokenList(pInfo);
 
  312   load(getPlugin(pluginName));
 
  317   std::map<std::string, AbstractPlugin*>::iterator it = m_pluginsMap.find(name);
 
  319   if(it == m_pluginsMap.end())
 
  320     throw Exception((boost::format(
"Plugin %1% is not loaded!") % name).str());
 
  325     throw Exception((boost::format(
"Plugin %1% is NULL!") % name).str());
 
  336   if(hasDependents(pluginName))
 
  337     moveDependentsToBrokenList(pluginName);
 
  347   if(engine.get() == 0)
 
  348     throw Exception((boost::format(
"Could not determine plugin %1% language type!") % pluginName).str());
 
  352   engine->unload(plugin); 
 
  354   m_unloadedPlugins.push_back(pInfo);
 
  357   removeFromCategory(plugin, pluginCategory);
 
  360     std::vector<AbstractPlugin*>::iterator it = std::find(m_plugins.begin(), m_plugins.end(), plugin);
 
  362     if(it != m_plugins.end())
 
  367     std::map<std::string, AbstractPlugin*>::iterator it = m_pluginsMap.find(pluginName);
 
  369     if(it != m_pluginsMap.end())
 
  370       m_pluginsMap.erase(it);
 
  377   std::vector<AbstractPlugin*>::reverse_iterator it = m_plugins.rbegin();
 
  379   while(it != m_plugins.rend())
 
  381     if((*it)->isStarted())
 
  390   return m_pluginsMap.size() + m_unloadedPlugins.size() + m_brokenPlugins.size();
 
  395   const std::size_t size = plugins.size();
 
  397   for(std::size_t i = 0; i < size; ++i)
 
  398     if(!isLoaded(plugins[i]))
 
  416     m_unloadedPlugins.push_back(plugin);
 
  437   if(isUnloadedPlugin(plugin))
 
  439     removeFromUnloadedList(info);
 
  443   removeFromBrokenList(info);
 
  448   std::vector<std::string> dependents;
 
  450   const std::size_t nplugins = m_plugins.size();
 
  452   for(std::size_t i = 0; i < nplugins; ++i)
 
  454     if(pluginName == m_plugins[i]->getInfo().m_name)
 
  457     const std::vector<std::string>& requiredPlugins = m_plugins[i]->getInfo().m_requiredPlugins;
 
  459     const std::size_t size = requiredPlugins.size();
 
  461     for(std::size_t j = 0; j < size; ++j)
 
  464       if(pluginName == requiredPlugins[j])
 
  466         dependents.push_back(m_plugins[i]->getInfo().m_name);  
 
  477   return getDependents(pluginName).empty() ? 
false : 
true;
 
  483   std::map<std::string, AbstractPlugin*>::iterator it = m_pluginsMap.find(name);
 
  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());
 
  491     throw Exception((boost::format(
TE_TR(
"Could not detach a NULL plugin (%1%) from PluginManager!")) % name).str());
 
  494   if(hasDependents(name))
 
  495     moveDependentsToBrokenList(name);
 
  502   std::vector<AbstractPlugin*>::iterator itv = std::find(m_plugins.begin(), m_plugins.end(), p);
 
  504   if(itv == m_plugins.end())
 
  505     throw Exception(
TE_TR(
"PluginManager has lost the synchronization between its internal indexes!"));
 
  507   m_plugins.erase(itv);
 
  509   m_pluginsMap.erase(name);
 
  517   std::map<std::string, std::vector<AbstractPlugin*> >::const_iterator it = m_pluginCategoryMap.begin();
 
  519   while(it != m_pluginCategoryMap.end())
 
  521     categories.push_back(it->first);
 
  529   std::map<std::string, std::vector<AbstractPlugin*> >::iterator it = m_pluginCategoryMap.find(name);
 
  531   if(it == m_pluginCategoryMap.end())
 
  533     std::vector<AbstractPlugin*> vec;
 
  534     m_pluginCategoryMap.insert(std::map<std::string, std::vector<AbstractPlugin*> >::value_type(name, vec));
 
  541   std::map<std::string, std::size_t> newPluginsMap;
 
  543   const std::size_t nplugins = plugins.size();
 
  545   for(std::size_t i = 0; i < nplugins; ++i)
 
  546     newPluginsMap.insert(std::make_pair(plugins[i].m_name, i));
 
  549   std::map<std::string, std::size_t>::const_iterator itend = newPluginsMap.end();
 
  552   typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> Graph;
 
  553   typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
 
  557   for(std::size_t i = 0; i < nplugins; ++i) 
 
  558     boost::add_vertex(dgraph);
 
  560   for(std::size_t i = 0; i < nplugins; ++i)
 
  562     const std::vector<std::string>& requiredPlugins = plugins[i].m_requiredPlugins;
 
  564     const std::size_t nrequiredplugins = requiredPlugins.size();
 
  566     for(std::size_t j = 0; j < nrequiredplugins; ++j)
 
  568       std::map<std::string, std::size_t>::const_iterator it = newPluginsMap.find(requiredPlugins[j]);
 
  573         boost::add_edge(it->second, i, dgraph);
 
  579   std::vector<Vertex> toposortResult;
 
  581   boost::topological_sort(dgraph, std::back_inserter(toposortResult));
 
  584   boost::ptr_vector<PluginInfo> pluginsTemp;
 
  586   for(std::vector<Vertex>::reverse_iterator it = toposortResult.rbegin(); it != toposortResult.rend(); ++it)
 
  587     pluginsTemp.push_back(
new PluginInfo(plugins[*it]));
 
  589   plugins = pluginsTemp;
 
  594   std::map<std::string, std::vector<AbstractPlugin*> >::iterator it = m_pluginCategoryMap.find(category);
 
  596   if(it == m_pluginCategoryMap.end())
 
  599   std::vector<AbstractPlugin*>& plugins = it->second;
 
  601   const std::size_t size = plugins.size();
 
  603   for(std::size_t i = 0; i < size; ++i)
 
  605     if(plugin == plugins[i])
 
  607       plugins.erase(plugins.begin() + i);
 
  610         m_pluginCategoryMap.erase(it);
 
  619   removeFromUnloadedList(pInfo);
 
  620   removeFromBrokenList(pInfo);
 
  623   m_brokenPlugins.push_back(
new PluginInfo(pInfo));
 
  628   for(boost::ptr_vector<PluginInfo>::iterator it = m_brokenPlugins.begin(); it != m_brokenPlugins.end(); ++it)
 
  630     if(pInfo.
m_name == it->m_name)
 
  632       m_brokenPlugins.erase(it);
 
  640   for(boost::ptr_vector<PluginInfo>::iterator it = m_unloadedPlugins.begin(); it != m_unloadedPlugins.end(); ++it)
 
  642     if(pInfo.
m_name == it->m_name)
 
  644       m_unloadedPlugins.erase(it);
 
  652   if(isBrokenPlugin(plugin))
 
  655   std::vector<std::string> deps = getDependents(plugin);
 
  659     std::vector<std::string>::iterator it;
 
  661     for(it=deps.begin(); it!=deps.end(); ++it)
 
  662       moveDependentsToBrokenList(*it, 
true);
 
  672     moveToBrokenList(info);
 
  678   boost::ptr_vector<PluginInfo> deps = getBrokenPlugins();
 
  682     boost::ptr_vector<PluginInfo>::iterator it;
 
  683     std::vector<PluginInfo*> toUpdate;
 
  685     for(it=deps.begin(); it!=deps.end(); ++it)
 
  686       if(isLoaded((*it).m_requiredPlugins))
 
  689     std::vector<PluginInfo*>::iterator it2;
 
  690     for(it2=toUpdate.begin(); it2 != toUpdate.end(); ++it2)
 
  692       removeFromBrokenList(*(*it2));
 
  693       m_unloadedPlugins.push_back(*it2);
 
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...
 
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. 
 
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. 
 
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. 
 
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. 
 
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)
 
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. 
 
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. 
 
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...
 
std::string m_category
The plugin category. 
 
void unload(const std::string &name)
It tries to unload a given plugin.