File indexing completed on 2025-06-29 04:46:12
0001 /* 0002 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "jsonldfilterengine.h" 0008 #include "jsonld.h" 0009 0010 #include <QJsonArray> 0011 #include <QJsonObject> 0012 0013 #include <cstring> 0014 0015 using namespace KItinerary; 0016 0017 void KItinerary::JsonLd::renameProperty(QJsonObject &obj, const char *oldName, const char *newName) 0018 { 0019 const auto value = obj.value(QLatin1StringView(oldName)); 0020 if (!value.isUndefined() && !obj.contains(QLatin1StringView(newName))) { 0021 obj.insert(QLatin1StringView(newName), value); 0022 obj.remove(QLatin1StringView(oldName)); 0023 } 0024 } 0025 0026 JsonLdFilterEngine::JsonLdFilterEngine() = default; 0027 JsonLdFilterEngine::~JsonLdFilterEngine() = default; 0028 0029 void JsonLdFilterEngine::filterRecursive(QJsonObject &obj) 0030 { 0031 auto type = JsonLd::typeName(obj).toUtf8(); 0032 0033 // normalize type 0034 if (m_typeMappings) { 0035 const auto it = std::lower_bound(m_typeMappings, m_typeMappings + m_typeMappingsSize, type, [](const auto &lhs, const auto &rhs) { 0036 return std::strcmp(lhs.fromType, rhs.constData()) < 0; 0037 }); 0038 if (it != (m_typeMappings + m_typeMappingsSize) && std::strcmp((*it).fromType, type.constData()) == 0) { 0039 type = it->toType; 0040 obj.insert(QStringLiteral("@type"), QLatin1StringView(type)); 0041 } 0042 } 0043 0044 for (auto it = obj.begin(); it != obj.end(); ++it) { 0045 if ((*it).type() == QJsonValue::Object) { 0046 QJsonObject subObj = (*it).toObject(); 0047 filterRecursive(subObj); 0048 *it = subObj; 0049 } else if ((*it).type() == QJsonValue::Array) { 0050 QJsonArray array = (*it).toArray(); 0051 filterRecursive(array); 0052 *it = array; 0053 } 0054 } 0055 0056 // rename properties 0057 if (m_propertyMappings) { 0058 const auto [pBegin, pEnd] = std::equal_range(m_propertyMappings, m_propertyMappings + m_propertyMappingsSize, type, [](const auto &lhs, const auto &rhs) { 0059 if constexpr (std::is_same_v<std::decay_t<decltype(lhs)>, QByteArray>) { 0060 return std::strcmp(lhs.constData(), rhs.type) < 0; 0061 } else { 0062 return std::strcmp(lhs.type, rhs.constData()) < 0; 0063 } 0064 }); 0065 for (auto it = pBegin; it != pEnd; ++it) { 0066 JsonLd::renameProperty(obj, (*it).fromName, (*it).toName); 0067 } 0068 } 0069 0070 // apply filter functions 0071 if (m_typeFilters) { 0072 const auto filterIt = std::lower_bound(m_typeFilters, m_typeFilters + m_typeFiltersSize, type, [](const auto &lhs, const auto &rhs) { 0073 return std::strcmp(lhs.type, rhs.constData()) < 0; 0074 }); 0075 if (filterIt != (m_typeFilters + m_typeFiltersSize) && std::strcmp((*filterIt).type, type.constData()) == 0) { 0076 (*filterIt).filterFunc(obj); 0077 } 0078 } 0079 } 0080 0081 void JsonLdFilterEngine::filterRecursive(QJsonArray &array) 0082 { 0083 for (auto it = array.begin(); it != array.end(); ++it) { 0084 if ((*it).type() == QJsonValue::Object) { 0085 QJsonObject subObj = (*it).toObject(); 0086 filterRecursive(subObj); 0087 *it = subObj; 0088 } else if ((*it).type() == QJsonValue::Array) { 0089 QJsonArray array = (*it).toArray(); 0090 filterRecursive(array); 0091 *it = array; 0092 } 0093 } 0094 } 0095 0096 void JsonLdFilterEngine::setTypeMappings(const JsonLdFilterEngine::TypeMapping *typeMappings, std::size_t count) 0097 { 0098 m_typeMappings = typeMappings; 0099 m_typeMappingsSize = count; 0100 } 0101 0102 void JsonLdFilterEngine::setTypeFilters(const JsonLdFilterEngine::TypeFilter *typeFilters, std::size_t count) 0103 { 0104 m_typeFilters = typeFilters; 0105 m_typeFiltersSize = count; 0106 } 0107 0108 void JsonLdFilterEngine::setPropertyMappings(const JsonLdFilterEngine::PropertyMapping *propertyMappings, std::size_t count) 0109 { 0110 m_propertyMappings = propertyMappings; 0111 m_propertyMappingsSize = count; 0112 }