1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
/*
* SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "DiscoverBackendsFactory.h"
#include "libdiscover_debug.h"
#include "resources/AbstractResourcesBackend.h"
#include "resources/ResourcesModel.h"
#include "utils.h"
#include <KConfigGroup>
#include <KDesktopFile>
#include <KLocalizedString>
#include <KSharedConfig>
#include <QCommandLineParser>
#include <QDir>
#include <QDirIterator>
#include <QPluginLoader>
#include <QStandardPaths>
using namespace Qt::StringLiterals;
Q_GLOBAL_STATIC(QStringList, s_requestedBackends)
static bool s_isFeedback = false;
void DiscoverBackendsFactory::setRequestedBackends(const QStringList &backends)
{
*s_requestedBackends = backends;
}
bool DiscoverBackendsFactory::hasRequestedBackends()
{
return !s_requestedBackends->isEmpty();
}
DiscoverBackendsFactory::DiscoverBackendsFactory()
{
}
QVector<AbstractResourcesBackend *> DiscoverBackendsFactory::backend(const QString &name) const
{
if (QDir::isAbsolutePath(name) && QStandardPaths::isTestModeEnabled()) {
return backendForFile(name, QFileInfo(name).fileName());
} else {
return backendForFile(name, name);
}
}
QVector<AbstractResourcesBackend *> DiscoverBackendsFactory::backendForFile(const QString &libname, const QString &name) const
{
QPluginLoader *loader = new QPluginLoader(QLatin1String("discover/") + libname, QCoreApplication::instance());
if (const auto iid = loader->metaData().value("IID"_L1).toString(); iid != QLatin1StringView(DISCOVER_PLUGIN_IID)) {
qCWarning(LIBDISCOVER_LOG) << "Plugin" << libname << "doesn't have the right IID" << iid << "expected" << DISCOVER_PLUGIN_IID;
return {};
}
// qCDebug(LIBDISCOVER_LOG) << "trying to load plugin:" << loader->fileName();
AbstractResourcesBackendFactory *f = qobject_cast<AbstractResourcesBackendFactory *>(loader->instance());
if (!f) {
qCWarning(LIBDISCOVER_LOG) << "error loading" << libname << loader->errorString() << loader->metaData();
return {};
}
auto instances = f->newInstance(QCoreApplication::instance(), name);
if (instances.isEmpty()) {
qCWarning(LIBDISCOVER_LOG) << "Couldn't find the backend: " << libname << "among" << allBackendNames(false, true);
return instances;
}
return instances;
}
QStringList DiscoverBackendsFactory::allBackendNames(bool whitelist, bool allowDummy) const
{
if (whitelist) {
QStringList whitelistNames = *s_requestedBackends;
if (s_isFeedback || !whitelistNames.isEmpty())
return whitelistNames;
}
QStringList pluginNames;
const auto libraryPaths = QCoreApplication::libraryPaths();
qDebug() << "libs" << libraryPaths;
for (const QString &dir : libraryPaths) {
QDirIterator it(dir + QStringLiteral("/discover"), QDir::Files);
while (it.hasNext()) {
it.next();
if (QLibrary::isLibrary(it.fileName()) && (allowDummy || it.fileName() != QLatin1String("dummy-backend.so"))) {
pluginNames += it.fileInfo().baseName();
}
}
}
pluginNames.removeDuplicates(); // will happen when discover is installed twice on the system
return pluginNames;
}
QVector<AbstractResourcesBackend *> DiscoverBackendsFactory::allBackends() const
{
QStringList names = allBackendNames();
auto ret = kTransform<QVector<AbstractResourcesBackend *>>(names, [this](const QString &name) {
return backend(name);
});
ret.removeAll(nullptr);
if (ret.isEmpty()) {
qCWarning(LIBDISCOVER_LOG) << "Didn't find any Discover backend!";
}
return ret;
}
int DiscoverBackendsFactory::backendsCount() const
{
return allBackendNames().count();
}
void DiscoverBackendsFactory::setupCommandLine(QCommandLineParser *parser)
{
parser->addOption(QCommandLineOption(QStringLiteral("backends"),
i18n("List all the backends we'll want to have loaded, separated by comma ','."),
QStringLiteral("names")));
}
void DiscoverBackendsFactory::processCommandLine(QCommandLineParser *parser, bool test)
{
if (parser->isSet(QStringLiteral("feedback"))) {
s_isFeedback = true;
s_requestedBackends->clear();
return;
}
QStringList backends = test //
? QStringList{QStringLiteral("dummy-backend")} //
: parser->value(QStringLiteral("backends")).split(QLatin1Char(','), Qt::SkipEmptyParts);
for (auto &backend : backends) {
if (!backend.endsWith(QLatin1String("-backend"))) {
backend.append(QLatin1String("-backend"));
}
}
*s_requestedBackends = backends;
}
|