#pragma once #include <iostream> #include <string> #include <stdexcept> #include <sstream> // JSON-Schema includes #include <utils/jsonschema/QJsonSchemaChecker.h> #include <QFile> #include <QString> #include <QJsonObject> #include <QJsonDocument> #include <QRegularExpression> class QJsonFactory { public: static int load(const QString& schema, const QString& config, QJsonObject& json) { // Load the schema and the config trees QJsonObject schemaTree = readJson(schema); QJsonObject configTree = readJson(config); // create the validator QJsonSchemaChecker schemaChecker; schemaChecker.setSchema(schemaTree); bool valid = schemaChecker.validate(configTree); for (std::list<std::string>::const_iterator i = schemaChecker.getMessages().begin(); i != schemaChecker.getMessages().end(); ++i) { std::cout << *i << std::endl; } if (!valid) { std::cerr << "Validation failed for configuration file: " << config.toStdString() << std::endl; return -3; } json = configTree; return 0; } static QJsonObject readJson(const QString& path) { QFile file(path); QJsonParseError error; if (!file.open(QIODevice::ReadOnly)) { std::stringstream sstream; sstream << "Configuration file not found: " << file.errorString().toStdString(); throw std::runtime_error(sstream.str()); } QString config = QString(file.readAll()); config.remove(QRegularExpression("([^:]?\\/\\/.*)")); QJsonDocument doc = QJsonDocument::fromJson(config.toUtf8(), &error); if (error.error != QJsonParseError::NoError) { // report to the user the failure and their locations in the document. int errorLine(0), errorColumn(0); for( int i=0, count=qMin( error.offset,config.size()); i<count; ++i ) { ++errorColumn; if(config.at(i) == '\n' ) { errorColumn = 0; ++errorLine; } } std::stringstream sstream; sstream << "Failed to parse configuration: " << error.errorString().toStdString() << " at Line: " << errorLine << ", Column: " << errorColumn; throw std::runtime_error(sstream.str()); } file.close(); return doc.object(); } };