##// END OF EJS Templates
Parser refactoring (3)...
Parser refactoring (3) Implements properties reading and properties checking Implementation takes some of the basic parser, which will be deleted at the end

File last commit:

r412:e1f4801c4363
r935:b93a3fb4e7f2
Show More
AmdaParser.cpp
125 lines | 4.2 KiB | text/x-c | CppLexer
Alexandre Leroux
Creates JSON parser
r354 #include "AmdaParser.h"
Alexandre Leroux
Amda provider update (1)...
r412 #include "AmdaDefs.h"
Alexandre Leroux
Creates JSON parser
r354
#include <DataSource/DataSourceItem.h>
Alexandre Leroux
AMDA parser (1)...
r355 #include <QFile>
Alexandre Leroux
AMDA parser (1)...
r356 #include <QJsonArray>
Alexandre Leroux
AMDA parser (1)...
r355 #include <QJsonDocument>
#include <QJsonObject>
Alexandre Leroux
Creates JSON parser
r354 Q_LOGGING_CATEGORY(LOG_AmdaParser, "AmdaParser")
Alexandre Leroux
AMDA parser (1)...
r355 namespace {
Alexandre Leroux
AMDA parser (1)...
r356 /// Returns the correct item type according to the key passed in parameter
DataSourceItemType itemType(const QString &key) noexcept
{
Alexandre Leroux
Amda provider update (1)...
r412 if (key == AMDA_PRODUCT_KEY) {
Alexandre Leroux
AMDA parser (1)...
r356 return DataSourceItemType::PRODUCT;
}
Alexandre Leroux
Amda provider update (1)...
r412 else if (key == AMDA_COMPONENT_KEY) {
Alexandre Leroux
AMDA parser (1)...
r356 return DataSourceItemType::COMPONENT;
}
else {
return DataSourceItemType::NODE;
}
}
/**
* Processes an entry of the JSON file to populate/create data source items
* @param jsonKey the entry's key
* @param jsonValue the entry's value
* @param item the current item for which the entry processing will be applied
* @param appendData flag indicating that the entry is part of an array. In the case of an array of
* values, each value will be concatenated to the others (rather than replacing the others)
*/
void parseEntry(const QString &jsonKey, const QJsonValue &jsonValue, DataSourceItem &item,
bool isArrayEntry = false)
{
if (jsonValue.isObject()) {
// Case of an object:
// - a new data source item is created and
// - parsing is called recursively to process the new item
// - the new item is then added as a child of the former item
auto object = jsonValue.toObject();
auto newItem = std::make_unique<DataSourceItem>(itemType(jsonKey));
for (auto it = object.constBegin(), end = object.constEnd(); it != end; ++it) {
parseEntry(it.key(), it.value(), *newItem);
}
item.appendChild(std::move(newItem));
}
else if (jsonValue.isArray()) {
// Case of an array: the item is populated with the arrays' content
auto object = jsonValue.toArray();
for (auto it = object.constBegin(), end = object.constEnd(); it != end; ++it) {
parseEntry(jsonKey, *it, item, true);
}
}
else {
// Case of a simple value: we add a data to the item. If the simple value is a part of an
// array, it is concatenated to the values already existing for this key
item.setData(jsonKey, jsonValue.toVariant(), isArrayEntry);
}
}
Alexandre Leroux
AMDA parser (1)...
r355 } // namespace
Alexandre Leroux
Creates JSON parser
r354 std::unique_ptr<DataSourceItem> AmdaParser::readJson(const QString &filePath) noexcept
{
Alexandre Leroux
AMDA parser (1)...
r355 QFile jsonFile{filePath};
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCCritical(LOG_AmdaParser())
<< QObject::tr("Can't retrieve data source tree from file %1: %2")
.arg(filePath, jsonFile.errorString());
return nullptr;
}
auto json = jsonFile.readAll();
auto jsonDocument = QJsonDocument::fromJson(json);
// Check preconditions for parsing
if (!jsonDocument.isObject()) {
qCCritical(LOG_AmdaParser())
<< QObject::tr(
"Can't retrieve data source tree from file %1: the file is malformed (there is "
"not one and only one root object)")
.arg(filePath);
return nullptr;
}
auto jsonDocumentObject = jsonDocument.object();
Alexandre Leroux
Amda provider update (1)...
r412 if (!jsonDocumentObject.contains(AMDA_ROOT_KEY)) {
Alexandre Leroux
AMDA parser (1)...
r355 qCCritical(LOG_AmdaParser())
<< QObject::tr(
"Can't retrieve data source tree from file %1: the file is malformed (the key "
"for the root element was not found (%2))")
Alexandre Leroux
Amda provider update (1)...
r412 .arg(filePath, AMDA_ROOT_KEY);
Alexandre Leroux
AMDA parser (1)...
r355 return nullptr;
}
Alexandre Leroux
Amda provider update (1)...
r412 auto rootValue = jsonDocumentObject.value(AMDA_ROOT_KEY);
Alexandre Leroux
AMDA parser (1)...
r355 if (!rootValue.isObject()) {
qCCritical(LOG_AmdaParser())
<< QObject::tr(
"Can't retrieve data source tree from file %1: the file is malformed (the root "
"element is of the wrong type)")
.arg(filePath);
return nullptr;
}
Alexandre Leroux
AMDA parser (1)...
r356
// Makes the parsing
auto rootObject = rootValue.toObject();
auto rootItem = std::make_unique<DataSourceItem>(DataSourceItemType::NODE);
for (auto it = rootObject.constBegin(), end = rootObject.constEnd(); it != end; ++it) {
parseEntry(it.key(), it.value(), *rootItem);
}
return rootItem;
Alexandre Leroux
Creates JSON parser
r354 }