File indexing completed on 2024-05-12 05:26:03
0001 /* 0002 * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) version 3, or any 0008 * later version accepted by the membership of KDE e.V. (or its 0009 * successor approved by the membership of KDE e.V.), which shall 0010 * act as a proxy defined in Section 6 of version 3 of the license. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #include "resource.h" 0022 0023 #include <QCoreApplication> 0024 #include <QDir> 0025 #include <QPluginLoader> 0026 #include <QPointer> 0027 0028 #include "facadefactory.h" 0029 #include "adaptorfactoryregistry.h" 0030 0031 namespace Sink { 0032 0033 Resource::Resource() : QObject(), d(nullptr) 0034 { 0035 Q_UNUSED(d); 0036 } 0037 0038 Resource::~Resource() 0039 { 0040 // delete d; 0041 } 0042 0043 void Resource::processCommand(int commandId, const QByteArray &data) 0044 { 0045 Q_UNUSED(commandId) 0046 Q_UNUSED(data) 0047 } 0048 0049 void Resource::setLowerBoundRevision(qint64 revision) 0050 { 0051 Q_UNUSED(revision) 0052 } 0053 0054 void Resource::setSecret(const QString &s) 0055 { 0056 Q_UNUSED(s) 0057 } 0058 0059 bool Resource::checkForUpgrade() 0060 { 0061 return false; 0062 } 0063 0064 0065 class ResourceFactory::Private 0066 { 0067 public: 0068 QByteArrayList capabilities; 0069 }; 0070 0071 typedef QHash<QString, QPointer<ResourceFactory>> FactoryRegistry; 0072 Q_GLOBAL_STATIC(FactoryRegistry, s_loadedFactories); 0073 0074 ResourceFactory::ResourceFactory(QObject *parent, const QByteArrayList &capabilities) : QObject(parent), d(new ResourceFactory::Private) 0075 { 0076 d->capabilities = capabilities; 0077 } 0078 0079 ResourceFactory::~ResourceFactory() 0080 { 0081 delete d; 0082 } 0083 0084 ResourceFactory *ResourceFactory::load(const QByteArray &resourceName) 0085 { 0086 ResourceFactory *factory = s_loadedFactories->value(resourceName); 0087 if (factory) { 0088 return factory; 0089 } 0090 0091 for (auto const &path : QCoreApplication::instance()->libraryPaths()) { 0092 QDir pluginDir(path); 0093 // TODO: centralize this so that it is easy to change centrally 0094 // also ref'd in cmake as ${SINK_RESOURCE_PLUGINS_PATH} 0095 if (!pluginDir.cd(QStringLiteral("sink")) || !pluginDir.cd(QStringLiteral("resources"))) { 0096 continue; 0097 } 0098 0099 for (const QString &fileName : pluginDir.entryList(QDir::Files)) { 0100 const QString path = pluginDir.absoluteFilePath(fileName); 0101 QPluginLoader loader(path); 0102 0103 const QString id = loader.metaData()[QStringLiteral("IID")].toString(); 0104 if (id == resourceName) { 0105 QObject *object = loader.instance(); 0106 if (object) { 0107 factory = qobject_cast<ResourceFactory *>(object); 0108 if (factory) { 0109 s_loadedFactories->insert(resourceName, factory); 0110 //TODO: Instead of always loading both facades and adaptorfactories into the respective singletons, we could also leave this up to the caller. (ResourceFactory::loadFacades(...)) 0111 factory->registerFacades(resourceName, FacadeFactory::instance()); 0112 factory->registerAdaptorFactories(resourceName, AdaptorFactoryRegistry::instance()); 0113 // TODO: if we need more data on it const QJsonObject json = loader.metaData()[QStringLiteral("MetaData")].toObject(); 0114 return factory; 0115 } else { 0116 qWarning() << "Plugin for" << resourceName << "from plugin" << loader.fileName() << "produced the wrong object type:" << object; 0117 delete object; 0118 } 0119 } else { 0120 qWarning() << "Could not load factory for" << resourceName << "from plugin" << loader.fileName() << "due to the following error:" << loader.errorString(); 0121 } 0122 } 0123 } 0124 } 0125 0126 qWarning() << "Failed to find factory for resource:" << resourceName; 0127 qWarning() << "Looked into the following directories: " << QCoreApplication::instance()->libraryPaths(); 0128 return nullptr; 0129 } 0130 0131 QByteArrayList ResourceFactory::capabilities() const 0132 { 0133 return d->capabilities; 0134 } 0135 0136 } // namespace Sink 0137 0138 // Ignore warning I don't know how to fix in a moc file 0139 #pragma clang diagnostic push 0140 #pragma clang diagnostic ignored "-Wundefined-reinterpret-cast" 0141 #include "moc_resource.cpp" 0142 #pragma clang diagnostic pop