diff --git a/autotests/extractorcollectiontest.cpp b/autotests/extractorcollectiontest.cpp index b321f82..f177468 100644 --- a/autotests/extractorcollectiontest.cpp +++ b/autotests/extractorcollectiontest.cpp @@ -1,46 +1,59 @@ /* * This file is part of the KDE KFileMetaData project * Copyright (C) 2014 Vishesh Handa * 2017 Igor Poboiko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "extractorcollection.h" #include "extractors/plaintextextractor.h" using namespace KFileMetaData; class ExtractorCollectionTest : public QObject { Q_OBJECT private Q_SLOTS: void testFetchExtractors() { QCoreApplication::setLibraryPaths({QCoreApplication::applicationDirPath()}); ExtractorCollection collection; QVERIFY(collection.fetchExtractors("unknown/mimetype").isEmpty()); QVERIFY(!collection.fetchExtractors("text/plain").isEmpty()); } + + void testMultipleExtractorCollections() + { + QCoreApplication::setLibraryPaths({QCoreApplication::applicationDirPath()}); + ExtractorCollection collection; + QVERIFY(collection.fetchExtractors("unknown/mimetype").isEmpty()); + QVERIFY(!collection.fetchExtractors("text/plain").isEmpty()); + ExtractorCollection collection2; + QVERIFY(collection.fetchExtractors("unknown/mimetype").isEmpty()); + QVERIFY(!collection.fetchExtractors("text/plain").isEmpty()); + QVERIFY(collection2.fetchExtractors("unknown/mimetype").isEmpty()); + QVERIFY(!collection2.fetchExtractors("text/plain").isEmpty()); + } }; QTEST_GUILESS_MAIN(ExtractorCollectionTest) #include "extractorcollectiontest.moc" diff --git a/src/extractor.cpp b/src/extractor.cpp index 7becc41..54af18a 100644 --- a/src/extractor.cpp +++ b/src/extractor.cpp @@ -1,46 +1,59 @@ /* * * Copyright (C) 2014 Vishesh Handa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "extractor.h" #include "extractor_p.h" #include "extractorplugin.h" using namespace KFileMetaData; Extractor::Extractor() : d(new ExtractorPrivate) { } Extractor::~Extractor() { - delete d->m_plugin; + if (d->m_autoDeletePlugin == AutoDeletePlugin) { + delete d->m_plugin; + } + delete d; } void Extractor::extract(ExtractionResult* result) { d->m_plugin->extract(result); } QStringList Extractor::mimetypes() const { return d->m_plugin->mimetypes(); } + +void Extractor::setExtractorPlugin(ExtractorPlugin *extractorPlugin) +{ + d->m_plugin = extractorPlugin; +} + +void Extractor::setAutoDeletePlugin(ExtractorPluginOwnership autoDelete) +{ + d->m_autoDeletePlugin = autoDelete; +} diff --git a/src/extractor.h b/src/extractor.h index 5cc2b7b..0cec637 100644 --- a/src/extractor.h +++ b/src/extractor.h @@ -1,52 +1,63 @@ /* * * Copyright (C) 2014 Vishesh Handa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef KFILEMETADATA_EXTRACTOR_H #define KFILEMETADATA_EXTRACTOR_H #include "kfilemetadata_export.h" #include namespace KFileMetaData { class ExtractionResult; class ExtractorCollection; -class ExtractorPrivate; +class ExtractorPlugin; class KFILEMETADATA_EXPORT Extractor { + class ExtractorPrivate; + + enum ExtractorPluginOwnership { + AutoDeletePlugin, + DoNotDeletePlugin, + }; + public: - virtual ~Extractor(); + virtual ~Extractor() noexcept; void extract(ExtractionResult* result); QStringList mimetypes() const; private: Extractor(); Extractor(const Extractor&); void operator =(const Extractor&); + void setExtractorPlugin(ExtractorPlugin *extractorPlugin); + + void setAutoDeletePlugin(ExtractorPluginOwnership autoDelete); + ExtractorPrivate *d; friend class ExtractorCollection; }; } #endif // KFILEMETADATA_EXTRACTOR_H diff --git a/src/extractor_p.h b/src/extractor_p.h index 62b7096..c46f22b 100644 --- a/src/extractor_p.h +++ b/src/extractor_p.h @@ -1,36 +1,40 @@ /* * * Copyright (C) 2014 Vishesh Handa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef KFILEMETADATA_EXTRACTOR_P_H #define KFILEMETADATA_EXTRACTOR_P_H namespace KFileMetaData { class ExtractorPlugin; -class ExtractorPrivate +class Extractor::ExtractorPrivate { public: - ExtractorPlugin *m_plugin; + + ExtractorPlugin *m_plugin = nullptr; + + ExtractorPluginOwnership m_autoDeletePlugin = AutoDeletePlugin; + }; } #endif diff --git a/src/extractorcollection.cpp b/src/extractorcollection.cpp index e61d47b..91876bc 100644 --- a/src/extractorcollection.cpp +++ b/src/extractorcollection.cpp @@ -1,165 +1,166 @@ /* * * Copyright (C) 2012 Vishesh Handa * Copyright (C) 2016 Varun Joshi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "extractor.h" #include "extractorplugin.h" #include "extractorcollection.h" -#include "extractor_p.h" #include "externalextractor.h" #include #include #include #include #include #include "config-kfilemetadata.h" using namespace KFileMetaData; class Q_DECL_HIDDEN ExtractorCollection::Private { public: QHash m_extractors; QList m_allExtractors; QList allExtractors() const; }; ExtractorCollection::ExtractorCollection() : d(new Private) { d->m_allExtractors = d->allExtractors(); foreach (Extractor* ex, d->m_allExtractors) { foreach (const QString& type, ex->mimetypes()) { d->m_extractors.insertMulti(type, ex); } } } ExtractorCollection::~ExtractorCollection() { qDeleteAll(d->m_allExtractors.begin(), d->m_allExtractors.end()); delete d; } QList ExtractorCollection::Private::allExtractors() const { QStringList plugins; QStringList pluginPaths; QStringList externalPlugins; QStringList externalPluginPaths; QStringList paths = QCoreApplication::libraryPaths(); Q_FOREACH (const QString& libraryPath, paths) { QString path(libraryPath + QStringLiteral("/kf5/kfilemetadata")); QDir dir(path); if (!dir.exists()) { continue; } QStringList entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); Q_FOREACH (const QString& fileName, entryList) { // Make sure the same plugin is not loaded twice, even if it is // installed in two different locations if (plugins.contains(fileName)) continue; plugins << fileName; pluginPaths << dir.absoluteFilePath(fileName); } } plugins.clear(); QDir externalPluginDir(QStringLiteral(LIBEXEC_INSTALL_DIR) + QStringLiteral("/kfilemetadata/externalextractors")); // For external plugins, we look into the directories QStringList externalPluginEntryList = externalPluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); Q_FOREACH (const QString& externalPlugin, externalPluginEntryList) { if (externalPlugins.contains(externalPlugin)) continue; externalPlugins << externalPlugin; externalPluginPaths << externalPluginDir.absoluteFilePath(externalPlugin); } externalPlugins.clear(); QList extractors; Q_FOREACH (const QString& pluginPath, pluginPaths) { QPluginLoader loader(pluginPath); if (!loader.load()) { qWarning() << "Could not create Extractor: " << pluginPath; qWarning() << loader.errorString(); continue; } QObject* obj = loader.instance(); if (obj) { ExtractorPlugin* plugin = qobject_cast(obj); if (plugin) { Extractor* ex= new Extractor; - ex->d->m_plugin = plugin; + ex->setExtractorPlugin(plugin); + ex->setAutoDeletePlugin(Extractor::DoNotDeletePlugin); extractors << ex; } else { qDebug() << "Plugin could not be converted to an ExtractorPlugin"; qDebug() << pluginPath; } } else { qDebug() << "Plugin could not create instance" << pluginPath; } } Q_FOREACH (const QString& externalPluginPath, externalPluginPaths) { ExternalExtractor *plugin = new ExternalExtractor(externalPluginPath); Extractor* extractor = new Extractor; - extractor->d->m_plugin = plugin; + extractor->setExtractorPlugin(plugin); + extractor->setAutoDeletePlugin(Extractor::AutoDeletePlugin); extractors << extractor; } return extractors; } QList ExtractorCollection::fetchExtractors(const QString& mimetype) const { QList plugins = d->m_extractors.values(mimetype); if (plugins.isEmpty()) { QMimeDatabase db; auto type = db.mimeTypeForName(mimetype); auto it = d->m_extractors.constBegin(); for (; it != d->m_extractors.constEnd(); it++) { if (plugins.contains(it.value())) { continue; } if (type.inherits(it.key())) { plugins << it.value(); } } } return plugins; }