From 1b735fbe24bd0911e8ee7a291b748f069e799639 Mon Sep 17 00:00:00 2001 From: redmitry Date: Tue, 27 Aug 2024 11:59:30 +0200 Subject: [PATCH] move back the scope resolution to parser --- .../schema/impl/DefaultJsonSchemaParser.java | 58 +++++++++---- .../json/schema/model/PrimitiveSchema.java | 4 + .../model/impl/AbstractJsonReferenceImpl.java | 16 ++-- .../schema/model/impl/AbstractJsonSchema.java | 6 +- .../model/impl/AbstractJsonSchemaElement.java | 34 +++++--- .../model/impl/BooleanJsonSchemaImpl.java | 6 +- .../json/schema/model/impl/JsonAllOfImpl.java | 6 +- .../json/schema/model/impl/JsonAnyOfImpl.java | 6 +- .../model/impl/JsonArraySchemaImpl.java | 17 ++-- .../model/impl/JsonBooleanSchemaImpl.java | 6 +- .../json/schema/model/impl/JsonConstImpl.java | 6 +- .../impl/JsonDependentPropertiesImpl.java | 9 +- .../model/impl/JsonDynamicReferenceImpl.java | 10 +-- .../json/schema/model/impl/JsonEnumImpl.java | 6 +- .../model/impl/JsonIntegerSchemaImpl.java | 6 +- .../impl/JsonMultitypeSchemaWrapper.java | 40 ++------- .../json/schema/model/impl/JsonNotImpl.java | 8 +- .../schema/model/impl/JsonNullSchemaImpl.java | 6 +- .../model/impl/JsonNumberSchemaImpl.java | 8 +- .../model/impl/JsonObjectSchemaImpl.java | 44 ++++------ .../json/schema/model/impl/JsonOneOfImpl.java | 6 +- .../schema/model/impl/JsonPropertiesImpl.java | 9 +- .../impl/JsonRecursiveReferenceImpl.java | 49 +++++------ .../schema/model/impl/JsonReferenceImpl.java | 7 +- .../model/impl/JsonStringSchemaImpl.java | 6 +- .../schema/model/impl/NumericSchemaImpl.java | 6 +- .../model/impl/PrimitiveSchemaImpl.java | 86 ++++++++++--------- .../schema/model/impl/SchemaArrayImpl.java | 8 +- 28 files changed, 242 insertions(+), 237 deletions(-) diff --git a/src/main/java/es/elixir/bsc/json/schema/impl/DefaultJsonSchemaParser.java b/src/main/java/es/elixir/bsc/json/schema/impl/DefaultJsonSchemaParser.java index d1898cc..c7e4d2b 100644 --- a/src/main/java/es/elixir/bsc/json/schema/impl/DefaultJsonSchemaParser.java +++ b/src/main/java/es/elixir/bsc/json/schema/impl/DefaultJsonSchemaParser.java @@ -53,6 +53,7 @@ import es.elixir.bsc.json.schema.model.impl.AbstractJsonSchemaElement; import es.elixir.bsc.json.schema.model.impl.JsonMultitypeSchemaWrapper; import java.io.IOException; +import java.net.URI; import java.util.Map; import javax.json.JsonArray; import javax.json.JsonObject; @@ -84,7 +85,7 @@ public AbstractJsonSchema parse(JsonSchemaLocator locator, AbstractJsonSchemaEle if (value.getValueType() == ValueType.TRUE || value.getValueType() == ValueType.FALSE) { - return new BooleanJsonSchemaImpl(parent, locator, jsonPointer).read(this, value); + return new BooleanJsonSchemaImpl(parent, locator, locator, jsonPointer).read(this, value); } if (value.getValueType() != ValueType.OBJECT) { @@ -103,10 +104,12 @@ public AbstractJsonSchema parse(JsonSchemaLocator locator, AbstractJsonSchemaEle // before draft 2019-09 $ref ignored any other properties if (JsonSchemaVersion.SCHEMA_DRAFT_2019_09.compareTo(getJsonSchemaVersion(locator)) > 0) { - return new JsonReferenceImpl(parent, locator, jsonPointer).read(this, object); + return new JsonReferenceImpl(parent, locator, locator, jsonPointer).read(this, object); } } - + + final JsonSchemaLocator scope = getScope(locator, object); + final JsonValue type_value = object.get(TYPE); final ValueType vtype; if (type_value == null) { @@ -135,29 +138,29 @@ public AbstractJsonSchema parse(JsonSchemaLocator locator, AbstractJsonSchemaEle if (jenum.isEmpty()) { throw new JsonSchemaException(new ParsingError(ParsingMessage.EMPTY_ENUM)); } - return new JsonEnumImpl(parent, locator, jsonPointer).read(this, object); + return new JsonEnumImpl(parent, scope, locator, jsonPointer).read(this, object); } final JsonValue jconst = object.get(CONST); if (jconst != null) { - return new JsonConstImpl(parent, locator, jsonPointer).read(this, object); + return new JsonConstImpl(parent, scope, locator, jsonPointer).read(this, object); } if (type == null) { - return new JsonMultitypeSchemaWrapper(parent, locator, jsonPointer, + return new JsonMultitypeSchemaWrapper(parent, scope, locator, jsonPointer, vtype == ValueType.ARRAY ? type_value.asJsonArray() : null) .read(this, object); } final AbstractJsonSchema schema; switch(type) { - case OBJECT: schema = new JsonObjectSchemaImpl(parent, locator, jsonPointer); break; - case ARRAY: schema = new JsonArraySchemaImpl(parent, locator, jsonPointer); break; - case STRING: schema = new JsonStringSchemaImpl(parent, locator, jsonPointer); break; - case NUMBER: schema = new JsonNumberSchemaImpl(parent, locator, jsonPointer); break; - case INTEGER: schema = new JsonIntegerSchemaImpl(parent, locator, jsonPointer); break; - case BOOLEAN: schema = new JsonBooleanSchemaImpl(parent, locator, jsonPointer); break; - case NULL: schema = new JsonNullSchemaImpl(parent, locator, jsonPointer); break; + case OBJECT: schema = new JsonObjectSchemaImpl(parent, scope, locator, jsonPointer); break; + case ARRAY: schema = new JsonArraySchemaImpl(parent, scope, locator, jsonPointer); break; + case STRING: schema = new JsonStringSchemaImpl(parent, scope, locator, jsonPointer); break; + case NUMBER: schema = new JsonNumberSchemaImpl(parent, scope, locator, jsonPointer); break; + case INTEGER: schema = new JsonIntegerSchemaImpl(parent, scope, locator, jsonPointer); break; + case BOOLEAN: schema = new JsonBooleanSchemaImpl(parent, scope, locator, jsonPointer); break; + case NULL: schema = new JsonNullSchemaImpl(parent, scope, locator, jsonPointer); break; default: return null; } @@ -180,11 +183,36 @@ public JsonSchemaVersion getJsonSchemaVersion(JsonSchemaLocator locator) { } catch (IOException ex) {} final Object version = properties.get(JsonSchemaParserConfig.JSON_SCHEMA_VERSION); - if (version instanceof JsonSchemaVersion) { - return (JsonSchemaVersion)version; + if (version instanceof JsonSchemaVersion v) { + return v; } return JsonSchemaVersion.SCHEMA_DRAFT_07; // default } + private JsonSchemaLocator getScope(JsonSchemaLocator locator, JsonObject object) + throws JsonSchemaException { + + JsonValue $id = object.get(JsonSchema.ID); + if ($id == null) { + $id = object.get("id"); // draft4 + } + + if ($id != null) { + if ($id.getValueType() != JsonValue.ValueType.STRING) { + throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, + "id", $id.getValueType().name(), JsonValue.ValueType.STRING.name())); + } else { + final String id = ((JsonString)$id).getString(); + try { + locator = locator.resolve(URI.create(id)); + locator.setSchema(object); + } catch(IllegalArgumentException ex) { + throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_REFERENCE, id)); + } + } + } + + return locator; + } } diff --git a/src/main/java/es/elixir/bsc/json/schema/model/PrimitiveSchema.java b/src/main/java/es/elixir/bsc/json/schema/model/PrimitiveSchema.java index aa89d89..bacbb57 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/PrimitiveSchema.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/PrimitiveSchema.java @@ -50,6 +50,10 @@ public interface PrimitiveSchema extends JsonSchema { public final static String THEN = "then"; public final static String ELSE = "else"; + String getAnchor(); + String getDynamicAnchor(); + Boolean getRecursiveAnchor(); + JsonAllOf getAllOf(); JsonAnyOf getAnyOf(); JsonOneOf getOneOf(); diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonReferenceImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonReferenceImpl.java index 645708f..a928f01 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonReferenceImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonReferenceImpl.java @@ -56,9 +56,9 @@ public abstract class AbstractJsonReferenceImpl extends AbstractJsonSchema extends AbstractJsonSchemaElement implements JsonSchema { - public AbstractJsonSchema(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public AbstractJsonSchema(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } public AbstractJsonSchema read(JsonSubschemaParser parser, T value) diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonSchemaElement.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonSchemaElement.java index 0cfd952..bd34299 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonSchemaElement.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/AbstractJsonSchemaElement.java @@ -30,40 +30,54 @@ import java.net.URI; /** + * This is an root class that any JSON Schema element inherits from. + * It contains minimum properties to identify and locate the element in + * parsed JSON Schema tree. + * * @author Dmitry Repchevsky */ public abstract class AbstractJsonSchemaElement implements JsonSchemaElement { public final AbstractJsonSchemaElement parent; + + public final JsonSchemaLocator scope; public final JsonSchemaLocator locator; - private final String jsonPointer; - - public AbstractJsonSchemaElement(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { + public final String jsonPointer; + + /** + * Constructor of the object. + * It only sets an essential properties to identify and locate the element in + * the JSON Schema. + * + * @param parent a parent element that encloses this one + * @param scope current element scope (may or may not be equal to the location) + * @param locator the locator that was used to load this document + * @param jsonPointer JSON Pointer to the parsed JSON Value that represents this element. + */ + public AbstractJsonSchemaElement(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { this.parent = parent; + + this.scope = scope; this.locator = locator; this.jsonPointer = jsonPointer.startsWith("//") ? jsonPointer.substring(1) : jsonPointer; } @Override public final URI getId() { - return getScope().uri; + return scope.uri; } @Override public String getJsonPointer() { // when scope != locator (new scope) jsonPointer is 'root' - return getScope() == locator ? jsonPointer : "/"; + return scope == locator ? jsonPointer : "/"; } @Override public AbstractJsonSchemaElement getParent() { return parent; } - - public JsonSchemaLocator getScope() { - return locator; - } } diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/BooleanJsonSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/BooleanJsonSchemaImpl.java index 41f5207..a905adc 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/BooleanJsonSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/BooleanJsonSchemaImpl.java @@ -50,9 +50,9 @@ public class BooleanJsonSchemaImpl extends AbstractJsonSchema private boolean evaluation; - public BooleanJsonSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public BooleanJsonSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAllOfImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAllOfImpl.java index b3259e0..9d6cf82 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAllOfImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAllOfImpl.java @@ -44,9 +44,9 @@ public class JsonAllOfImpl extends SchemaArrayImpl implements JsonAllOf { - public JsonAllOfImpl(AbstractJsonSchema parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonAllOfImpl(AbstractJsonSchema parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAnyOfImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAnyOfImpl.java index 7f77f03..e46a414 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAnyOfImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonAnyOfImpl.java @@ -46,9 +46,9 @@ public class JsonAnyOfImpl extends SchemaArrayImpl implements JsonAnyOf { - public JsonAnyOfImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonAnyOfImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonArraySchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonArraySchemaImpl.java index f339715..163096d 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonArraySchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonArraySchemaImpl.java @@ -36,7 +36,6 @@ import java.util.ArrayList; import java.util.List; import es.elixir.bsc.json.schema.impl.JsonSubschemaParser; -import static es.elixir.bsc.json.schema.model.JsonArraySchema.ADDITIONAL_ITEMS; import es.elixir.bsc.json.schema.model.JsonSchemaElement; import java.util.HashSet; import java.util.Set; @@ -70,9 +69,9 @@ public class JsonArraySchemaImpl extends PrimitiveSchemaImpl private Long minContains; private Long maxContains; - public JsonArraySchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonArraySchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override @@ -174,7 +173,7 @@ public JsonArraySchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonValue jcontains = object.get(CONTAINS); if (jcontains != null) { - contains = parser.parse(getScope(), this, getJsonPointer() + "/" + CONTAINS, jcontains, null); + contains = parser.parse(scope, this, getJsonPointer() + "/" + CONTAINS, jcontains, null); } final JsonNumber jminContains = JsonSchemaUtil.check(object.getJsonNumber(MIN_CONTAINS), JsonValue.ValueType.NUMBER); @@ -192,7 +191,7 @@ public JsonArraySchemaImpl read(JsonSubschemaParser parser, JsonObject object) switch(jitems.getValueType()) { case OBJECT: case TRUE: - case FALSE: final AbstractJsonSchema schema = parser.parse(getScope(), this, getJsonPointer() + "/" + ITEMS, jitems, null); + case FALSE: final AbstractJsonSchema schema = parser.parse(scope, this, getJsonPointer() + "/" + ITEMS, jitems, null); getItems().add(schema); break; case ARRAY: additionalItems = true; @@ -201,7 +200,7 @@ public JsonArraySchemaImpl read(JsonSubschemaParser parser, JsonObject object) switch(value.getValueType()) { case OBJECT: case TRUE: - case FALSE: final AbstractJsonSchema arr = parser.parse(getScope(), this, getJsonPointer() + "/" + ITEMS + "/" + i, value, null); + case FALSE: final AbstractJsonSchema arr = parser.parse(scope, this, getJsonPointer() + "/" + ITEMS + "/" + i, value, null); getItems().add(arr); break; default: throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, @@ -225,7 +224,7 @@ public JsonArraySchemaImpl read(JsonSubschemaParser parser, JsonObject object) default: throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, ADDITIONAL_ITEMS, jadditionalItems.getValueType().name(), "either object or boolean")); } - additionalItemsSchema = parser.parse(getScope(), this, getJsonPointer() + "/" + ADDITIONAL_ITEMS, jadditionalItems, null); + additionalItemsSchema = parser.parse(scope, this, getJsonPointer() + "/" + ADDITIONAL_ITEMS, jadditionalItems, null); } } @@ -233,7 +232,7 @@ public JsonArraySchemaImpl read(JsonSubschemaParser parser, JsonObject object) if (junevaluatedItems != null) { switch(junevaluatedItems.getValueType()) { case OBJECT: unevaluatedItems = null; - unevaluatedItemsSchema = parser.parse(getScope(), this, getJsonPointer() + "/" + UNEVALUATED_ITEMS, junevaluatedItems, null); + unevaluatedItemsSchema = parser.parse(scope, this, getJsonPointer() + "/" + UNEVALUATED_ITEMS, junevaluatedItems, null); break; case TRUE: unevaluatedItems = true; break; case FALSE: unevaluatedItems = false; break; diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonBooleanSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonBooleanSchemaImpl.java index 94e24f4..57d6f39 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonBooleanSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonBooleanSchemaImpl.java @@ -43,9 +43,9 @@ public class JsonBooleanSchemaImpl extends PrimitiveSchemaImpl implements JsonBooleanSchema { - public JsonBooleanSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonBooleanSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonConstImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonConstImpl.java index f184e4d..080ce78 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonConstImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonConstImpl.java @@ -45,9 +45,9 @@ public class JsonConstImpl extends PrimitiveSchemaImpl implements JsonConst { private JsonValue value; - public JsonConstImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonConstImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDependentPropertiesImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDependentPropertiesImpl.java index f8ceafb..f9d1977 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDependentPropertiesImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDependentPropertiesImpl.java @@ -48,12 +48,11 @@ public class JsonDependentPropertiesImpl extends AbstractJsonSchemaElement implements JsonDependentProperties { - private final Map properties; + private final Map properties = new LinkedHashMap(); - public JsonDependentPropertiesImpl(AbstractJsonSchema parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); - properties = new LinkedHashMap(); + public JsonDependentPropertiesImpl(AbstractJsonSchema parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDynamicReferenceImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDynamicReferenceImpl.java index 3dbbeea..a63aec9 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDynamicReferenceImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonDynamicReferenceImpl.java @@ -46,9 +46,9 @@ public class JsonDynamicReferenceImpl extends JsonReferenceImpl implements JsonDynamicReference { - public JsonDynamicReferenceImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonDynamicReferenceImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override @@ -93,12 +93,12 @@ public JsonSchemaElement getSchema() throws JsonSchemaException { private AbstractJsonSchemaElement getSchema(AbstractJsonSchemaElement e, URI uri) throws IOException, JsonSchemaException { final String fragment = uri.getFragment(); - final JsonSchemaLocator scope = e.getScope().resolve(uri); + final JsonSchemaLocator scope = e.scope.resolve(uri); final JsonValue value = scope.getSchema("/"); if (value instanceof JsonObject jsubschema) { final String anchor = jsubschema.getString(DYNAMIC_ANCHOR, null); if (fragment.equals(anchor)) { - return parser.parse(scope, e.getParent(), e.getJsonPointer(), jsubschema, null); + return parser.parse(scope, this, e.getJsonPointer(), jsubschema, null); } } return null; diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonEnumImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonEnumImpl.java index 91f4bbe..0e55b89 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonEnumImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonEnumImpl.java @@ -44,9 +44,9 @@ public class JsonEnumImpl extends PrimitiveSchemaImpl implements JsonEnum { private List values; - public JsonEnumImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonEnumImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonIntegerSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonIntegerSchemaImpl.java index 18ddb72..78edfab 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonIntegerSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonIntegerSchemaImpl.java @@ -50,9 +50,9 @@ public class JsonIntegerSchemaImpl extends NumericSchemaImpl implements JsonIntegerSchema { - public JsonIntegerSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonIntegerSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonMultitypeSchemaWrapper.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonMultitypeSchemaWrapper.java index cff07f8..c4fb265 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonMultitypeSchemaWrapper.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonMultitypeSchemaWrapper.java @@ -32,14 +32,12 @@ import es.elixir.bsc.json.schema.impl.JsonSubschemaParser; import es.elixir.bsc.json.schema.model.JsonArraySchema; import es.elixir.bsc.json.schema.model.JsonObjectSchema; -import es.elixir.bsc.json.schema.model.JsonSchema; import es.elixir.bsc.json.schema.model.JsonSchemaElement; import es.elixir.bsc.json.schema.model.JsonType; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; -import java.net.URI; import java.util.Spliterator; import java.util.Spliterators; import java.util.stream.Stream; @@ -55,12 +53,12 @@ public class JsonMultitypeSchemaWrapper extends JsonAnyOfImpl { - private JsonSchemaLocator scope; private final JsonArray types; - public JsonMultitypeSchemaWrapper(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer, JsonArray types) { - super(parent, locator, jsonPointer); + public JsonMultitypeSchemaWrapper(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer, + JsonArray types) { + super(parent, scope, locator, jsonPointer); this.types = types; } @@ -72,41 +70,15 @@ public Stream getChildren() { .filter(s -> s instanceof JsonObjectSchema || s instanceof JsonArraySchema) .flatMap(JsonSchemaElement::getChildren); } - - @Override - public JsonSchemaLocator getScope() { - return scope; - } @Override public JsonAnyOfImpl read(JsonSubschemaParser parser, JsonObject object) throws JsonSchemaException { - JsonValue $id = object.get(JsonSchema.ID); - if ($id == null) { - $id = object.get("id"); // draft4 - } - - if ($id == null) { - scope = locator; - } else if ($id.getValueType() != JsonValue.ValueType.STRING) { - throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, - "id", $id.getValueType().name(), JsonValue.ValueType.STRING.name())); - } else { - final String id = ((JsonString)$id).getString(); - try { - scope = locator.resolve(URI.create(id)); - scope.setSchema(object); - } catch(IllegalArgumentException ex) { - throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_REFERENCE, - new Object[] {id})); - } - } - if (types == null) { for (JsonType val : JsonType.values()) { try { - final AbstractJsonSchema s = parser.parse(locator, this, getJsonPointer(), object, val); + final AbstractJsonSchema s = parser.parse(scope, this, getJsonPointer(), object, val); if (s != null) { add(s); } @@ -121,7 +93,7 @@ public JsonAnyOfImpl read(JsonSubschemaParser parser, JsonObject object) } try { final JsonType t = JsonType.fromValue(((JsonString)val).getString()); - add(parser.parse(locator, this, getJsonPointer(), object, t)); + add(parser.parse(scope, this, getJsonPointer(), object, t)); } catch(IllegalArgumentException ex) { throw new JsonSchemaException( new ParsingError(ParsingMessage.UNKNOWN_OBJECT_TYPE, val)); diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNotImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNotImpl.java index 730ef72..b78b8a6 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNotImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNotImpl.java @@ -47,9 +47,9 @@ public class JsonNotImpl extends AbstractJsonSchema private AbstractJsonSchema schema; - public JsonNotImpl(AbstractJsonSchema parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonNotImpl(AbstractJsonSchema parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override @@ -71,7 +71,7 @@ public void setJsonSchema(AbstractJsonSchema schema) { public JsonNotImpl read(JsonSubschemaParser parser, JsonValue value) throws JsonSchemaException { - this.schema = parser.parse(getScope(), null, getJsonPointer(), value, null); + this.schema = parser.parse(scope, this, getJsonPointer(), value, null); return this; } diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNullSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNullSchemaImpl.java index fae8388..f84a79b 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNullSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNullSchemaImpl.java @@ -43,9 +43,9 @@ public class JsonNullSchemaImpl extends PrimitiveSchemaImpl implements JsonNullSchema { - public JsonNullSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonNullSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNumberSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNumberSchemaImpl.java index a9fc347..7af4152 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNumberSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonNumberSchemaImpl.java @@ -45,9 +45,9 @@ public class JsonNumberSchemaImpl extends NumericSchemaImpl implements JsonNumberSchema { - public JsonNumberSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonNumberSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override @@ -92,7 +92,7 @@ public boolean validate(String jsonPointer, JsonValue value, JsonValue parent, return nerrors == errors.size(); } - + private void validate(String jsonPointer, BigDecimal dec, List errors) { if (minimum != null) { diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonObjectSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonObjectSchemaImpl.java index 3e51f66..b1f1377 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonObjectSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonObjectSchemaImpl.java @@ -40,7 +40,9 @@ import es.elixir.bsc.json.schema.ParsingMessage; import es.elixir.bsc.json.schema.impl.JsonSubschemaParser; import es.elixir.bsc.json.schema.model.JsonDependentProperties; +import static es.elixir.bsc.json.schema.model.JsonObjectSchema.PROPERTY_NAMES; import es.elixir.bsc.json.schema.model.JsonSchemaElement; +import es.elixir.bsc.json.schema.model.JsonType; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; @@ -74,9 +76,9 @@ public class JsonObjectSchemaImpl extends PrimitiveSchemaImpl private AbstractJsonSchema unevaluatedPropertiesSchema; private AbstractJsonSchema propertyNames; - public JsonObjectSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonObjectSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override @@ -117,8 +119,8 @@ public StringArray getRequired() { @Override public JsonProperties getDependentSchemas() { if (dependentSchemas == null) { - dependentSchemas = new JsonPropertiesImpl(this, getScope(), - getJsonPointer() + "/" + DEPENDENT_SCHEMAS); + dependentSchemas = new JsonPropertiesImpl(this, + scope, scope, jsonPointer + "/" + DEPENDENT_SCHEMAS); } return dependentSchemas; } @@ -126,8 +128,8 @@ public JsonProperties getDependentSchemas() { @Override public JsonDependentProperties getDependentRequired() { if (dependentRequired == null) { - dependentRequired = new JsonDependentPropertiesImpl(this, getScope(), - getJsonPointer() + "/" + DEPENDENT_REQUIRED); + dependentRequired = new JsonDependentPropertiesImpl(this, + scope, scope, jsonPointer + "/" + DEPENDENT_REQUIRED); } return dependentRequired; } @@ -170,7 +172,7 @@ public JsonObjectSchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonObject jproperties = JsonSchemaUtil.check(object.get(PROPERTIES), ValueType.OBJECT); if (jproperties != null) { - properties = new JsonPropertiesImpl(this, getScope(), getJsonPointer() + "/" + PROPERTIES) + properties = new JsonPropertiesImpl(this, scope, scope, jsonPointer + "/" + PROPERTIES) .read(parser, jproperties); } @@ -186,7 +188,7 @@ public JsonObjectSchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonObject jpatternProperties = JsonSchemaUtil.check(object.get(PATTERN_PROPERTIES), ValueType.OBJECT); if (jpatternProperties != null) { - patternProperties = new JsonPropertiesImpl(this, getScope(), getJsonPointer() + "/" + PATTERN_PROPERTIES) + patternProperties = new JsonPropertiesImpl(this, scope, scope, jsonPointer + "/" + PATTERN_PROPERTIES) .read(parser, jpatternProperties); } @@ -198,7 +200,7 @@ public JsonObjectSchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonValue jadditionalProperties = object.get(ADDITIONAL_PROPERTIES); if (jadditionalProperties != null) { switch(jadditionalProperties.getValueType()) { - case OBJECT: additionalPropertiesSchema = parser.parse(getScope(), this, getJsonPointer() + "/" + ADDITIONAL_PROPERTIES, jadditionalProperties, null); break; + case OBJECT: additionalPropertiesSchema = parser.parse(scope, this, getJsonPointer() + "/" + ADDITIONAL_PROPERTIES, jadditionalProperties, null); break; case TRUE: additionalProperties = true; break; case FALSE: additionalProperties = false; break; default: throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, @@ -209,7 +211,7 @@ public JsonObjectSchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonValue junevaluatedProperties = object.get(UNEVALUATED_PROPERTIES); if (junevaluatedProperties != null) { switch(junevaluatedProperties.getValueType()) { - case OBJECT: unevaluatedPropertiesSchema = parser.parse(getScope(), this, getJsonPointer() + "/" + UNEVALUATED_PROPERTIES, junevaluatedProperties, null); break; + case OBJECT: unevaluatedPropertiesSchema = parser.parse(scope, this, getJsonPointer() + "/" + UNEVALUATED_PROPERTIES, junevaluatedProperties, null); break; case TRUE: unevaluatedProperties = true; break; case FALSE: unevaluatedProperties = false; break; default: throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, @@ -219,27 +221,19 @@ public JsonObjectSchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonValue jpropertyNames = object.get(PROPERTY_NAMES); if (jpropertyNames != null) { - switch(jpropertyNames.getValueType()) { - case OBJECT: propertyNames = new JsonStringSchemaImpl(this, getScope(), getJsonPointer() + "/" + PROPERTY_NAMES).read(parser, jpropertyNames.asJsonObject()); - break; - case TRUE: - case FALSE: propertyNames = new BooleanJsonSchemaImpl(this, getScope(), getJsonPointer() + "/" + PROPERTY_NAMES).read(parser, jpropertyNames); - break; - default: throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, - PROPERTY_NAMES, jpropertyNames.getValueType().name(), "either object or boolean")); - } + propertyNames = parser.parse(scope, this, getJsonPointer() + "/" + PROPERTY_NAMES, jpropertyNames, JsonType.STRING); } final JsonObject jdependentSchemas = JsonSchemaUtil.check(object.get(DEPENDENT_SCHEMAS), ValueType.OBJECT); if (jdependentSchemas != null) { - dependentSchemas = new JsonPropertiesImpl(this, getScope(), - getJsonPointer() + "/" + DEPENDENT_SCHEMAS).read(parser, jdependentSchemas); + dependentSchemas = new JsonPropertiesImpl(this, scope, scope, + jsonPointer + "/" + DEPENDENT_SCHEMAS).read(parser, jdependentSchemas); } final JsonObject jdependentRequired = JsonSchemaUtil.check(object.get(DEPENDENT_REQUIRED), ValueType.OBJECT); if (jdependentRequired != null) { - dependentRequired = new JsonDependentPropertiesImpl(this, getScope(), - getJsonPointer() + "/" + DEPENDENT_REQUIRED).read(parser, jdependentRequired); + dependentRequired = new JsonDependentPropertiesImpl(this, scope, scope, + jsonPointer + "/" + DEPENDENT_REQUIRED).read(parser, jdependentRequired); } final JsonObject jdependencies = JsonSchemaUtil.check(object.get(DEPENDENCIES), ValueType.OBJECT); @@ -251,7 +245,7 @@ public JsonObjectSchemaImpl read(JsonSubschemaParser parser, JsonObject object) switch(value.getValueType()) { case OBJECT: case TRUE: - case FALSE: final AbstractJsonSchema schema = parser.parse(getScope(), this, getJsonPointer() + "/" + DEPENDENCIES + "/" + name + "/", value, null); + case FALSE: final AbstractJsonSchema schema = parser.parse(scope, this, getJsonPointer() + "/" + DEPENDENCIES + "/" + name + "/", value, null); getDependentSchemas().put(name, schema); break; case ARRAY: final StringArray arr = new JsonStringArray().read(value.asJsonArray()); diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonOneOfImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonOneOfImpl.java index fb4f22c..1cf8fe8 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonOneOfImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonOneOfImpl.java @@ -44,9 +44,9 @@ public class JsonOneOfImpl extends SchemaArrayImpl implements JsonOneOf { - public JsonOneOfImpl(AbstractJsonSchema parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonOneOfImpl(AbstractJsonSchema parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonPropertiesImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonPropertiesImpl.java index 12f1006..5004659 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonPropertiesImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonPropertiesImpl.java @@ -45,12 +45,11 @@ public class JsonPropertiesImpl extends AbstractJsonSchemaElement implements JsonProperties { - private final Map properties; + private final Map properties = new LinkedHashMap(); - public JsonPropertiesImpl(AbstractJsonSchema parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); - properties = new LinkedHashMap(); + public JsonPropertiesImpl(AbstractJsonSchema parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonRecursiveReferenceImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonRecursiveReferenceImpl.java index fd5f915..f26ebd1 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonRecursiveReferenceImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonRecursiveReferenceImpl.java @@ -32,11 +32,11 @@ import es.elixir.bsc.json.schema.impl.JsonSubschemaParser; import es.elixir.bsc.json.schema.model.JsonRecursiveReference; import es.elixir.bsc.json.schema.model.JsonSchemaElement; +import es.elixir.bsc.json.schema.model.PrimitiveSchema; import java.util.stream.Stream; import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; -import java.io.IOException; /** * @author Dmitry Repchevsky @@ -45,9 +45,9 @@ public class JsonRecursiveReferenceImpl extends AbstractJsonReferenceImpl implements JsonRecursiveReference { - public JsonRecursiveReferenceImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonRecursiveReferenceImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override @@ -59,32 +59,27 @@ public Stream getChildren() { public JsonSchemaElement getSchema() throws JsonSchemaException { if (schema == null) { AbstractJsonSchemaElement e = this; - try { - while ((e = e.getParent()) != null) { - if ("/".equals(e.getJsonPointer())) { - final JsonSchemaLocator scope = e.getScope(); - final JsonValue value = scope.getSchema("/"); - if (value instanceof JsonObject jsubschema) { - final boolean anchor = jsubschema.getBoolean(RECURSIVE_ANCHOR, false); - - // no 'type' or 'type': [] leads to JsonMultitypeSchemaWrapper wrapper. - // because we are in a 'root' parent either has different location - // or be the wrapper. - if (e.parent instanceof JsonMultitypeSchemaWrapper) { - e = e.parent; - } + while ((e = e.getParent()) != null) { + if (e instanceof PrimitiveSchema element && + "/".equals(e.getJsonPointer())) { + final Boolean anchor = element.getRecursiveAnchor(); + + // no 'type' or 'type': [] leads to JsonMultitypeSchemaWrapper wrapper. + // because we are in a 'root' parent either has different location + // or be the wrapper. + if (e.parent instanceof JsonMultitypeSchemaWrapper) { + e = e.parent; + } - if (anchor) { - schema = e; - continue; - } else if (schema == null) { - schema = e; - } - break; - } + if (Boolean.TRUE == anchor) { + schema = e; + continue; + } else if (schema == null) { + schema = e; } + break; } - } catch (IOException ex) {} + } } return schema; diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonReferenceImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonReferenceImpl.java index 73f4595..99ff626 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonReferenceImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonReferenceImpl.java @@ -32,7 +32,6 @@ import es.elixir.bsc.json.schema.impl.JsonSubschemaParser; import es.elixir.bsc.json.schema.model.JsonReference; import es.elixir.bsc.json.schema.model.JsonSchemaElement; -import es.elixir.bsc.json.schema.model.JsonType; import java.io.IOException; import java.util.stream.Stream; import javax.json.JsonException; @@ -45,9 +44,9 @@ public class JsonReferenceImpl extends AbstractJsonReferenceImpl implements JsonReference { - public JsonReferenceImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonReferenceImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonStringSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonStringSchemaImpl.java index d01c6ce..aeb8105 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonStringSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/JsonStringSchemaImpl.java @@ -54,9 +54,9 @@ public class JsonStringSchemaImpl extends PrimitiveSchemaImpl private String format; private Pattern pattern; - public JsonStringSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public JsonStringSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/NumericSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/NumericSchemaImpl.java index 2681bb2..961379a 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/NumericSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/NumericSchemaImpl.java @@ -54,9 +54,9 @@ public abstract class NumericSchemaImpl extends PrimitiveSchem protected Number exclusiveMinimum; protected Number exclusiveMaximum; - public NumericSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public NumericSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/PrimitiveSchemaImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/PrimitiveSchemaImpl.java index 65d07d1..50a74d0 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/PrimitiveSchemaImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/PrimitiveSchemaImpl.java @@ -59,11 +59,13 @@ public class PrimitiveSchemaImpl extends AbstractJsonSchema implements PrimitiveSchema { - private JsonSchemaLocator scope; - private String title; private String description; + private String anchor; + private String dynamic_anchor; + private Boolean recursive_anchor; + private JsonAllOfImpl allOf; private JsonAnyOfImpl anyOf; private JsonOneOfImpl oneOf; @@ -80,9 +82,9 @@ public class PrimitiveSchemaImpl extends AbstractJsonSchema */ private AbstractJsonReferenceImpl ref; - public PrimitiveSchemaImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public PrimitiveSchemaImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); } @Override @@ -98,11 +100,6 @@ public Stream getChildren() { ref != null ? ref.getChildren() : null) .flatMap(c -> c); } - - @Override - public JsonSchemaLocator getScope() { - return scope; - } public String getTitle() { return title; @@ -120,6 +117,21 @@ public void setDescription(String description) { this.description = description; } + @Override + public String getAnchor() { + return anchor; + } + + @Override + public String getDynamicAnchor() { + return dynamic_anchor; + } + + @Override + public Boolean getRecursiveAnchor() { + return recursive_anchor; + } + @Override public JsonAllOfImpl getAllOf() { return allOf; @@ -164,26 +176,6 @@ public JsonReference getReference() { public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) throws JsonSchemaException { - JsonValue $id = object.get(JsonSchema.ID); - if ($id == null) { - $id = object.get("id"); // draft4 - } - - if ($id == null) { - scope = locator; - } else if ($id.getValueType() != JsonValue.ValueType.STRING) { - throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, - "id", $id.getValueType().name(), JsonValue.ValueType.STRING.name())); - } else { - final String id = ((JsonString)$id).getString(); - try { - scope = locator.resolve(URI.create(id)); - scope.setSchema(object); - } catch(IllegalArgumentException ex) { - throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_REFERENCE, id)); - } - } - final JsonString jtitle = JsonSchemaUtil.check(object.get(TITLE), JsonValue.ValueType.STRING); if (jtitle != null) { setTitle(jtitle.getString()); @@ -196,14 +188,24 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonString janchor = JsonSchemaUtil.check(object.get(JsonSchema.ANCHOR), JsonValue.ValueType.STRING); if (janchor != null) { - final String anchor = janchor.getString(); + anchor = janchor.getString(); scope.resolve(URI.create("#" + anchor)).setSchema(object); } + final JsonValue jrecursiveanchor = object.get(RECURSIVE_ANCHOR); + if (jrecursiveanchor != null) { + switch(jrecursiveanchor.getValueType()) { + case TRUE: recursive_anchor = true; break; + case FALSE: recursive_anchor = false; break; + default: throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, + RECURSIVE_ANCHOR, jrecursiveanchor.getValueType().name(), "must be boolean")); + } + } + final JsonString jdynamicanchor = JsonSchemaUtil.check(object.get(JsonSchema.DYNAMIC_ANCHOR), JsonValue.ValueType.STRING); if (jdynamicanchor != null) { - final String anchor = jdynamicanchor.getString(); - scope.resolve(URI.create("#" + anchor)).setSchema(object); + dynamic_anchor = jdynamicanchor.getString(); + scope.resolve(URI.create("#" + dynamic_anchor)).setSchema(object); } JsonValue jdefs = object.get(JsonSchema.DEFS); @@ -213,7 +215,7 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) JsonSchema.DEFS, jdefs.getValueType().name(), JsonValue.ValueType.OBJECT.name())); } for (Map.Entry entry : jdefs.asJsonObject().entrySet()) { - parser.parse(getScope(), this, getJsonPointer() + "/" + JsonSchema.DEFS + "/" + entry.getKey(), entry.getValue(), null); + parser.parse(scope, this, getJsonPointer() + "/" + JsonSchema.DEFS + "/" + entry.getKey(), entry.getValue(), null); } } @@ -224,13 +226,13 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) "definitions", jdefinitions.getValueType().name(), JsonValue.ValueType.OBJECT.name())); } for (Map.Entry entry : jdefinitions.asJsonObject().entrySet()) { - parser.parse(getScope(), this, getJsonPointer() + "/definitions/" + entry.getKey(), entry.getValue(), null); + parser.parse(scope, this, getJsonPointer() + "/definitions/" + entry.getKey(), entry.getValue(), null); } } final JsonArray jallOf = JsonSchemaUtil.check(object.get(ALL_OF), JsonValue.ValueType.ARRAY); if (jallOf != null) { - final JsonAllOfImpl _allOf = new JsonAllOfImpl(this, scope, getJsonPointer() + "/" + ALL_OF) + final JsonAllOfImpl _allOf = new JsonAllOfImpl(this, scope, scope, jsonPointer + "/" + ALL_OF) .read(parser, jallOf); if (allOf == null) { allOf = _allOf; @@ -243,13 +245,13 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) final JsonArray janyOf = JsonSchemaUtil.check(object.get(ANY_OF), JsonValue.ValueType.ARRAY); if (janyOf != null) { - anyOf = new JsonAnyOfImpl(this, scope, getJsonPointer() + "/" + ANY_OF); + anyOf = new JsonAnyOfImpl(this, scope, scope, jsonPointer + "/" + ANY_OF); anyOf.read(parser, janyOf); } final JsonArray joneOf = JsonSchemaUtil.check(object.get(ONE_OF), JsonValue.ValueType.ARRAY); if (joneOf != null) { - oneOf = new JsonOneOfImpl(this, scope, getJsonPointer() + "/" + ONE_OF); + oneOf = new JsonOneOfImpl(this, scope, scope, jsonPointer + "/" + ONE_OF); oneOf.read(parser, joneOf); } @@ -258,7 +260,7 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) switch(jnot.getValueType()) { case OBJECT: case TRUE: - case FALSE: not = new JsonNotImpl(this, scope, getJsonPointer() + "/" + NOT) + case FALSE: not = new JsonNotImpl(this, scope, scope, jsonPointer + "/" + NOT) .read(parser, jnot); break; default: throw new JsonSchemaException(new ParsingError(ParsingMessage.INVALID_ATTRIBUTE_TYPE, @@ -289,7 +291,7 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) JsonReference.REF, jref.getValueType().name(), JsonValue.ValueType.STRING.name())); } - ref = new JsonReferenceImpl(this, scope, getJsonPointer()).read(parser, object); + ref = new JsonReferenceImpl(this, scope, scope, jsonPointer).read(parser, object); } final JsonValue jdynamic_ref = object.get(JsonDynamicReference.DYNAMIC_REF); @@ -304,7 +306,7 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) throw new JsonSchemaException(new ParsingError(ParsingMessage.INCOMPATIBLE_KEYWORDS, String.join(",", List.of(JsonRecursiveReference.REF, JsonDynamicReference.DYNAMIC_REF)))); } - ref = new JsonDynamicReferenceImpl(this, scope, getJsonPointer()).read(parser, object); + ref = new JsonDynamicReferenceImpl(this, scope, scope, jsonPointer).read(parser, object); } final JsonValue jrecursive_ref = object.get(JsonRecursiveReference.RECURSIVE_REF); @@ -320,7 +322,7 @@ public PrimitiveSchemaImpl read(JsonSubschemaParser parser, JsonObject object) String.join(",", List.of(JsonRecursiveReference.REF, JsonRecursiveReference.RECURSIVE_REF)))); } - ref = new JsonRecursiveReferenceImpl(this, scope, getJsonPointer()).read(parser, object); + ref = new JsonRecursiveReferenceImpl(this, scope, scope, jsonPointer).read(parser, object); } return this; diff --git a/src/main/java/es/elixir/bsc/json/schema/model/impl/SchemaArrayImpl.java b/src/main/java/es/elixir/bsc/json/schema/model/impl/SchemaArrayImpl.java index 7b4f4cb..9cb063e 100644 --- a/src/main/java/es/elixir/bsc/json/schema/model/impl/SchemaArrayImpl.java +++ b/src/main/java/es/elixir/bsc/json/schema/model/impl/SchemaArrayImpl.java @@ -49,9 +49,9 @@ public abstract class SchemaArrayImpl private final Set schemas; - public SchemaArrayImpl(AbstractJsonSchemaElement parent, JsonSchemaLocator locator, - String jsonPointer) { - super(parent, locator, jsonPointer); + public SchemaArrayImpl(AbstractJsonSchemaElement parent, + JsonSchemaLocator scope, JsonSchemaLocator locator, String jsonPointer) { + super(parent, scope, locator, jsonPointer); schemas = new HashSet(); } @@ -89,7 +89,7 @@ public SchemaArrayImpl read(JsonSubschemaParser parser, JsonArray array) for (int i = 0, n = array.size(); i < n; i++) { final JsonValue value = array.get(i); - final AbstractJsonSchema schema = parser.parse(getScope(), this, + final AbstractJsonSchema schema = parser.parse(scope, this, getJsonPointer() + "/" + Integer.toString(i), value, null); add(schema); }