kde-playground/kdepimlibs/akonadi/pluginloader.cpp
2015-04-14 21:49:29 +00:00

190 lines
6.1 KiB
C++

/* -*- c++ -*-
Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "pluginloader_p.h"
#include <kconfiggroup.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <klocalizedstring.h>
#include <kstandarddirs.h>
#include <KPluginLoader>
#include <QtCore/QDebug>
using namespace Akonadi;
PluginMetaData::PluginMetaData()
{
}
PluginMetaData::PluginMetaData(const QString &lib, const QString &name, const QString &comment, const QString &cname)
: library(lib)
, nameLabel(name)
, descriptionLabel(comment)
, className(cname)
, loaded(false)
{
}
PluginLoader *PluginLoader::mSelf = 0;
PluginLoader::PluginLoader()
{
scan();
}
PluginLoader::~PluginLoader()
{
qDeleteAll(mPluginLoaders);
mPluginLoaders.clear();
}
PluginLoader *PluginLoader::self()
{
if (!mSelf) {
mSelf = new PluginLoader();
}
return mSelf;
}
QStringList PluginLoader::names() const
{
return mPluginInfos.keys();
}
QObject *PluginLoader::createForName(const QString &name)
{
if (!mPluginInfos.contains(name)) {
kWarning(5300) << "plugin name \"" << name << "\" is unknown to the plugin loader." << endl;
return 0;
}
PluginMetaData &info = mPluginInfos[name];
//First try to load it staticly
foreach (QObject *plugin, QPluginLoader::staticInstances()) {
if (QLatin1String(plugin->metaObject()->className()) == info.className) {
info.loaded = true;
return plugin;
break;
}
}
if (!info.loaded) {
KPluginLoader *loader = new KPluginLoader(info.library);
if (loader->fileName().isEmpty()) {
kWarning(5300) << loader->errorString();
delete loader;
return 0;
}
mPluginLoaders.insert(name, loader);
info.loaded = true;
}
QPluginLoader *loader = mPluginLoaders.value(name);
Q_ASSERT(loader);
QObject *object = loader->instance();
if (!object) {
kWarning(5300) << "unable to load plugin for plugin name \"" << name << "\"." << endl;
kWarning(5300) << "Error was:\"" << loader->errorString() << "\"." << endl;
return 0;
}
return object;
}
PluginMetaData PluginLoader::infoForName(const QString &name) const
{
if (!mPluginInfos.contains(name)) {
return PluginMetaData();
}
return mPluginInfos.value(name);
}
void PluginLoader::scan()
{
const QStringList list = KGlobal::dirs()->findAllResources("data", QLatin1String("akonadi/plugins/serializer/*.desktop"),
KStandardDirs::Recursive | KStandardDirs::NoDuplicates);
for (int i = 0; i < list.count(); ++i) {
const QString entry = list.at(i);
KConfig config(entry, KConfig::SimpleConfig);
if (config.hasGroup("Misc") && config.hasGroup("Plugin")) {
KConfigGroup group(&config, "Plugin");
const QString type = group.readEntry("Type").toLower();
if (type.isEmpty()) {
kWarning(5300) << "missing or empty [Plugin]Type value in \"" << entry << "\" - skipping" << endl;
continue;
}
// read Class entry as a list so that types like QPair<A,B> are
// properly escaped and don't end up being split into QPair<A
// and B>.
const QStringList classes = group.readXdgListEntry("X-Akonadi-Class");
if (classes.isEmpty()) {
kWarning(5300) << "missing or empty [Plugin]X-Akonadi-Class value in \"" << entry << "\" - skipping" << endl;
continue;
}
const QString library = group.readEntry("X-KDE-Library");
if (library.isEmpty()) {
kWarning(5300) << "missing or empty [Plugin]X-KDE-Library value in \"" << entry << "\" - skipping" << endl;
continue;
}
KConfigGroup group2(&config, "Misc");
QString name = group2.readEntry("Name");
if (name.isEmpty()) {
kWarning(5300) << "missing or empty [Misc]Name value in \"" << entry << "\" - inserting default name" << endl;
name = i18n("Unnamed plugin");
}
QString comment = group2.readEntry("Comment");
if (comment.isEmpty()) {
kWarning(5300) << "missing or empty [Misc]Comment value in \"" << entry << "\" - inserting default name" << endl;
comment = i18n("No description available");
}
QString cname = group.readEntry("X-KDE-ClassName");
if (cname.isEmpty()) {
kWarning(5300) << "missing or empty X-KDE-ClassName value in \"" << entry << "\"" << endl;
}
const QStringList mimeTypes = type.split(QLatin1Char(','), QString::SkipEmptyParts);
kDebug(5300) << "registering Desktop file" << entry << "for" << mimeTypes << '@' << classes;
Q_FOREACH (const QString &mimeType, mimeTypes) {
Q_FOREACH (const QString &classType, classes) {
mPluginInfos.insert(mimeType + QLatin1Char('@') + classType, PluginMetaData(library, name, comment, cname));
}
}
} else {
kWarning(5300) << "Desktop file \"" << entry << "\" doesn't seem to describe a plugin " << "(misses Misc and/or Plugin group)" << endl;
}
}
}