diff --git a/autotests/plugins/cli7zplugin/cli7ztest.h b/autotests/plugins/cli7zplugin/cli7ztest.h --- a/autotests/plugins/cli7zplugin/cli7ztest.h +++ b/autotests/plugins/cli7zplugin/cli7ztest.h @@ -27,7 +27,7 @@ #define CLI7ZTEST_H #include "cliplugin.h" -#include +#include "pluginmanager.h" using namespace Kerfuffle; @@ -49,7 +49,8 @@ void testExtractArgs(); private: - KPluginMetaData m_pluginMetadata; + PluginManager m_pluginManger; + Plugin *m_plugin; }; Q_DECLARE_METATYPE(ArchiveEntry) diff --git a/autotests/plugins/cli7zplugin/cli7ztest.cpp b/autotests/plugins/cli7zplugin/cli7ztest.cpp --- a/autotests/plugins/cli7zplugin/cli7ztest.cpp +++ b/autotests/plugins/cli7zplugin/cli7ztest.cpp @@ -40,9 +40,11 @@ { qRegisterMetaType(); - const auto plugins = KPluginLoader::findPluginsById(QStringLiteral("kerfuffle"), QStringLiteral("kerfuffle_cli7z")); - if (plugins.size() == 1) { - m_pluginMetadata = plugins.at(0); + m_plugin = new Plugin(this); + foreach (Plugin *plugin, m_pluginManger.availablePlugins()) { + if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_cli7z")) { + m_plugin = plugin; + } } } @@ -65,12 +67,12 @@ void Cli7zTest::testArchive() { - if (!m_pluginMetadata.isValid()) { - QSKIP("Could not find the cli7z plugin. Skipping test.", SkipSingle); + if (!m_plugin->isValid()) { + QSKIP("cli7z plugin not available. Skipping test.", SkipSingle); } QFETCH(QString, archivePath); - Archive *archive = Archive::create(archivePath, m_pluginMetadata, this); + Archive *archive = Archive::create(archivePath, m_plugin, this); QVERIFY(archive); if (!archive->isValid()) { diff --git a/autotests/plugins/clirarplugin/clirartest.h b/autotests/plugins/clirarplugin/clirartest.h --- a/autotests/plugins/clirarplugin/clirartest.h +++ b/autotests/plugins/clirarplugin/clirartest.h @@ -28,7 +28,7 @@ #define CLIRARTEST_H #include "cliplugin.h" -#include +#include "pluginmanager.h" using namespace Kerfuffle; @@ -50,7 +50,8 @@ void testExtractArgs(); private: - KPluginMetaData m_pluginMetadata; + PluginManager m_pluginManger; + Plugin *m_plugin; }; Q_DECLARE_METATYPE(ArchiveEntry) diff --git a/autotests/plugins/clirarplugin/clirartest.cpp b/autotests/plugins/clirarplugin/clirartest.cpp --- a/autotests/plugins/clirarplugin/clirartest.cpp +++ b/autotests/plugins/clirarplugin/clirartest.cpp @@ -41,9 +41,11 @@ { qRegisterMetaType(); - const auto plugins = KPluginLoader::findPluginsById(QStringLiteral("kerfuffle"), QStringLiteral("kerfuffle_clirar")); - if (plugins.size() == 1) { - m_pluginMetadata = plugins.at(0); + m_plugin = new Plugin(this); + foreach (Plugin *plugin, m_pluginManger.availablePlugins()) { + if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_clirar")) { + m_plugin = plugin; + } } } @@ -66,12 +68,12 @@ void CliRarTest::testArchive() { - if (!m_pluginMetadata.isValid()) { - QSKIP("Could not find the clirar plugin. Skipping test.", SkipSingle); + if (!m_plugin->isValid()) { + QSKIP("clirar plugin not available. Skipping test.", SkipSingle); } QFETCH(QString, archivePath); - Archive *archive = Archive::create(archivePath, m_pluginMetadata, this); + Archive *archive = Archive::create(archivePath, m_plugin, this); QVERIFY(archive); if (!archive->isValid()) { diff --git a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h --- a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h +++ b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h @@ -21,7 +21,7 @@ #define CLIUNARCHIVERTEST_H #include "cliplugin.h" -#include +#include "pluginmanager.h" using namespace Kerfuffle; @@ -45,7 +45,8 @@ private: - KPluginMetaData m_pluginMetadata; + PluginManager m_pluginManger; + Plugin *m_plugin; }; Q_DECLARE_METATYPE(ArchiveEntry) diff --git a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp --- a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp +++ b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp @@ -18,7 +18,7 @@ */ #include "cliunarchivertest.h" -#include "kerfuffle/jobs.h" +#include "jobs.h" #include #include @@ -36,9 +36,11 @@ { qRegisterMetaType(); - const auto plugins = KPluginLoader::findPluginsById(QStringLiteral("kerfuffle"), QStringLiteral("kerfuffle_cliunarchiver")); - if (plugins.size() == 1) { - m_pluginMetadata = plugins.at(0); + m_plugin = new Plugin(this); + foreach (Plugin *plugin, m_pluginManger.availablePlugins()) { + if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_cliunarchiver")) { + m_plugin = plugin; + } } } @@ -76,12 +78,12 @@ void CliUnarchiverTest::testArchive() { - if (!m_pluginMetadata.isValid()) { - QSKIP("Could not find the cliunarchiver plugin. Skipping test.", SkipSingle); + if (!m_plugin->isValid()) { + QSKIP("cliunarchiver plugin not available. Skipping test.", SkipSingle); } QFETCH(QString, archivePath); - Archive *archive = Archive::create(archivePath, m_pluginMetadata, this); + Archive *archive = Archive::create(archivePath, m_plugin, this); QVERIFY(archive); if (!archive->isValid()) { @@ -279,12 +281,12 @@ // if we ever ends up using a temp dir for any cliplugin, instead of only for cliunarchiver. void CliUnarchiverTest::testExtraction() { - if (!m_pluginMetadata.isValid()) { - QSKIP("Could not find the cliunarchiver plugin. Skipping test.", SkipSingle); + if (!m_plugin->isValid()) { + QSKIP("cliunarchiver plugin not available. Skipping test.", SkipSingle); } QFETCH(QString, archivePath); - Archive *archive = Archive::create(archivePath, m_pluginMetadata, this); + Archive *archive = Archive::create(archivePath, m_plugin, this); QVERIFY(archive); if (!archive->isValid()) { diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h --- a/kerfuffle/archive_kerfuffle.h +++ b/kerfuffle/archive_kerfuffle.h @@ -45,6 +45,7 @@ class ExtractJob; class DeleteJob; class AddJob; +class Plugin; class Query; class ReadOnlyArchiveInterface; @@ -173,19 +174,15 @@ qulonglong packedSize() const; QString subfolderName(); - static bool comparePlugins(const KPluginMetaData &p1, const KPluginMetaData &p2); - static QVector findPluginOffers(const QString& filename, const QString& fixedMimeType); - static Archive *create(const QString &fileName, QObject *parent = 0); static Archive *create(const QString &fileName, const QString &fixedMimeType, QObject *parent = 0); /** - * Create an archive instance from a given plugin. + * Create an archive instance from a given @p plugin. * @param fileName The name of the archive. - * @param pluginMetadata The plugin's metadata. * @return A valid archive if the plugin could be loaded, an invalid one otherwise (with the FailedPlugin error set). */ - static Archive *create(const QString &fileName, const KPluginMetaData &pluginMetadata, QObject *parent = Q_NULLPTR); + static Archive *create(const QString &fileName, Plugin *plugin, QObject *parent = Q_NULLPTR); ~Archive(); diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp --- a/kerfuffle/archive_kerfuffle.cpp +++ b/kerfuffle/archive_kerfuffle.cpp @@ -30,43 +30,21 @@ #include "archiveinterface.h" #include "jobs.h" #include "mimetypes.h" +#include "pluginmanager.h" #include #include #include #include #include +#include #include #include namespace Kerfuffle { -bool Archive::comparePlugins(const KPluginMetaData &p1, const KPluginMetaData &p2) -{ - return (p1.rawData()[QStringLiteral("X-KDE-Priority")].toInt()) > (p2.rawData()[QStringLiteral("X-KDE-Priority")].toInt()); -} - -QVector Archive::findPluginOffers(const QString& filename, const QString& fixedMimeType) -{ - qCDebug(ARK) << "Find plugin offers for" << filename << "with mime" << fixedMimeType; - - const QString mimeType = fixedMimeType.isEmpty() ? determineMimeType(filename).name() : fixedMimeType; - - qCDebug(ARK) << "Detected mime" << mimeType; - - QVector offers = KPluginLoader::findPlugins(QStringLiteral("kerfuffle"), [mimeType](const KPluginMetaData& metaData) { - return metaData.serviceTypes().contains(QStringLiteral("Kerfuffle/Plugin")) && - metaData.mimeTypes().contains(mimeType); - }); - - qSort(offers.begin(), offers.end(), comparePlugins); - qCDebug(ARK) << "Have" << offers.size() << "offers"; - - return offers; -} - QDebug operator<<(QDebug d, const fileRootNodePair &pair) { d.nospace() << "fileRootNodePair(" << pair.file << "," << pair.rootNode << ")"; @@ -84,15 +62,18 @@ qRegisterMetaType("ArchiveEntry"); - const QVector offers = findPluginOffers(fileName, fixedMimeType); + PluginManager pluginManager; + const QMimeType mimeType = fixedMimeType.isEmpty() ? determineMimeType(fileName) : QMimeDatabase().mimeTypeForName(fixedMimeType); + + const QVector offers = pluginManager.preferredPluginsFor(mimeType); if (offers.isEmpty()) { qCCritical(ARK) << "Could not find a plugin to handle" << fileName; return new Archive(NoPlugin, parent); } Archive *archive; - foreach (const KPluginMetaData& pluginMetadata, offers) { - archive = create(fileName, pluginMetadata, parent); + foreach (Plugin *plugin, offers) { + archive = create(fileName, plugin, parent); // Use the first valid plugin, according to the priority sorting. if (archive->isValid()) { return archive; @@ -103,42 +84,32 @@ return archive; } -Archive *Archive::create(const QString &fileName, const KPluginMetaData &pluginMetadata, QObject *parent) +Archive *Archive::create(const QString &fileName, Plugin *plugin, QObject *parent) { - const bool isReadOnly = !pluginMetadata.rawData()[QStringLiteral("X-KDE-Kerfuffle-ReadWrite")].toBool(); - qCDebug(ARK) << "Loading plugin" << pluginMetadata.pluginId(); + Q_ASSERT(plugin); + + qCDebug(ARK) << "Checking plugin" << plugin->metaData().pluginId(); - KPluginFactory *factory = KPluginLoader(pluginMetadata.fileName()).factory(); + KPluginFactory *factory = KPluginLoader(plugin->metaData().fileName()).factory(); if (!factory) { - qCWarning(ARK) << "Invalid plugin factory for" << pluginMetadata.pluginId(); + qCWarning(ARK) << "Invalid plugin factory for" << plugin->metaData().pluginId(); return new Archive(FailedPlugin, parent); } const QVariantList args = {QVariant(QFileInfo(fileName).absoluteFilePath())}; ReadOnlyArchiveInterface *iface = factory->create(Q_NULLPTR, args); if (!iface) { - qCWarning(ARK) << "Could not create plugin instance" << pluginMetadata.pluginId(); + qCWarning(ARK) << "Could not create plugin instance" << plugin->metaData().pluginId(); return new Archive(FailedPlugin, parent); } - // Not CliBased plugin, don't search for executables. - if (!iface->isCliBased()) { - return new Archive(iface, isReadOnly, parent); - } - - qCDebug(ARK) << "Finding executables for plugin" << pluginMetadata.pluginId(); - - if (iface->findExecutables(!isReadOnly)) { - return new Archive(iface, isReadOnly, parent); - } - - if (!isReadOnly && iface->findExecutables(false)) { - qCWarning(ARK) << "Failed to find read-write executables: falling back to read-only mode for read-write plugin" << pluginMetadata.pluginId(); - return new Archive(iface, true, parent); + if (!plugin->isValid()) { + qCDebug(ARK) << "Cannot use plugin" << plugin->metaData().pluginId() << "- check whether" << plugin->readOnlyExecutables() << "are installed."; + return new Archive(FailedPlugin, parent); } - qCWarning(ARK) << "Failed to find needed executables for plugin" << pluginMetadata.pluginId(); - return new Archive(FailedPlugin, parent); + qCDebug(ARK) << "Successfully loaded plugin" << plugin->metaData().pluginId(); + return new Archive(iface, !plugin->isReadWrite(), parent); } Archive::Archive(ArchiveError errorCode, QObject *parent) diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h --- a/kerfuffle/archiveinterface.h +++ b/kerfuffle/archiveinterface.h @@ -104,7 +104,6 @@ virtual bool doResume(); virtual bool isCliBased() const; - virtual bool findExecutables(bool isReadWrite); bool isHeaderEncryptionEnabled() const; diff --git a/kerfuffle/archiveinterface.cpp b/kerfuffle/archiveinterface.cpp --- a/kerfuffle/archiveinterface.cpp +++ b/kerfuffle/archiveinterface.cpp @@ -70,12 +70,6 @@ return false; } -bool ReadOnlyArchiveInterface::findExecutables(bool isReadWrite) -{ - Q_UNUSED(isReadWrite) - return true; -} - bool ReadOnlyArchiveInterface::open() { return true; diff --git a/kerfuffle/cliinterface.h b/kerfuffle/cliinterface.h --- a/kerfuffle/cliinterface.h +++ b/kerfuffle/cliinterface.h @@ -282,7 +282,6 @@ bool doKill() Q_DECL_OVERRIDE; bool doSuspend() Q_DECL_OVERRIDE; bool doResume() Q_DECL_OVERRIDE; - bool findExecutables(bool isReadWrite) Q_DECL_OVERRIDE; bool isCliBased() const Q_DECL_OVERRIDE; /** diff --git a/kerfuffle/cliinterface.cpp b/kerfuffle/cliinterface.cpp --- a/kerfuffle/cliinterface.cpp +++ b/kerfuffle/cliinterface.cpp @@ -90,32 +90,6 @@ return true; } -bool CliInterface::findExecutables(bool isReadWrite) -{ - cacheParameterList(); - - QList execTypes = QList() << ListProgram << ExtractProgram; - if (isReadWrite) { - execTypes << AddProgram << DeleteProgram; - } - - foreach (const int execType, execTypes) { - bool execTypeFound = false; - foreach (const QString &program, m_param.value(execType).toStringList()) { - if (!QStandardPaths::findExecutable(program).isEmpty()) { - qCDebug(ARK) << "Found executable type" << execType << ":" << program; - execTypeFound = true; - break; - } - } - if (!execTypeFound) { - return false; - } - } - return true; -} - - void CliInterface::setListEmptyLines(bool emptyLines) { m_listEmptyLines = emptyLines;