##// END OF EJS Templates
AMDA parser (1)...
Alexandre Leroux -
r356:62b101728035
parent child
Show More
@@ -1,63 +1,129
1 1 #include "AmdaParser.h"
2 2
3 3 #include <DataSource/DataSourceItem.h>
4 4
5 5 #include <QFile>
6 #include <QJsonArray>
6 7 #include <QJsonDocument>
7 8 #include <QJsonObject>
8 9
9 10 Q_LOGGING_CATEGORY(LOG_AmdaParser, "AmdaParser")
10 11
11 12 namespace {
12 13
13 14 // Significant keys of an AMDA's JSON file
15 const auto COMPONENT_KEY = QStringLiteral("component");
16 const auto PRODUCT_KEY = QStringLiteral("parameter");
14 17 const auto ROOT_KEY = QStringLiteral("dataCenter");
15 18
19 /// Returns the correct item type according to the key passed in parameter
20 DataSourceItemType itemType(const QString &key) noexcept
21 {
22 if (key == PRODUCT_KEY) {
23 return DataSourceItemType::PRODUCT;
24 }
25 else if (key == COMPONENT_KEY) {
26 return DataSourceItemType::COMPONENT;
27 }
28 else {
29 return DataSourceItemType::NODE;
30 }
31 }
32
33 /**
34 * Processes an entry of the JSON file to populate/create data source items
35 * @param jsonKey the entry's key
36 * @param jsonValue the entry's value
37 * @param item the current item for which the entry processing will be applied
38 * @param appendData flag indicating that the entry is part of an array. In the case of an array of
39 * values, each value will be concatenated to the others (rather than replacing the others)
40 */
41 void parseEntry(const QString &jsonKey, const QJsonValue &jsonValue, DataSourceItem &item,
42 bool isArrayEntry = false)
43 {
44 if (jsonValue.isObject()) {
45 // Case of an object:
46 // - a new data source item is created and
47 // - parsing is called recursively to process the new item
48 // - the new item is then added as a child of the former item
49 auto object = jsonValue.toObject();
50
51 auto newItem = std::make_unique<DataSourceItem>(itemType(jsonKey));
52
53 for (auto it = object.constBegin(), end = object.constEnd(); it != end; ++it) {
54 parseEntry(it.key(), it.value(), *newItem);
55 }
56
57 item.appendChild(std::move(newItem));
58 }
59 else if (jsonValue.isArray()) {
60 // Case of an array: the item is populated with the arrays' content
61 auto object = jsonValue.toArray();
62
63 for (auto it = object.constBegin(), end = object.constEnd(); it != end; ++it) {
64 parseEntry(jsonKey, *it, item, true);
65 }
66 }
67 else {
68 // Case of a simple value: we add a data to the item. If the simple value is a part of an
69 // array, it is concatenated to the values already existing for this key
70 item.setData(jsonKey, jsonValue.toVariant(), isArrayEntry);
71 }
72 }
73
16 74 } // namespace
17 75
18 76 std::unique_ptr<DataSourceItem> AmdaParser::readJson(const QString &filePath) noexcept
19 77 {
20 78 QFile jsonFile{filePath};
21 79
22 80 if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
23 81 qCCritical(LOG_AmdaParser())
24 82 << QObject::tr("Can't retrieve data source tree from file %1: %2")
25 83 .arg(filePath, jsonFile.errorString());
26 84 return nullptr;
27 85 }
28 86
29 87 auto json = jsonFile.readAll();
30 88 auto jsonDocument = QJsonDocument::fromJson(json);
31 89
32 90 // Check preconditions for parsing
33 91 if (!jsonDocument.isObject()) {
34 92 qCCritical(LOG_AmdaParser())
35 93 << QObject::tr(
36 94 "Can't retrieve data source tree from file %1: the file is malformed (there is "
37 95 "not one and only one root object)")
38 96 .arg(filePath);
39 97 return nullptr;
40 98 }
41 99
42 100 auto jsonDocumentObject = jsonDocument.object();
43 101 if (!jsonDocumentObject.contains(ROOT_KEY)) {
44 102 qCCritical(LOG_AmdaParser())
45 103 << QObject::tr(
46 104 "Can't retrieve data source tree from file %1: the file is malformed (the key "
47 105 "for the root element was not found (%2))")
48 106 .arg(filePath, ROOT_KEY);
49 107 return nullptr;
50 108 }
51 109
52 110 auto rootValue = jsonDocumentObject.value(ROOT_KEY);
53 111 if (!rootValue.isObject()) {
54 112 qCCritical(LOG_AmdaParser())
55 113 << QObject::tr(
56 114 "Can't retrieve data source tree from file %1: the file is malformed (the root "
57 115 "element is of the wrong type)")
58 116 .arg(filePath);
59 117 return nullptr;
60 118 }
61 /// @todo ALX
62 return nullptr;
119
120 // Makes the parsing
121 auto rootObject = rootValue.toObject();
122 auto rootItem = std::make_unique<DataSourceItem>(DataSourceItemType::NODE);
123
124 for (auto it = rootObject.constBegin(), end = rootObject.constEnd(); it != end; ++it) {
125 parseEntry(it.key(), it.value(), *rootItem);
126 }
127
128 return rootItem;
63 129 }
General Comments 0
You need to be logged in to leave comments. Login now