umbrello API Documentation

pluginloader.cpp

00001 /***************************************************************************
00002     begin                : Mon Jan 13 2003
00003     copyright            : (C) 2003 by Andrew Sutton
00004     email                : ansutton@kent.edu
00005 ***************************************************************************/
00006 
00007 /***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 // own header
00017 #include "pluginloader.h"
00018 
00019 // Qt includes
00020 #include <qstring.h>
00021 
00022 // KDE includes
00023 #include <kdebug.h>
00024 #include <klibloader.h>
00025 
00026 // u2 includes
00027 #include "plugin.h"
00028 
00029 using namespace Umbrello;
00030 
00031 // static data
00032 PluginLoader *PluginLoader::_instance = NULL;
00033 
00034 PluginLoader::PluginLoader() :
00035         _plugins(),
00036         _categories()
00037 {
00038     // preseed the categories
00039     _categories["metamodel"] = PluginList();
00040     _categories["storage"] = PluginList();
00041     _categories["visual"] = PluginList();
00042 }
00043 
00044 PluginLoader::~PluginLoader()
00045 {
00046 }
00047 
00048 PluginLoader *
00049 PluginLoader::instance()
00050 {
00051     if(!_instance) _instance = new PluginLoader;
00052     return _instance;
00053 }
00054 
00055 Plugin *
00056 PluginLoader::loadPlugin(const QString &name)
00057 {
00058     KLibrary *lib = NULL;
00059     KLibFactory *factory = NULL;
00060     Plugin *plugin = NULL;
00061     PluginMap::iterator it;
00062     bool success = true;
00063 
00064     // if the plugin has already been loaded, increment
00065     // its reference and return.
00066     if((it = _plugins.find(name)) != _plugins.end()) {
00067         plugin = it.data();
00068         plugin->ref();
00069         return plugin;
00070     }
00071 
00072     // use KLibLoader to get a reference to the library
00073     lib = KLibLoader::self()->library(name.latin1());
00074     if(!lib) {
00075         kdError() << "failed loading plugin library " << name << endl;
00076         success = false;
00077     }
00078 
00079     // get the factory from the library
00080     if(success) {
00081         factory = lib->factory();
00082         if(!factory) {
00083             kdError() << "failed to find factory for " << name << endl;
00084             success = false;
00085         }
00086     }
00087 
00088     // use the factory to create the plugin
00089     if(success) {
00090         plugin = dynamic_cast<Plugin *>(factory->create((QObject*)0, name.latin1()));
00091         if(!plugin) {
00092             kdError() << "failed to create a plugin object for " << name << endl;
00093             success = false;
00094         }
00095         else {
00096             // we have to register the plugin here, otherwise, we can get
00097             // recursive loads
00098             _plugins[name] = plugin;
00099             _categories[plugin->category()].append(plugin);
00100         }
00101     }
00102 
00103     // initialize the plugin
00104     if(success && plugin) {
00105         success = plugin->init();
00106         if(!success) {
00107             // on failure, delete the plugin. this should cause the
00108             // library to unload.
00109             kdError() << "failure initializing " << name << endl;
00110             _categories[plugin->category()].remove(plugin);
00111             _plugins.remove(name);
00112             delete plugin;
00113         }
00114     }
00115 
00116     // finally, finally connect to the destroyed signal and keep a
00117     // reference to it
00118     if(success) {
00119         plugin->ref();
00120         connect(plugin, SIGNAL(destroyed(QObject *)), SLOT(slotDestroyed(QObject *)));
00121     }
00122 
00123     return plugin;
00124 }
00125 
00126 Plugin *
00127 PluginLoader::findPlugin(const QString &name)
00128 {
00129     Plugin *ret = NULL;
00130     PluginMap::iterator it = _plugins.find(name);
00131     if(it != _plugins.end()) {
00132         ret = it.data();
00133     }
00134     return ret;
00135 }
00136 
00137 void
00138 PluginLoader::unloadPlugin(const QString &name)
00139 {
00140     KLibLoader::self()->unloadLibrary(name.latin1());
00141 }
00142 
00143 const PluginLoader::PluginMap &
00144 PluginLoader::plugins() const
00145 {
00146     return _plugins;
00147 }
00148 
00149 const PluginLoader::CategoryMap &
00150 PluginLoader::categories() const
00151 {
00152     return _categories;
00153 }
00154 
00155 void
00156 PluginLoader::slotDestroyed(QObject *obj)
00157 {
00158     Plugin *plugin = static_cast<Plugin *>(obj);
00159 
00160     // we can't just use the name because its already been destroyed
00161     // at this point. we have to iterate thru and find the reference
00162     // by hand.
00163 
00164     PluginMap::iterator end(_plugins.end());
00165     for(PluginMap::iterator i = _plugins.begin(); i != end; ++i) {
00166         Plugin *p = i.data();
00167         if(p == plugin) {
00168             kdDebug() << "unloading plugin " << i.key() << endl;
00169 
00170             // remove it from the mapping
00171             _plugins.remove(i);
00172             break;
00173         }
00174     }
00175 }
00176 
00177 #include "pluginloader.moc"
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:59 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003