From 33b0532e5281e2de0eae144ccc5ffe40c5ad6c7f Mon Sep 17 00:00:00 2001 From: Philipp Kewisch Date: Wed, 24 Oct 2012 15:13:22 +0200 Subject: [PATCH 1/2] Issue #53 - Add initial support for lookups via json pointer --- lib/jsv.js | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/jsv.js b/lib/jsv.js index 1ca04ae..c24d450 100644 --- a/lib/jsv.js +++ b/lib/jsv.js @@ -243,6 +243,20 @@ var exports = exports || this, return o.toString(); } } + + function traversePointer(obj, pointer) { + if (pointer !== "/") { + var parr = pointer.split("/").slice(1); + for (var part = parr.shift(); part; part = parr.shift()) { + if (obj.hasOwnProperty(part)) { + obj = obj[part]; + } else { + return null; + } + } + } + return obj; + } /** * The exception that is thrown when a schema fails to be created. @@ -814,10 +828,10 @@ var exports = exports || this, } if (this._env._options["validateReferences"] && this._refs) { - if (this._refs["describedby"] && !this._env.findSchema(this._refs["describedby"])) { + if (this._refs["describedby"] && !this._env.findSchema(this._refs["describedby"], parentSchema)) { report.addError(this, this._schema, "{describedby}", "Unknown schema reference", this._refs["describedby"]); } - if (this._refs["full"] && !this._env.findSchema(this._refs["full"])) { + if (this._refs["full"] && !this._env.findSchema(this._refs["full"], parentSchema)) { report.addError(this, this._schema, "{full}", "Unknown schema reference", this._refs["full"]); } } @@ -1055,11 +1069,23 @@ var exports = exports || this, * Returns the schema registered with the provided URI. * * @param {String} uri The absolute URI of the required schema + * @param {JSONSchema} [parentSchema] The schema of the parent/containing instance, used in case the schema is referenced by JSON pointer. * @returns {JSONSchema|undefined} The request schema, or undefined if not found */ - Environment.prototype.findSchema = function (uri) { - return this._schemas[formatURI(uri)]; + Environment.prototype.findSchema = function (uri, parentSchema) { + var furi = formatURI(uri); + var schema = null; + if (furi in this._schemas) { + schema = this._schemas[furi]; + } else if (parentSchema) { + var fragment = furi.substr(furi.indexOf("#")); + var targetElem = traversePointer(parentSchema.getValue(), fragment); + if (targetElem) { + schema = this.createSchema(targetElem, null); + } + } + return schema; }; /** @@ -1494,4 +1520,4 @@ var exports = exports || this, require("./environments"); //load default environments -}()); \ No newline at end of file +}()); From baf6302ffc6213d47b67877d7e9e9ec59fbabf64 Mon Sep 17 00:00:00 2001 From: Philipp Kewisch Date: Thu, 25 Oct 2012 15:36:53 +0200 Subject: [PATCH 2/2] Issue #53 - Fix lookup to correctly find the base node --- lib/jsv.js | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/jsv.js b/lib/jsv.js index c24d450..1441fa7 100644 --- a/lib/jsv.js +++ b/lib/jsv.js @@ -828,10 +828,10 @@ var exports = exports || this, } if (this._env._options["validateReferences"] && this._refs) { - if (this._refs["describedby"] && !this._env.findSchema(this._refs["describedby"], parentSchema)) { + if (this._refs["describedby"] && !this._env.findSchema(this._refs["describedby"])) { report.addError(this, this._schema, "{describedby}", "Unknown schema reference", this._refs["describedby"]); } - if (this._refs["full"] && !this._env.findSchema(this._refs["full"], parentSchema)) { + if (this._refs["full"] && !this._env.findSchema(this._refs["full"])) { report.addError(this, this._schema, "{full}", "Unknown schema reference", this._refs["full"]); } } @@ -1073,19 +1073,25 @@ var exports = exports || this, * @returns {JSONSchema|undefined} The request schema, or undefined if not found */ - Environment.prototype.findSchema = function (uri, parentSchema) { - var furi = formatURI(uri); - var schema = null; - if (furi in this._schemas) { - schema = this._schemas[furi]; - } else if (parentSchema) { - var fragment = furi.substr(furi.indexOf("#")); - var targetElem = traversePointer(parentSchema.getValue(), fragment); - if (targetElem) { - schema = this.createSchema(targetElem, null); - } - } - return schema; + Environment.prototype.findSchema = function (uri) { + var furi = formatURI(uri); + var schema = null; + if (furi in this._schemas) { + schema = this._schemas[furi]; + } else { + var base = furi.substr(0, furi.indexOf("#")); + if (formatURI(base) != furi) { + var baseSchema = this.findSchema(base); + if (baseSchema) { + var fragment = furi.substr(base.length); + var targetElem = traversePointer(baseSchema.getValue(), fragment); + if (targetElem) { + schema = this.createSchema(targetElem, null, furi); + } + } + } + } + return schema; }; /**