2016-07-20 17:16:06 +02:00
# pragma once
# include <iostream>
# include <stdexcept>
// 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
2017-01-23 23:25:12 +01:00
QJsonObject schemaTree = readSchema ( schema ) ;
QJsonObject configTree = readConfig ( config ) ;
2016-07-20 17:16:06 +02:00
// create the validator
QJsonSchemaChecker schemaChecker ;
schemaChecker . setSchema ( schemaTree ) ;
bool valid = schemaChecker . validate ( configTree ) ;
2017-03-04 22:17:42 +01:00
QStringList messages = schemaChecker . getMessages ( ) ;
for ( int i = 0 ; i < messages . size ( ) ; + + i )
2016-07-20 17:16:06 +02:00
{
2017-03-04 22:17:42 +01:00
std : : cout < < messages [ i ] . toStdString ( ) < < std : : endl ;
2016-07-20 17:16:06 +02:00
}
if ( ! valid )
{
std : : cerr < < " Validation failed for configuration file: " < < config . toStdString ( ) < < std : : endl ;
return - 3 ;
}
json = configTree ;
return 0 ;
}
2017-01-23 23:25:12 +01:00
static QJsonObject readConfig ( const QString & path )
2016-07-20 17:16:06 +02:00
{
QFile file ( path ) ;
QJsonParseError error ;
2017-01-23 23:25:12 +01:00
2016-07-20 17:16:06 +02:00
if ( ! file . open ( QIODevice : : ReadOnly ) )
{
2017-03-04 22:17:42 +01:00
throw std : : runtime_error ( QString ( " Configuration file not found: ' " + path + " ' ( " + file . errorString ( ) + " ) " ) . toStdString ( ) ) ;
2016-07-20 17:16:06 +02:00
}
QString config = QString ( file . readAll ( ) ) ;
config . remove ( QRegularExpression ( " ([^:]? \\ / \\ /.*) " ) ) ;
QJsonDocument doc = QJsonDocument : : fromJson ( config . toUtf8 ( ) , & error ) ;
2017-01-23 23:25:12 +01:00
file . close ( ) ;
2016-07-20 17:16:06 +02:00
if ( error . error ! = QJsonParseError : : NoError )
{
// report to the user the failure and their locations in the document.
int errorLine ( 0 ) , errorColumn ( 0 ) ;
2017-01-23 23:25:12 +01:00
2016-07-20 17:16:06 +02:00
for ( int i = 0 , count = qMin ( error . offset , config . size ( ) ) ; i < count ; + + i )
{
+ + errorColumn ;
if ( config . at ( i ) = = ' \n ' )
{
errorColumn = 0 ;
+ + errorLine ;
}
}
2017-01-23 23:25:12 +01:00
2017-03-04 22:17:42 +01:00
throw std : : runtime_error (
QString ( " Failed to parse configuration: " + error . errorString ( ) + " at Line: " + QString : : number ( errorLine ) + " , Column: " + QString : : number ( errorColumn ) ) . toStdString ( )
) ;
2016-07-20 17:16:06 +02:00
}
2017-01-23 23:25:12 +01:00
return doc . object ( ) ;
}
static QJsonObject readSchema ( const QString & path )
{
QFile schemaData ( path ) ;
QJsonParseError error ;
if ( ! schemaData . open ( QIODevice : : ReadOnly ) )
{
2017-03-04 22:17:42 +01:00
throw std : : runtime_error ( QString ( " Schema not found: ' " + path + " ' ( " + schemaData . errorString ( ) + " ) " ) . toStdString ( ) ) ;
2017-01-23 23:25:12 +01:00
}
QByteArray schema = schemaData . readAll ( ) ;
QJsonDocument doc = QJsonDocument : : fromJson ( schema , & error ) ;
schemaData . close ( ) ;
2016-07-20 17:16:06 +02:00
2017-01-23 23:25:12 +01:00
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 , schema . size ( ) ) ; i < count ; + + i )
{
+ + errorColumn ;
if ( schema . at ( i ) = = ' \n ' )
{
errorColumn = 0 ;
+ + errorLine ;
}
}
2017-03-04 22:17:42 +01:00
throw std : : runtime_error ( QString ( " ERROR: Json schema wrong: " + error . errorString ( ) + " at Line: " + QString : : number ( errorLine )
+ " , Column: " + QString : : number ( errorColumn ) ) . toStdString ( )
) ;
2017-01-23 23:25:12 +01:00
}
2016-07-20 17:16:06 +02:00
return doc . object ( ) ;
}
2016-10-09 22:22:17 +02:00
static void writeJson ( const QString & filename , QJsonObject & jsonTree )
{
QJsonDocument doc ;
doc . setObject ( jsonTree ) ;
QByteArray configData = doc . toJson ( QJsonDocument : : Indented ) ;
QFile configFile ( filename ) ;
configFile . open ( QIODevice : : WriteOnly | QIODevice : : Truncate ) ;
configFile . write ( configData ) ;
configFile . close ( ) ;
}
2016-07-20 17:16:06 +02:00
} ;