File indexing completed on 2024-12-15 03:44:59
0001 /* 0002 SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: MIT 0005 */ 0006 0007 #include "product.h" 0008 #include "aggregation.h" 0009 0010 #include <QDebug> 0011 #include <QJsonArray> 0012 #include <QJsonDocument> 0013 #include <QJsonObject> 0014 #include <QSharedData> 0015 #include <QString> 0016 0017 using namespace KUserFeedback::Console; 0018 0019 namespace KUserFeedback { 0020 namespace Console { 0021 class ProductData : public QSharedData 0022 { 0023 public: 0024 QString name; 0025 QVector<SchemaEntry> schema; 0026 QVector<Aggregation> aggregations; 0027 }; 0028 0029 } 0030 } 0031 0032 Product::Product() : d(new ProductData) {} 0033 Product::Product(const Product&) = default; 0034 Product::~Product() = default; 0035 Product& Product::operator=(const Product&) = default; 0036 0037 bool Product::isValid() const 0038 { 0039 return !d->name.isEmpty(); 0040 } 0041 0042 QString Product::name() const 0043 { 0044 return d->name; 0045 } 0046 0047 void Product::setName(const QString& name) 0048 { 0049 d->name = name; 0050 } 0051 0052 QVector<SchemaEntry> Product::schema() const 0053 { 0054 return d->schema; 0055 } 0056 0057 SchemaEntry Product::schemaEntry(const QString& name) const 0058 { 0059 const auto it = std::find_if(d->schema.cbegin(), d->schema.cend(), [name](const auto &entry) { 0060 return entry.name() == name; 0061 }); 0062 if (it == d->schema.cend()) 0063 return {}; 0064 return *it; 0065 } 0066 0067 void Product::setSchema(const QVector<SchemaEntry> &schema) 0068 { 0069 d->schema = schema; 0070 } 0071 0072 QVector<Aggregation> Product::aggregations() const 0073 { 0074 return d->aggregations; 0075 } 0076 0077 void Product::setAggregations(const QVector<Aggregation>& aggregations) 0078 { 0079 d->aggregations = aggregations; 0080 } 0081 0082 void Product::addTemplate(const Product& tpl) 0083 { 0084 // TODO could be done slightly more clever 0085 d->schema += tpl.schema(); 0086 d->aggregations += tpl.aggregations(); 0087 } 0088 0089 QByteArray Product::toJson() const 0090 { 0091 QJsonObject obj; 0092 obj.insert(QStringLiteral("name"), name()); 0093 { 0094 QJsonArray schema; 0095 foreach (const auto &s, d->schema) 0096 schema.push_back(s.toJsonObject()); 0097 obj.insert(QStringLiteral("schema"), schema); 0098 } 0099 0100 { 0101 QJsonArray aggrs; 0102 foreach (const auto &a, d->aggregations) 0103 aggrs.push_back(a.toJsonObject()); 0104 obj.insert(QStringLiteral("aggregation"), aggrs); 0105 } 0106 QJsonDocument doc(obj); 0107 return doc.toJson(); 0108 } 0109 0110 static Product productFromJsonObject(const QJsonObject &obj) 0111 { 0112 Product product; 0113 product.setName(obj.value(QStringLiteral("name")).toString()); 0114 product.setSchema(SchemaEntry::fromJson(obj.value(QStringLiteral("schema")).toArray())); 0115 product.setAggregations(Aggregation::fromJson(product, obj.value(QLatin1String("aggregation")).toArray())); 0116 return product; 0117 } 0118 0119 QVector<Product> Product::fromJson(const QByteArray &data) 0120 { 0121 QVector<Product> products; 0122 QJsonParseError error; 0123 const auto doc = QJsonDocument::fromJson(data, &error); 0124 if (doc.isArray()) { 0125 const auto array = doc.array(); 0126 products.reserve(array.size()); 0127 foreach (const auto &value, array) { 0128 const auto obj = value.toObject(); 0129 products.push_back(productFromJsonObject(obj)); 0130 } 0131 } else if (doc.isObject()) { 0132 products.push_back(productFromJsonObject(doc.object())); 0133 } else { 0134 qDebug() << "Failed to parse product JSON:" << error.errorString() << error.offset; 0135 } 0136 return products; 0137 }