summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/pluginloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'umbrello/umbrello/pluginloader.cpp')
-rw-r--r--umbrello/umbrello/pluginloader.cpp177
1 files changed, 177 insertions, 0 deletions
diff --git a/umbrello/umbrello/pluginloader.cpp b/umbrello/umbrello/pluginloader.cpp
new file mode 100644
index 00000000..db79bca1
--- /dev/null
+++ b/umbrello/umbrello/pluginloader.cpp
@@ -0,0 +1,177 @@
+/***************************************************************************
+ begin : Mon Jan 13 2003
+ copyright : (C) 2003 by Andrew Sutton
+ email : ansutton@kent.edu
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// own header
+#include "pluginloader.h"
+
+// Qt includes
+#include <qstring.h>
+
+// KDE includes
+#include <kdebug.h>
+#include <klibloader.h>
+
+// u2 includes
+#include "plugin.h"
+
+using namespace Umbrello;
+
+// static data
+PluginLoader *PluginLoader::_instance = NULL;
+
+PluginLoader::PluginLoader() :
+ _plugins(),
+ _categories()
+{
+ // preseed the categories
+ _categories["metamodel"] = PluginList();
+ _categories["storage"] = PluginList();
+ _categories["visual"] = PluginList();
+}
+
+PluginLoader::~PluginLoader()
+{
+}
+
+PluginLoader *
+PluginLoader::instance()
+{
+ if(!_instance) _instance = new PluginLoader;
+ return _instance;
+}
+
+Plugin *
+PluginLoader::loadPlugin(const QString &name)
+{
+ KLibrary *lib = NULL;
+ KLibFactory *factory = NULL;
+ Plugin *plugin = NULL;
+ PluginMap::iterator it;
+ bool success = true;
+
+ // if the plugin has already been loaded, increment
+ // its reference and return.
+ if((it = _plugins.find(name)) != _plugins.end()) {
+ plugin = it.data();
+ plugin->ref();
+ return plugin;
+ }
+
+ // use KLibLoader to get a reference to the library
+ lib = KLibLoader::self()->library(name.latin1());
+ if(!lib) {
+ kdError() << "failed loading plugin library " << name << endl;
+ success = false;
+ }
+
+ // get the factory from the library
+ if(success) {
+ factory = lib->factory();
+ if(!factory) {
+ kdError() << "failed to find factory for " << name << endl;
+ success = false;
+ }
+ }
+
+ // use the factory to create the plugin
+ if(success) {
+ plugin = dynamic_cast<Plugin *>(factory->create((QObject*)0, name.latin1()));
+ if(!plugin) {
+ kdError() << "failed to create a plugin object for " << name << endl;
+ success = false;
+ }
+ else {
+ // we have to register the plugin here, otherwise, we can get
+ // recursive loads
+ _plugins[name] = plugin;
+ _categories[plugin->category()].append(plugin);
+ }
+ }
+
+ // initialize the plugin
+ if(success && plugin) {
+ success = plugin->init();
+ if(!success) {
+ // on failure, delete the plugin. this should cause the
+ // library to unload.
+ kdError() << "failure initializing " << name << endl;
+ _categories[plugin->category()].remove(plugin);
+ _plugins.remove(name);
+ delete plugin;
+ }
+ }
+
+ // finally, finally connect to the destroyed signal and keep a
+ // reference to it
+ if(success) {
+ plugin->ref();
+ connect(plugin, SIGNAL(destroyed(QObject *)), SLOT(slotDestroyed(QObject *)));
+ }
+
+ return plugin;
+}
+
+Plugin *
+PluginLoader::findPlugin(const QString &name)
+{
+ Plugin *ret = NULL;
+ PluginMap::iterator it = _plugins.find(name);
+ if(it != _plugins.end()) {
+ ret = it.data();
+ }
+ return ret;
+}
+
+void
+PluginLoader::unloadPlugin(const QString &name)
+{
+ KLibLoader::self()->unloadLibrary(name.latin1());
+}
+
+const PluginLoader::PluginMap &
+PluginLoader::plugins() const
+{
+ return _plugins;
+}
+
+const PluginLoader::CategoryMap &
+PluginLoader::categories() const
+{
+ return _categories;
+}
+
+void
+PluginLoader::slotDestroyed(QObject *obj)
+{
+ Plugin *plugin = static_cast<Plugin *>(obj);
+
+ // we can't just use the name because its already been destroyed
+ // at this point. we have to iterate thru and find the reference
+ // by hand.
+
+ PluginMap::iterator end(_plugins.end());
+ for(PluginMap::iterator i = _plugins.begin(); i != end; ++i) {
+ Plugin *p = i.data();
+ if(p == plugin) {
+ kdDebug() << "unloading plugin " << i.key() << endl;
+
+ // remove it from the mapping
+ _plugins.remove(i);
+ break;
+ }
+ }
+}
+
+#include "pluginloader.moc"