Commit fbd9424c authored by Boris Kocherov's avatar Boris Kocherov

add smart detection 'soft circular links'

parent 33371ea6
...@@ -71,19 +71,40 @@ ...@@ -71,19 +71,40 @@
return target; return target;
} }
function checkCircular(g, path, url) { function checkCircular(urls, path, url) {
var required_stack, var required_stack,
idx, idx,
prev_field_path = getMaxPathInDict(g.props.schema_required_urls, path); prev_field_path = getMaxPathInDict(urls, path);
required_stack = g.props.schema_required_urls[prev_field_path] || []; required_stack = urls[prev_field_path] || [];
idx = required_stack.indexOf(url); idx = required_stack.indexOf(url);
if (idx >= 0) { if (idx >= 0) {
if (path === prev_field_path && idx === 0) { if (path === prev_field_path && idx === 0) {
return; return;
} }
throw new Error("Circular reference detected"); return true;
}
// copy and add url as first element
urls[path] = [url].concat(required_stack);
}
function checkHardCircular(g, path, url) {
return checkCircular(g.props.schema_required_urls, path, url);
}
function checkAndMarkSoftCircular(g, schema_arr, path, url) {
var ret = true;
// if schema_arr.length > 1 selection rendered in any case
// so we not need checkCircular and have small optimisation
if (schema_arr.length === 1) {
ret = checkCircular(g.props.schema_urls, path, url);
schema_arr[0].circular = ret;
}
if (ret) {
// if schema_arr.length > 1 selection rendered and loop break
// if circular found selection rendered and loop break
// so we can begin from start
g.props.schema_urls[path] = [];
} }
g.props.schema_required_urls[path] = [url].concat(required_stack);
} }
function convertToRealWorldSchemaPath(g, path) { function convertToRealWorldSchemaPath(g, path) {
...@@ -261,7 +282,9 @@ ...@@ -261,7 +282,9 @@
} }
queue queue
.push(function (json) { .push(function (json) {
checkCircular(g, path, url); if (checkHardCircular(g, path, url)) {
throw new Error("Circular reference detected");
}
return resolveLocalReference(json, hash); return resolveLocalReference(json, hash);
}); });
} }
...@@ -305,12 +328,7 @@ ...@@ -305,12 +328,7 @@
return expandSchema(g, schema_part, path, $ref); return expandSchema(g, schema_part, path, $ref);
}) })
.push(function (schema_arr) { .push(function (schema_arr) {
// if length array > 1 form rendered on demand already checkAndMarkSoftCircular(g, schema_arr, path, url);
// so not needed circular detection
if (schema_arr.length === 1) {
// XXX need smart circular detection in this place
schema_arr[0].circular = true;
}
return schema_arr; return schema_arr;
}); });
} }
...@@ -740,11 +758,19 @@ ...@@ -740,11 +758,19 @@
"http://json-schema.org/draft-07/schema": "json-schema/schema7.json", "http://json-schema.org/draft-07/schema": "json-schema/schema7.json",
"http://json-schema.org/schema": "json-schema/schema7.json" "http://json-schema.org/schema": "json-schema/schema7.json"
}; };
// schema_urls[path] = [
// stack urls
// "url1",
// "url2"
// ]
// used for break soft circular relation of schemas
g.props.schema_urls = {};
// schema_required_urls[path] = [ // schema_required_urls[path] = [
// stack required urls, on every unrequired field stack begining from [] // stack required urls, on every unrequired field stack begining from []
// "url1", // "url1",
// "url2" // "url2"
// ] // ]
// used for break hard circular relation of schemas
g.props.schema_required_urls = {}; g.props.schema_required_urls = {};
// schema_resolve_errors[schema_url] = { // schema_resolve_errors[schema_url] = {
// schemaPath: local_schema_path, // schemaPath: local_schema_path,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment