File indexing completed on 2024-05-19 03:56:22
0001 /* 0002 This file is part of the KDE project 0003 0004 SPDX-FileCopyrightText: 2007 Matthias Kretz <kretz@kde.org> 0005 SPDX-FileCopyrightText: 2007 Bernhard Loos <nhuh.put@web.de> 0006 SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "kpluginfactory.h" 0012 #include "kpluginfactory_p.h" 0013 0014 #include "kcoreaddons_debug.h" 0015 #include <QPluginLoader> 0016 #include <algorithm> 0017 0018 KPluginFactory::KPluginFactory() 0019 : d(new KPluginFactoryPrivate) 0020 { 0021 } 0022 0023 KPluginFactory::~KPluginFactory() = default; 0024 0025 KPluginFactory::Result<KPluginFactory> KPluginFactory::loadFactory(const KPluginMetaData &data) 0026 { 0027 Result<KPluginFactory> result; 0028 QObject *obj = nullptr; 0029 if (data.isStaticPlugin()) { 0030 obj = data.staticPlugin().instance(); 0031 } else { 0032 if (data.fileName().isEmpty()) { 0033 result.errorString = tr("Could not find plugin %1").arg(data.requestedFileName()); 0034 result.errorText = QStringLiteral("Could not find plugin %1").arg(data.requestedFileName()); 0035 result.errorReason = INVALID_PLUGIN; 0036 qCWarning(KCOREADDONS_DEBUG) << result.errorText; 0037 return result; 0038 } 0039 QPluginLoader loader(data.fileName()); 0040 obj = loader.instance(); 0041 if (!obj) { 0042 result.errorString = tr("Could not load plugin from %1: %2").arg(data.fileName(), loader.errorString()); 0043 result.errorText = QStringLiteral("Could not load plugin from %1: %2").arg(data.fileName(), loader.errorString()); 0044 result.errorReason = INVALID_PLUGIN; 0045 qCWarning(KCOREADDONS_DEBUG) << result.errorText; 0046 return result; 0047 } 0048 } 0049 0050 KPluginFactory *factory = qobject_cast<KPluginFactory *>(obj); 0051 0052 if (factory == nullptr) { 0053 result.errorString = tr("The library %1 does not offer a KPluginFactory.").arg(data.fileName()); 0054 result.errorReason = INVALID_FACTORY; 0055 qCWarning(KCOREADDONS_DEBUG) << "Expected a KPluginFactory, got a" << obj->metaObject()->className(); 0056 delete obj; 0057 return result; 0058 } 0059 0060 factory->setMetaData(data); 0061 result.plugin = factory; 0062 return result; 0063 } 0064 0065 KPluginMetaData KPluginFactory::metaData() const 0066 { 0067 return d->metaData; 0068 } 0069 0070 void KPluginFactory::setMetaData(const KPluginMetaData &metaData) 0071 { 0072 d->metaData = metaData; 0073 } 0074 0075 void KPluginFactory::registerPlugin(const QMetaObject *metaObject, CreateInstanceWithMetaDataFunction instanceFunction) 0076 { 0077 Q_ASSERT(metaObject); 0078 const QMetaObject *superClass = metaObject->superClass(); 0079 Q_ASSERT(superClass); 0080 0081 for (const KPluginFactoryPrivate::PluginWithMetadata &plugin : d->createInstanceWithMetaDataHash) { 0082 for (const QMetaObject *otherSuper = plugin.first->superClass(); otherSuper; otherSuper = otherSuper->superClass()) { 0083 if (superClass == otherSuper) { 0084 qCWarning(KCOREADDONS_DEBUG).nospace() << "Two plugins with the same interface (" << superClass->className() 0085 << ") were registered in the KPluginFactory " << this->metaObject()->className() << ". " 0086 << "This might be due to a missing Q_OBJECT macro in one of the registered classes"; 0087 } 0088 } 0089 } 0090 // check hierarchy of newly newly registered plugin against all registered classes 0091 for (const KPluginFactoryPrivate::PluginWithMetadata &plugin : d->createInstanceWithMetaDataHash) { 0092 superClass = plugin.first->superClass(); 0093 for (const QMetaObject *otherSuper = metaObject->superClass(); otherSuper; otherSuper = otherSuper->superClass()) { 0094 if (superClass == otherSuper) { 0095 qCWarning(KCOREADDONS_DEBUG).nospace() << "Two plugins with the same interface (" << superClass->className() 0096 << ") were registered in the KPluginFactory " << this->metaObject()->className() << ". " 0097 << "This might be due to a missing Q_OBJECT macro in one of the registered classes"; 0098 } 0099 } 0100 } 0101 d->createInstanceWithMetaDataHash.push_back({metaObject, instanceFunction}); 0102 } 0103 0104 void KPluginFactory::logFailedInstantiationMessage(KPluginMetaData data) 0105 { 0106 qCWarning(KCOREADDONS_DEBUG) << "KPluginFactory could not load the plugin" << data.fileName(); 0107 } 0108 void KPluginFactory::logFailedInstantiationMessage(const char *className, KPluginMetaData data) 0109 { 0110 qCWarning(KCOREADDONS_DEBUG) << "KPluginFactory could not create a" << className << "instance from" << data.fileName(); 0111 } 0112 0113 QObject *KPluginFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args) 0114 { 0115 for (const KPluginFactoryPrivate::PluginWithMetadata &plugin : d->createInstanceWithMetaDataHash) { 0116 for (const QMetaObject *current = plugin.first; current; current = current->superClass()) { 0117 if (0 == qstrcmp(iface, current->className())) { 0118 return plugin.second(parentWidget, parent, d->metaData, args); 0119 } 0120 } 0121 } 0122 0123 return nullptr; 0124 } 0125 0126 #include "moc_kpluginfactory.cpp"