summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin/qfactoryloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/plugin/qfactoryloader.cpp')
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp157
1 files changed, 127 insertions, 30 deletions
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index fe5aea0e8a..ce988fa2ff 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -51,6 +51,10 @@
#include "qpluginloader.h"
#include "private/qobject_p.h"
#include "private/qcoreapplication_p.h"
+#include "qjsondocument.h"
+#include "qjsonvalue.h"
+#include "qjsonobject.h"
+#include "qjsonarray.h"
QT_BEGIN_NAMESPACE
@@ -137,29 +141,44 @@ void QFactoryLoader::update()
continue;
}
QStringList keys;
- if (!library->loadPlugin()) {
- if (qt_debug_component()) {
- qDebug() << library->errorString;
- qDebug() << " could not load";
+ if (library->compatPlugin) {
+ qWarning() << "Compat plugin, need to load for accessing meta data";
+ if (!library->loadPlugin()) {
+ if (qt_debug_component()) {
+ qDebug() << library->errorString;
+ qDebug() << " could not load";
+ }
+ library->release();
+ continue;
}
- library->release();
- continue;
- }
- if (!library->inst)
- library->inst = library->instance();
- QObject *instance = library->inst.data();
- if (!instance) {
- library->release();
- // ignore plugins that have a valid signature but cannot be loaded.
- continue;
+ if (!library->inst)
+ library->inst = library->instance();
+ QObject *instance = library->inst.data();
+ if (!instance) {
+ library->release();
+ // ignore plugins that have a valid signature but cannot be loaded.
+ continue;
+ }
+ QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
+ if (instance && factory && instance->qt_metacast(d->iid))
+ keys = factory->keys();
+ } else {
+ QString iid = library->metaData.value(QLatin1String("IID")).toString();
+ if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
+ QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
+ QJsonArray k = object.value(QLatin1String("Keys")).toArray();
+ for (int i = 0; i < k.size(); ++i) {
+ QString s = k.at(i).toString();
+ keys += s;
+ }
+ }
+ if (qt_debug_component())
+ qDebug() << "Got keys from plugin meta data" << keys;
}
- QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
- if (instance && factory && instance->qt_metacast(d->iid))
- keys = factory->keys();
- if (keys.isEmpty())
- library->unload();
+
if (keys.isEmpty()) {
+ library->unload();
library->release();
continue;
}
@@ -173,7 +192,12 @@ void QFactoryLoader::update()
if (!d->cs)
key = key.toLower();
QLibraryPrivate *previous = d->keyMap.value(key);
- if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) {
+ int prev_qt_version = 0;
+ if (previous) {
+ prev_qt_version = (int)previous->metaData.value(QLatin1String("version")).toDouble();
+ }
+ int qt_version = (int)library->metaData.value(QLatin1String("version")).toDouble();
+ if (!previous || (prev_qt_version > QT_VERSION && qt_version <= QT_VERSION)) {
d->keyMap[key] = library;
d->keyList += keys.at(k);
}
@@ -200,23 +224,76 @@ QStringList QFactoryLoader::keys() const
Q_D(const QFactoryLoader);
QMutexLocker locker(&d->mutex);
QStringList keys = d->keyList;
- QObjectList instances = QPluginLoader::staticInstances();
- for (int i = 0; i < instances.count(); ++i)
- if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instances.at(i)))
- if (instances.at(i)->qt_metacast(d->iid))
- keys += factory->keys();
+ QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
+ for (int i = 0; i < staticPlugins.count(); ++i) {
+ if (staticPlugins.at(i).metaData) {
+ const char *rawMetaData = staticPlugins.at(i).metaData();
+ QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
+ if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
+ continue;
+
+ QJsonObject meta = object.value(QLatin1String("MetaData")).toObject();
+ QJsonArray a = meta.value(QLatin1String("Keys")).toArray();
+ for (int i = 0; i < a.size(); ++i) {
+ QString s = a.at(i).toString();
+ if (!s.isEmpty())
+ keys += s;
+ }
+ } else {
+ // compat plugin
+ QObject *instance = staticPlugins.at(i).instance();
+ QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
+ if (instance && factory && instance->qt_metacast(d->iid))
+ keys = factory->keys();
+ }
+ }
return keys;
}
+QList<QJsonObject> QFactoryLoader::metaData() const
+{
+ Q_D(const QFactoryLoader);
+ QMutexLocker locker(&d->mutex);
+ QList<QJsonObject> metaData;
+ for (int i = 0; i < d->libraryList.size(); ++i)
+ metaData.append(d->libraryList.at(i)->metaData);
+
+ QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
+ for (int i = 0; i < staticPlugins.count(); ++i) {
+ if (staticPlugins.at(i).metaData) {
+ const char *rawMetaData = staticPlugins.at(i).metaData();
+ QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
+ if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
+ continue;
+
+ QJsonObject meta = object.value(QLatin1String("MetaData")).toObject();
+ metaData.append(meta);
+ } else {
+ // compat plugins
+ QObject *instance = staticPlugins.at(i).instance();
+ QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
+ if (instance && factory && instance->qt_metacast(d->iid)) {
+ QJsonObject meta;
+ QJsonArray a = QJsonArray::fromStringList(factory->keys());
+ meta.insert(QLatin1String("Keys"), a);
+ metaData.append(meta);
+ }
+ }
+ }
+ return metaData;
+}
+
QObject *QFactoryLoader::instance(const QString &key) const
{
Q_D(const QFactoryLoader);
QMutexLocker locker(&d->mutex);
- QObjectList instances = QPluginLoader::staticInstances();
- for (int i = 0; i < instances.count(); ++i)
- if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instances.at(i)))
- if (instances.at(i)->qt_metacast(d->iid) && factory->keys().contains(key, Qt::CaseInsensitive))
- return instances.at(i);
+ QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
+ for (int i = 0; i < staticPlugins.count(); ++i) {
+ QObject *instance = staticPlugins.at(i).instance();
+ if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance))
+ if (instance->qt_metacast(d->iid) && factory->keys().contains(key, Qt::CaseInsensitive))
+ return instance;
+ }
QString lowered = d->cs ? key : key.toLower();
if (QLibraryPrivate* library = d->keyMap.value(lowered)) {
@@ -234,6 +311,26 @@ QObject *QFactoryLoader::instance(const QString &key) const
return 0;
}
+QObject *QFactoryLoader::instance(int index) const
+{
+ Q_D(const QFactoryLoader);
+ if (index < 0 || index >= d->libraryList.size())
+ return 0;
+
+ QLibraryPrivate *library = d->libraryList.at(index);
+ if (library->instance || library->loadPlugin()) {
+ if (!library->inst)
+ library->inst = library->instance();
+ QObject *obj = library->inst.data();
+ if (obj) {
+ if (!obj->parent())
+ obj->moveToThread(QCoreApplicationPrivate::mainThread());
+ return obj;
+ }
+ }
+ return 0;
+}
+
#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
QLibraryPrivate *QFactoryLoader::library(const QString &key) const
{