bool JsonClientConnection::checkJson(const Json::Value & message, const QString & schemaResource, std::string & errorMessage) { // read the json schema from the resource QResource schemaData(schemaResource); assert(schemaData.isValid()); Json::Reader jsonReader; Json::Value schemaJson; if (!jsonReader.parse(reinterpret_cast<const char *>(schemaData.data()), reinterpret_cast<const char *>(schemaData.data()) + schemaData.size(), schemaJson, false)) { throw std::runtime_error("Schema error: " + jsonReader.getFormattedErrorMessages()) ; } // create schema checker JsonSchemaChecker schema; schema.setSchema(schemaJson); // check the message if (!schema.validate(message)) { const std::list<std::string> & errors = schema.getMessages(); std::stringstream ss; ss << "{"; foreach (const std::string & error, errors) { ss << error << " "; } ss << "}"; errorMessage = ss.str(); return false; } return true; }
void XercesParser::initialiseSchema(XERCES_CPP_NAMESPACE::SAX2XMLReader* reader, const String& schemaName, const String& xmlFilename, const String& resourceGroup) { XERCES_CPP_NAMESPACE_USE; // enable schema use and set validation options reader->setFeature(XMLUni::fgXercesSchema, true); reader->setFeature(XMLUni::fgSAX2CoreValidation, true); reader->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true); // load in the raw schema data RawDataContainer rawSchemaData; // try base filename first, from default resource group try { Logger::getSingleton().logEvent("XercesParser::initialiseSchema - Attempting to load schema from file '" + schemaName + "'."); System::getSingleton().getResourceProvider()->loadRawDataContainer(schemaName, rawSchemaData, d_defaultSchemaResourceGroup); } // oops, no file. Try an alternative instead, using base path and // resource group from the XML file we're going to be processing. catch(InvalidRequestException) { // get path from filename String schemaFilename; size_t pos = xmlFilename.rfind("/"); if (pos == String::npos) pos = xmlFilename.rfind("\\"); if (pos != String::npos) schemaFilename.assign(xmlFilename, 0, pos + 1); // append schema filename schemaFilename += schemaName; // re-try the load operation. Logger::getSingleton().logEvent("XercesParser::initialiseSchema - Attempting to load schema from file '" + schemaFilename + "'."); System::getSingleton().getResourceProvider()->loadRawDataContainer(schemaFilename, rawSchemaData, resourceGroup); } // wrap schema data in a xerces MemBufInputSource object MemBufInputSource schemaData( rawSchemaData.getDataPtr(), static_cast<const unsigned int>(rawSchemaData.getSize()), schemaName.c_str(), false); reader->loadGrammar(schemaData, Grammar::SchemaGrammarType, true); // enable grammar reuse reader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true); // set schema for usage XMLCh* pval = XMLString::transcode(schemaName.c_str()); reader->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval); XMLString::release(&pval); Logger::getSingleton().logEvent("XercesParser::initialiseSchema - XML schema file '" + schemaName + "' has been initialised."); // use resource provider to release loaded schema data (if it supports this) System::getSingleton().getResourceProvider()->unloadRawDataContainer(rawSchemaData); }
Json::Value loadConfig(const std::string & configFile) { // make sure the resources are loaded (they may be left out after static linking) Q_INIT_RESOURCE(resource); // read the json schema from the resource QResource schemaData(":/hyperion-schema"); assert(schemaData.isValid()); Json::Reader jsonReader; Json::Value schemaJson; if (!jsonReader.parse(reinterpret_cast<const char *>(schemaData.data()), reinterpret_cast<const char *>(schemaData.data()) + schemaData.size(), schemaJson, false)) { throw std::runtime_error("Schema error: " + jsonReader.getFormattedErrorMessages()) ; } JsonSchemaChecker schemaChecker; schemaChecker.setSchema(schemaJson); const Json::Value jsonConfig = JsonFactory::readJson(configFile); schemaChecker.validate(jsonConfig); return jsonConfig; }
bool loadConfig(const QString & configFile) { // make sure the resources are loaded (they may be left out after static linking) Q_INIT_RESOURCE(resource); QJsonParseError error; //////////////////////////////////////////////////////////// // read and set the json schema from the resource //////////////////////////////////////////////////////////// QFile schemaData(":/hyperion-schema"); if (!schemaData.open(QIODevice::ReadOnly)) { std::stringstream error; error << "Schema not found: " << schemaData.errorString().toStdString(); throw std::runtime_error(error.str()); } QByteArray schema = schemaData.readAll(); QJsonDocument schemaJson = QJsonDocument::fromJson(schema, &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,schema.size()); i<count; ++i ) { ++errorColumn; if(schema.at(i) == '\n' ) { errorColumn = 0; ++errorLine; } } std::stringstream sstream; sstream << "Schema error: " << error.errorString().toStdString() << " at Line: " << errorLine << ", Column: " << errorColumn; throw std::runtime_error(sstream.str()); } QJsonSchemaChecker schemaChecker; schemaChecker.setSchema(schemaJson.object()); //////////////////////////////////////////////////////////// // read and validate the configuration file from the command line //////////////////////////////////////////////////////////// const QJsonObject jsonConfig = QJsonFactory::readJson(configFile); if (!schemaChecker.validate(jsonConfig)) { for (std::list<std::string>::const_iterator i = schemaChecker.getMessages().begin(); i != schemaChecker.getMessages().end(); ++i) { std::cout << *i << std::endl; } std::cout << "FAILED" << std::endl; exit(1); return false; } return true; }