File indexing completed on 2024-06-16 10:41:44

0001 /* This file is part of the KDE project
0002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
0003    Copyright (C) 2007 David Faure <faure@kde.org>
0004    Copyright (C) 2015 Jarosław Staniek <staniek@kde.org>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "KDbJsonTrader_p.h"
0023 #include "KDb.h"
0024 #include "kdb_debug.h"
0025 
0026 #include <QList>
0027 #include <QPluginLoader>
0028 #include <QJsonObject>
0029 #include <QJsonArray>
0030 #include <QDirIterator>
0031 #include <QDir>
0032 #include <QCoreApplication>
0033 
0034 Q_GLOBAL_STATIC(KDbJsonTrader, KDbJsonTrader_instance)
0035 
0036 class Q_DECL_HIDDEN KDbJsonTrader::Private
0037 {
0038 public:
0039     Private() : pluginPathFound(false)
0040     {
0041     }
0042     bool pluginPathFound;
0043     QStringList pluginPaths;
0044 private:
0045     Q_DISABLE_COPY(Private)
0046 };
0047 
0048 // ---
0049 
0050 KDbJsonTrader::KDbJsonTrader()
0051     : d(new Private)
0052 {
0053     Q_ASSERT(!KDbJsonTrader_instance.exists());
0054 }
0055 
0056 KDbJsonTrader::~KDbJsonTrader()
0057 {
0058     delete d;
0059 }
0060 
0061 KDbJsonTrader* KDbJsonTrader::self()
0062 {
0063     return KDbJsonTrader_instance;
0064 }
0065 
0066 //! Checks loader @a loader
0067 static bool checkLoader(QPluginLoader *loader, const QString &servicetype,
0068                         const QString &mimetype)
0069 {
0070     QJsonObject json = loader->metaData().value(QLatin1String("MetaData")).toObject();
0071     if (json.isEmpty()) {
0072         //kdbDebug() << dirIter.filePath() << "has no json!";
0073         return false;
0074     }
0075     QJsonObject pluginData = json.value(QLatin1String("KPlugin")).toObject();
0076     if (!pluginData.value(QLatin1String("ServiceTypes")).toArray()
0077             .contains(QJsonValue(servicetype)))
0078     {
0079         return false;
0080     }
0081 
0082     if (!mimetype.isEmpty()) {
0083         QStringList mimeTypes
0084                 = json.value(QLatin1String("MimeType")).toString().split(QLatin1Char(';'));
0085         mimeTypes += json.value(QLatin1String("X-KDE-NativeMimeType")).toString();
0086         if (! mimeTypes.contains(mimetype)) {
0087             return false;
0088         }
0089     }
0090     return true;
0091 }
0092 
0093 static QList<QPluginLoader *> findPlugins(const QString &path, const QString &servicetype,
0094                                           const QString &mimetype)
0095 {
0096     QList<QPluginLoader*> list;
0097     QDirIterator dirIter(path, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
0098     while (dirIter.hasNext()) {
0099         dirIter.next();
0100         if (dirIter.fileInfo().isFile()) {
0101             QPluginLoader *loader = new QPluginLoader(dirIter.filePath());
0102             if (checkLoader(loader, servicetype, mimetype)) {
0103                 list.append(loader);
0104             } else {
0105                 delete loader;
0106             }
0107         }
0108     }
0109     return list;
0110 }
0111 
0112 QList<QPluginLoader *> KDbJsonTrader::query(const QString &servicetype,
0113                                             const QString &mimetype)
0114 {
0115     if (!d->pluginPathFound) {
0116         d->pluginPaths = KDb::libraryPaths();
0117     }
0118 
0119     QList<QPluginLoader *> list;
0120     foreach(const QString &path, d->pluginPaths) {
0121         list += findPlugins(path, servicetype, mimetype);
0122     }
0123     return list;
0124 }