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