From 170fbfa08d5a55b6ace0dabf838bd6ff2301f4dd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 6 Aug 2009 14:53:06 +0200 Subject: move lib/MiddleWare/PluginManager.* -> src/Daemon/PluginManager.* This reduces code size by 14k. Signed-off-by: Denys Vlasenko --- src/Daemon/Makefile.am | 1 + src/Daemon/PluginManager.cpp | 287 +++++++++++++++++++++++++++++++++++++++++++ src/Daemon/PluginManager.h | 156 +++++++++++++++++++++++ 3 files changed, 444 insertions(+) create mode 100644 src/Daemon/PluginManager.cpp create mode 100644 src/Daemon/PluginManager.h (limited to 'src') diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am index 194d0137..41d60a73 100644 --- a/src/Daemon/Makefile.am +++ b/src/Daemon/Makefile.am @@ -1,6 +1,7 @@ sbin_PROGRAMS = abrt abrt_SOURCES = \ + PluginManager.cpp PluginManager.h \ MiddleWare.cpp MiddleWare.h \ CrashWatcher.cpp CrashWatcher.h \ Daemon.cpp \ diff --git a/src/Daemon/PluginManager.cpp b/src/Daemon/PluginManager.cpp new file mode 100644 index 00000000..7224c4e9 --- /dev/null +++ b/src/Daemon/PluginManager.cpp @@ -0,0 +1,287 @@ +/* + PluginManager.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) + Copyright (C) 2009 RedHat inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include "PluginManager.h" +#include "ABRTException.h" +#include "CommLayerInner.h" +#include +#include +#include + +/** + * Text representation of plugin types. + */ +static const char* const plugin_type_str_t[] = { + "Analyzer", + "Action", + "Reporter", + "Database" +}; + + +CPluginManager::CPluginManager( + const std::string& pPluginsConfDir, + const std::string& pPluginsLibDir) +: + m_sPluginsConfDir(pPluginsConfDir), + m_sPluginsLibDir(pPluginsLibDir) +{} + +CPluginManager::~CPluginManager() +{} + +void CPluginManager::LoadPlugins() +{ + DIR *dir = opendir(m_sPluginsLibDir.c_str()); + struct dirent *dent = NULL; + if (dir != NULL) + { + while ((dent = readdir(dir)) != NULL) + { + // FIXME: need to handle DT_UNKNOWN too + if (dent->d_type == DT_REG) + { + std::string name = dent->d_name; + std::string extension = name.substr(name.length() - sizeof(PLUGINS_LIB_EXTENSION) + 1); + if (extension == PLUGINS_LIB_EXTENSION) + { + name.erase(0, sizeof(PLUGINS_LIB_PREFIX) - 1); + name.erase(name.length() - sizeof(PLUGINS_LIB_EXTENSION)); + LoadPlugin(name); + } + } + } + closedir(dir); + } +} + +void CPluginManager::UnLoadPlugins() +{ + map_abrt_plugins_t::iterator it_p; + while ((it_p = m_mapABRTPlugins.begin()) != m_mapABRTPlugins.end()) + { + std::string pluginName = it_p->first; + UnLoadPlugin(pluginName); + } +} + +void CPluginManager::LoadPlugin(const std::string& pName) +{ + if (m_mapABRTPlugins.find(pName) == m_mapABRTPlugins.end()) + { + CABRTPlugin* abrtPlugin = NULL; + try + { + std::string libPath = m_sPluginsLibDir + "/" + PLUGINS_LIB_PREFIX + pName + "." + PLUGINS_LIB_EXTENSION; + abrtPlugin = new CABRTPlugin(libPath); + if (abrtPlugin->GetMagicNumber() != PLUGINS_MAGIC_NUMBER || + (abrtPlugin->GetType() < ANALYZER && abrtPlugin->GetType() > DATABASE)) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::LoadPlugin(): non-compatible plugin"); + } + comm_layer_inner_debug("Plugin " + pName + " (" + abrtPlugin->GetVersion() + ") succesfully loaded."); + m_mapABRTPlugins[pName] = abrtPlugin; + } + catch (CABRTException& e) + { + if (abrtPlugin != NULL) + { + delete abrtPlugin; + } + comm_layer_inner_warning("CPluginManager::LoadPlugin(): " + e.what()); + comm_layer_inner_warning("Failed to load plugin " + pName); + } + } +} + +void CPluginManager::UnLoadPlugin(const std::string& pName) +{ + if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end()) + { + UnRegisterPlugin(pName); + delete m_mapABRTPlugins[pName]; + m_mapABRTPlugins.erase(pName); + comm_layer_inner_debug("Plugin " + pName + " sucessfully unloaded."); + } +} + +void CPluginManager::RegisterPlugin(const std::string& pName) +{ + if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end()) + { + if (m_mapPlugins.find(pName) == m_mapPlugins.end()) + { + std::string path = m_sPluginsConfDir + "/" + pName + "." + PLUGINS_CONF_EXTENSION; + CPlugin* plugin = m_mapABRTPlugins[pName]->PluginNew(); + try + { + plugin->Init(); + plugin->LoadSettings(path); + } + catch (std::string sError) + { + comm_layer_inner_warning("Can not initialize plugin " + pName + "(" + + std::string(plugin_type_str_t[m_mapABRTPlugins[pName]->GetType()]) + + ")"); + UnLoadPlugin(pName); + return; + } + m_mapPlugins[pName] = plugin; + comm_layer_inner_debug("Registered plugin " + pName + "(" + + std::string(plugin_type_str_t[m_mapABRTPlugins[pName]->GetType()]) + + ")"); + } + } +} + +void CPluginManager::UnRegisterPlugin(const std::string& pName) +{ + if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end()) + { + if (m_mapPlugins.find(pName) != m_mapPlugins.end()) + { + m_mapPlugins[pName]->DeInit(); + delete m_mapPlugins[pName]; + m_mapPlugins.erase(pName); + comm_layer_inner_debug("UnRegistred plugin " + pName + "(" + + std::string(plugin_type_str_t[m_mapABRTPlugins[pName]->GetType()]) + + ")"); + } + } +} + +CAnalyzer* CPluginManager::GetAnalyzer(const std::string& pName) +{ + if (m_mapPlugins.find(pName) == m_mapPlugins.end()) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAnalyzer():" + "Analyzer plugin: '"+pName+"' is not registered."); + } + if (m_mapABRTPlugins[pName]->GetType() != ANALYZER) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAnalyzer():" + "Plugin: '"+pName+"' is not analyzer plugin."); + } + return dynamic_cast(m_mapPlugins[pName]); +} + +CReporter* CPluginManager::GetReporter(const std::string& pName) +{ + if (m_mapPlugins.find(pName) == m_mapPlugins.end()) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetReporter():" + "Reporter plugin: '"+pName+"' is not registered."); + } + if (m_mapABRTPlugins[pName]->GetType() != REPORTER) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetReporter():" + "Plugin: '"+pName+"' is not reporter plugin."); + } + return dynamic_cast(m_mapPlugins[pName]); +} + +CAction* CPluginManager::GetAction(const std::string& pName) +{ + if (m_mapPlugins.find(pName) == m_mapPlugins.end()) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAction():" + "Action plugin: '"+pName+"' is not registered."); + } + if (m_mapABRTPlugins[pName]->GetType() != ACTION) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAction():" + "Plugin: '"+pName+"' is not action plugin."); + } + return dynamic_cast(m_mapPlugins[pName]); +} + +CDatabase* CPluginManager::GetDatabase(const std::string& pName) +{ + if (m_mapPlugins.find(pName) == m_mapPlugins.end()) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetDatabase():" + "Database plugin: '"+pName+"' is not registered."); + } + if (m_mapABRTPlugins[pName]->GetType() != DATABASE) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetDatabase():" + "Plugin: '"+pName+"' is not database plugin."); + } + return dynamic_cast(m_mapPlugins[pName]); +} + +plugin_type_t CPluginManager::GetPluginType(const std::string& pName) +{ + if (m_mapPlugins.find(pName) == m_mapPlugins.end()) + { + throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetPluginType():" + "Plugin: '"+pName+"' is not registered."); + } + return m_mapABRTPlugins[pName]->GetType(); +} + +vector_map_string_string_t CPluginManager::GetPluginsInfo() +{ + vector_map_string_string_t ret; + map_abrt_plugins_t::iterator it_abrt_plugin; + for (it_abrt_plugin = m_mapABRTPlugins.begin(); it_abrt_plugin != m_mapABRTPlugins.end(); it_abrt_plugin++) + { + map_string_string_t plugin_info; + + plugin_info["Enabled"] = (m_mapPlugins.find(it_abrt_plugin->second->GetName()) != m_mapPlugins.end()) ? + "yes" : "no"; + plugin_info["Type"] = plugin_type_str_t[it_abrt_plugin->second->GetType()]; + plugin_info["Name"] = it_abrt_plugin->second->GetName(); + plugin_info["Version"] = it_abrt_plugin->second->GetVersion(); + plugin_info["Description"] = it_abrt_plugin->second->GetDescription(); + plugin_info["Email"] = it_abrt_plugin->second->GetEmail(); + plugin_info["WWW"] = it_abrt_plugin->second->GetWWW(); + plugin_info["GTKBuilder"] = it_abrt_plugin->second->GetGTKBuilder(); + ret.push_back(plugin_info); + } + return ret; +} + +void CPluginManager::SetPluginSettings(const std::string& pName, + const map_plugin_settings_t& pSettings) +{ + if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end()) + { + if (m_mapPlugins.find(pName) != m_mapPlugins.end()) + { + m_mapPlugins[pName]->SetSettings(pSettings); + } + } +} + +map_plugin_settings_t CPluginManager::GetPluginSettings(const std::string& pName) +{ + map_plugin_settings_t ret; + if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end()) + { + if (m_mapPlugins.find(pName) != m_mapPlugins.end()) + { + ret = m_mapPlugins[pName]->GetSettings(); + } + } + return ret; +} diff --git a/src/Daemon/PluginManager.h b/src/Daemon/PluginManager.h new file mode 100644 index 00000000..53ec77c9 --- /dev/null +++ b/src/Daemon/PluginManager.h @@ -0,0 +1,156 @@ +/* + PluginManager.h - header file for plugin manager. it takes care about + (un)loading plugins + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) + Copyright (C) 2009 RedHat inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef PLUGINMANAGER_H_ +#define PLUGINMANAGER_H_ + +#include +#include +#include "ABRTPlugin.h" +#include "Plugin.h" +#include "Analyzer.h" +#include "Reporter.h" +#include "Database.h" +#include "Action.h" +#include "MiddleWareTypes.h" + +/** + * A class. It takes care of loading, registering and manipulating with + * plugins. When a plugin is loaded, its library is opened, but no plugin + * instance is created. It is possible after plugin registration. + */ +class CPluginManager +{ + private: + typedef std::map map_abrt_plugins_t; + typedef std::map map_plugins_t; + + /** + * Loaded plugins. A key is a plugin name. + */ + map_abrt_plugins_t m_mapABRTPlugins; + /** + * Registered plugins. A key is a plugin name. + */ + map_plugins_t m_mapPlugins; + /** + * Plugins configuration directory (e.g. /etc/abrt/plugins, ...). + */ + std::string m_sPluginsConfDir; + /** + * Plugins library directory (e.g. /usr/lib/abrt/plugins, ...). + */ + std::string m_sPluginsLibDir; + + public: + /** + * A constructor. + * @param pPluginsConfDir A plugins configuration directory. + * @param pPluginsLibDir A plugins library directory. + */ + CPluginManager(const std::string& pPluginsConfDir, + const std::string& pPluginsLibDir); + /** + * A destructor. + */ + ~CPluginManager(); + /** + * A method, which loads all plugins in plugins library direcotry. + */ + void LoadPlugins(); + /** + * A method, which unregister and unload all loaded plugins. + */ + void UnLoadPlugins(); + /** + * A method, which loads particular plugin. + * @param pName A plugin name. + */ + void LoadPlugin(const std::string& pName); + /** + * A method, which unloads particular plugin. + * @param pName A plugin name. + */ + void UnLoadPlugin(const std::string& pName); + /** + * A method, which registers particular plugin. + * @param pName A plugin name. + */ + void RegisterPlugin(const std::string& pName); + /** + * A method, which unregister particular plugin. + * @param pName A plugin name. + */ + void UnRegisterPlugin(const std::string& pName); + /** + * A method, which returns instance of particular analyzer plugin. + * @param pName A plugin name. + * @return An analyzer plugin. + */ + CAnalyzer* GetAnalyzer(const std::string& pName); + /** + * A method, which returns instance of particular reporter plugin. + * @param pName A plugin name. + * @return A reporter plugin. + */ + CReporter* GetReporter(const std::string& pName); + /** + * A method, which returns instance of particular action plugin. + * @param pName A plugin name. + * @return An action plugin. + */ + CAction* GetAction(const std::string& pName); + /** + * A method, which returns instance of particular database plugin. + * @param pName A plugin name. + * @return A database plugin. + */ + CDatabase* GetDatabase(const std::string& pName); + /** + * A method, which returns type of particular plugin. + * @param pName A plugin name. + * @return A plugin type. + */ + plugin_type_t GetPluginType(const std::string& pName); + /** + * A method, which gets all plugins info (event those plugins which are + * disabled). It can be send via DBus to GUI and displayed to an user. + * Then a user can fill all needed informations like URLs etc. + * @return A vector of maps + */ + vector_map_string_string_t GetPluginsInfo(); + /** + * A method, which sets up a plugin. + * @param pName A plugin name. + * @param pSettings A plugin's settings. + */ + void SetPluginSettings(const std::string& pName, + const map_plugin_settings_t& pSettings); + /** + * A method, which returns plugin's settings. + * @param pName A plugin name. + * @return Plugin's settings + */ + map_plugin_settings_t GetPluginSettings(const std::string& pName); +}; + +#endif /*PLUGINMANAGER_H_*/ -- cgit