File indexing completed on 2024-04-28 15:29:53

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2000 Torben Weis <weis@kde.org>
0004     SPDX-FileCopyrightText: 2006 David Faure <faure@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "kservicetypetrader.h"
0010 
0011 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90)
0012 
0013 #include "kservicefactory_p.h"
0014 #include "kservicetype.h"
0015 #include "kservicetypefactory_p.h"
0016 #include "ksycoca.h"
0017 #include "ksycoca_p.h"
0018 #include "ktraderparsetree_p.h"
0019 #include <kservicetypeprofile.h>
0020 
0021 #include "servicesdebug.h"
0022 
0023 using namespace KTraderParse;
0024 
0025 // --------------------------------------------------
0026 
0027 namespace KServiceTypeProfile
0028 {
0029 KServiceOfferList sortServiceTypeOffers(const KServiceOfferList &list, const QString &servicetype);
0030 }
0031 
0032 class KServiceTypeTraderSingleton
0033 {
0034 public:
0035     KServiceTypeTrader instance;
0036 };
0037 
0038 Q_GLOBAL_STATIC(KServiceTypeTraderSingleton, s_globalServiceTypeTrader)
0039 
0040 KServiceTypeTrader *KServiceTypeTrader::self()
0041 {
0042     return &s_globalServiceTypeTrader()->instance;
0043 }
0044 
0045 KServiceTypeTrader::KServiceTypeTrader()
0046     : d(nullptr)
0047 {
0048 }
0049 
0050 KServiceTypeTrader::~KServiceTypeTrader()
0051 {
0052 }
0053 
0054 // shared with KMimeTypeTrader
0055 void KServiceTypeTrader::applyConstraints(KService::List &lst, const QString &constraint)
0056 {
0057     if (lst.isEmpty() || constraint.isEmpty()) {
0058         return;
0059     }
0060 
0061     const ParseTreeBase::Ptr constr = parseConstraints(constraint); // for ownership
0062     const ParseTreeBase *pConstraintTree = constr.data(); // for speed
0063 
0064     if (!constr) { // parse error
0065         lst.clear();
0066     } else {
0067         // Find all services matching the constraint
0068         // and remove the other ones
0069         auto isMatch = [=](const KService::Ptr &service) {
0070             return matchConstraint(pConstraintTree, service, lst) != 1;
0071         };
0072 
0073         lst.erase(std::remove_if(lst.begin(), lst.end(), isMatch), lst.end());
0074     }
0075 }
0076 
0077 KServiceOfferList KServiceTypeTrader::weightedOffers(const QString &serviceType) // static, internal
0078 {
0079     // qDebug() << "KServiceTypeTrader::weightedOffers( " << serviceType << " )";
0080 
0081     KSycoca::self()->ensureCacheValid();
0082     KServiceType::Ptr servTypePtr = KSycocaPrivate::self()->serviceTypeFactory()->findServiceTypeByName(serviceType);
0083     if (!servTypePtr) {
0084         qCWarning(SERVICES) << "KServiceTypeTrader: serviceType" << serviceType << "not found";
0085         return KServiceOfferList();
0086     }
0087     if (servTypePtr->serviceOffersOffset() == -1) { // no offers in ksycoca
0088         return KServiceOfferList();
0089     }
0090 
0091     // First, get all offers known to ksycoca.
0092     const KServiceOfferList services = KSycocaPrivate::self()->serviceFactory()->offers(servTypePtr->offset(), servTypePtr->serviceOffersOffset());
0093 
0094     const KServiceOfferList offers = KServiceTypeProfile::sortServiceTypeOffers(services, serviceType);
0095 
0096     return offers;
0097 }
0098 
0099 KService::List KServiceTypeTrader::defaultOffers(const QString &serviceType, const QString &constraint) const
0100 {
0101     KSycoca::self()->ensureCacheValid();
0102     KServiceType::Ptr servTypePtr = KSycocaPrivate::self()->serviceTypeFactory()->findServiceTypeByName(serviceType);
0103     if (!servTypePtr) {
0104         qCWarning(SERVICES) << "KServiceTypeTrader: serviceType" << serviceType << "not found";
0105         return KService::List();
0106     }
0107     if (servTypePtr->serviceOffersOffset() == -1) {
0108         return KService::List();
0109     }
0110 
0111     KService::List lst = KSycocaPrivate::self()->serviceFactory()->serviceOffers(servTypePtr->offset(), servTypePtr->serviceOffersOffset());
0112 
0113     applyConstraints(lst, constraint);
0114 
0115     // qDebug() << "query for serviceType " << serviceType << constraint
0116     //             << " : returning " << lst.count() << " offers" << endl;
0117     return lst;
0118 }
0119 
0120 KService::List KServiceTypeTrader::query(const QString &serviceType, const QString &constraint) const
0121 {
0122     if (!KServiceTypeProfile::hasProfile(serviceType)) {
0123         // Fast path: skip the profile stuff if there's none (to avoid kservice->serviceoffer->kservice)
0124         // The ordering according to initial preferences is done by kbuildsycoca
0125         return defaultOffers(serviceType, constraint);
0126     }
0127 
0128     // Get all services of this service type.
0129     const KServiceOfferList offers = weightedOffers(serviceType);
0130     KService::List lst;
0131     lst.reserve(offers.size());
0132 
0133     // Now extract only the services; the weighting was only used for sorting.
0134     std::transform(offers.cbegin(), offers.cend(), std::back_inserter(lst), [](const KServiceOffer &offer) {
0135         return offer.service();
0136     });
0137 
0138     applyConstraints(lst, constraint);
0139 
0140     // qDebug() << "query for serviceType " << serviceType << constraint
0141     //             << " : returning " << lst.count() << " offers" << endl;
0142     return lst;
0143 }
0144 
0145 KService::Ptr KServiceTypeTrader::preferredService(const QString &serviceType) const
0146 {
0147     const KServiceOfferList offers = weightedOffers(serviceType);
0148 
0149     KServiceOfferList::const_iterator itOff = offers.begin();
0150 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 67)
0151     // Look for the first one that is allowed as default.
0152     // Since the allowed-as-default are first anyway, we only have
0153     // to look at the first one to know.
0154     if (itOff != offers.end() && (*itOff).allowAsDefault()) {
0155 #else
0156     if (itOff != offers.end()) {
0157 #endif
0158         return (*itOff).service();
0159     }
0160 
0161     // qDebug() << "No offers, or none allowed as default";
0162     return KService::Ptr();
0163 }
0164 
0165 #endif