io.openapiprocessor.jsonschema.schema.JsonSchemaObject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of json-schema-validator Show documentation
Show all versions of json-schema-validator Show documentation
OpenAPI Parser JSON-Schema Validator
/*
* Copyright 2021 https://github.com/openapi-processor/openapi-parser
* PDX-License-Identifier: Apache-2.0
*/
package io.openapiprocessor.jsonschema.schema;
import io.openapiprocessor.jsonschema.converter.*;
import io.openapiprocessor.jsonschema.support.Null;
import io.openapiprocessor.jsonschema.support.Types;
import io.openapiprocessor.jsonschema.support.Uris;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.net.URI;
import java.util.*;
import static io.openapiprocessor.jsonschema.schema.Keywords.*;
public class JsonSchemaObject implements JsonSchema {
private final JsonSchemaContext context;
private final Bucket schemaObject;
private final Bucket schemaProperties;
@SuppressWarnings("method.invocation")
public JsonSchemaObject (Map document, JsonSchemaContext context) {
this.context = context;
schemaObject = new Bucket (context.getScope (), document);
schemaProperties = getBucketProperties (schemaObject);
}
@SuppressWarnings("method.invocation")
public JsonSchemaObject (JsonPointer location, Map document, JsonSchemaContext context) {
this.context = context;
this.schemaObject = new Bucket (context.getScope (), location, document);
schemaProperties = getBucketProperties (schemaObject);
}
@Override
public JsonSchemaContext getContext () {
return context;
}
public JsonPointer getLocation () {
return schemaObject.getLocation ();
}
@Override
public boolean isRef () {
return schemaObject.hasProperty (REF);
}
@Override
public @Nullable URI getRef () {
return schemaObject.convert (REF, new UriConverter ());
}
@Override
public @Nullable String getAnchor () {
return schemaObject.convert (ANCHOR, new StringNullableConverter ());
}
@Override
public boolean isDynamicRef () {
if (context.getVersion () == SchemaVersion.Draft201909) {
return schemaObject.hasProperty (RECURSIVE_REF);
}
return schemaObject.hasProperty (DYNAMIC_REF);
}
@Override
public @Nullable URI getDynamicRef () {
if (context.getVersion () == SchemaVersion.Draft201909) {
return schemaObject.convert (RECURSIVE_REF, new UriConverter ());
}
return schemaObject.convert (DYNAMIC_REF, new UriConverter ());
}
@Override
public @Nullable String getDynamicAnchor () {
if (context.getVersion () == SchemaVersion.Draft201909) {
Boolean anchor = schemaObject.convert (RECURSIVE_ANCHOR, new BooleanConverter ());
if (anchor == null || !anchor)
return null;
return HASH;
}
return schemaObject.convert (DYNAMIC_ANCHOR, new StringNullableConverter ());
}
@Override
public JsonSchema getRefSchema () {
Reference reference = context.getReference (Null.nonNull(getRef()));
JsonSchemaContext refContext = context.withScope (reference.getValueScope ());
JsonSchema schema = new JsonSchemaRefConverter (refContext)
.convert (REF, reference.getValue (), reference.getPointer ());
if (schema == null)
throw new NoValueException (getLocation ().append (REF));
return schema;
}
// recursiveRef/ref
@Override
public JsonSchema getRefSchema (@Nullable URI dynamicScope) {
if (dynamicScope == null) {
// like $ref
// no ref in registry with scope
Reference reference = context.getReference (Null.nonNull (getDynamicRef ()));
JsonSchemaContext refContext = context.withScope (reference.getValueScope ());
JsonSchema schema = new JsonSchemaRefConverter (refContext)
.convert (DYNAMIC_REF, reference.getValue (), reference.getPointer ());
if (schema == null)
throw new NoValueException (getLocation ().append (DYNAMIC_REF));
return schema;
} else {
URI dynamicRef = Null.nonNull(getDynamicRef ());
String fragment = dynamicRef.getFragment ();
dynamicRef = Uris.createUri ("#" + fragment);
Reference reference = context.getDynamicReference (dynamicRef, dynamicScope);
JsonSchemaContext refContext = context.withScope (reference.getValueScope ());
JsonSchema schema = new JsonSchemaRefConverter (refContext)
.convert (DYNAMIC_REF, reference.getValue (), reference.getPointer ());
if (schema == null)
throw new NoValueException (getLocation ().append (DYNAMIC_REF));
return schema;
}
}
@Override
public @Nullable URI getMetaSchema () {
return schemaObject.convert (SCHEMA, new UriConverter ());
}
@Override
public @Nullable JsonSchema getMetaSchemaSchema () {
URI metaSchemaUri = getMetaSchema ();
if (metaSchemaUri == null) {
return null;
}
Reference reference = context.getReference (metaSchemaUri);
return new JsonSchemaConverter (context)
.convert (SCHEMA, reference.getValue (), reference.getPointer ());
}
@Override
public @Nullable Vocabularies getVocabulary () {
return schemaObject.convert (VOCABULARY, new VocabularyConverter (context));
}
@Override
public @Nullable URI getId () {
if (context.getVersion () == SchemaVersion.Draft4) {
return schemaObject.convert (ID4, new UriConverter ());
}
return schemaObject.convert (ID, new UriConverter ());
}
@Override
public @Nullable Number getMultipleOf () {
return schemaObject.convert (MULTIPLE_OF, new NumberConverter ());
}
@Override
public @Nullable Number getMaximum () {
return schemaObject.convert (MAXIMUM, new NumberConverter ());
}
@Override
public Boolean getExclusiveMaximumB () {
Boolean exclusive = schemaObject.convert (EXCLUSIVE_MAXIMUM, new BooleanConverter ());
if (exclusive == null)
return false;
return exclusive;
}
@Override
public @Nullable Number getExclusiveMaximum () {
return schemaObject.convert (EXCLUSIVE_MAXIMUM, new NumberConverter ());
}
@Override
public @Nullable Number getMinimum () {
return schemaObject.convert (MINIMUM, new NumberConverter ());
}
@Override
public Boolean getExclusiveMinimumB () {
Boolean exclusive = schemaObject.convert (EXCLUSIVE_MINIMUM, new BooleanConverter ());
if (exclusive == null)
return false;
return exclusive;
}
@Override
public @Nullable Number getExclusiveMinimum () {
return schemaObject.convert (EXCLUSIVE_MINIMUM, new NumberConverter ());
}
@Override
public @Nullable Integer getMaxLength () {
return schemaObject.convert (MAX_LENGTH, new IntegerConverter ());
}
@Override
public @Nullable Integer getMinLength () {
return schemaObject.convert (MIN_LENGTH, new IntegerConverter ());
}
@Override
public @Nullable String getPattern () {
return schemaObject.convert (PATTERN, new StringNullableConverter ());
}
@Override
public Collection getPrefixItems () {
Collection prefixItems = getJsonSchemasOf (PREFIX_ITEMS);
if (prefixItems == null)
return Collections.emptyList ();
return prefixItems;
}
@Override
public JsonSchemas getItems () {
boolean exists = schemaObject.hasProperty (ITEMS);
if (!exists)
return new JsonSchemas();
Object raw = schemaObject.getRawValue (ITEMS);
if (Types.isSchema (raw)) {
return new JsonSchemas (getJsonSchemaOf (ITEMS));
} else if (Types.isArray (raw)) {
Collection items = getJsonSchemasOf (ITEMS);
if (items != null) {
return new JsonSchemas (items);
}
}
throw new InvalidPropertyException (getLocation ().append (ITEMS));
}
@Override
public JsonSchemas getAdditionalItems () {
boolean exists = schemaObject.hasProperty (ADDITIONAL_ITEMS);
if (!exists)
return new JsonSchemas();
Object raw = schemaObject.getRawValue (ADDITIONAL_ITEMS);
if (raw == null)
return new JsonSchemas ((JsonSchema) null);
else
return new JsonSchemas (getJsonSchemaOf (ADDITIONAL_ITEMS));
}
@Override
public @Nullable JsonSchema getUnevaluatedItems () {
return getJsonSchemaOf (UNEVALUATED_ITEMS);
}
@Override
public @Nullable Integer getMaxItems () {
return schemaObject.convert (MAX_ITEMS, new IntegerConverter ());
}
@Override
public @Nullable Integer getMinItems () {
return schemaObject.convert (MIN_ITEMS, new IntegerConverter ());
}
@Override
public @Nullable Boolean isUniqueItems () {
return schemaObject.convert (UNIQUE_ITEMS, new BooleanConverter ());
}
@Override
public @Nullable JsonSchema getContains () {
return getJsonSchemaOf (CONTAINS);
}
@Override
public Integer getMinContains () {
Integer minContains = schemaObject.convert (MIN_CONTAINS, new IntegerConverter ());
if (minContains == null)
return 1;
return minContains;
}
@Override
public @Nullable Integer getMaxContains () {
return schemaObject.convert (MAX_CONTAINS, new IntegerConverter ());
}
@Override
public @Nullable Integer getMaxProperties () {
return schemaObject.convert (MAX_PROPERTIES, new IntegerConverter ());
}
@Override
public @Nullable Integer getMinProperties () {
return schemaObject.convert (MIN_PROPERTIES, new IntegerConverter ());
}
@Override
public @Nullable Collection getRequired () {
Object raw = schemaObject.getRawValue (REQUIRED);
if (raw == null)
return null;
return Collections.unmodifiableCollection(Types.asCol(raw));
}
@Override
public Map getProperties () {
Map properties = schemaObject.convert (PROPERTIES, new MapJsonSchemasConverter (context));
if (properties == null)
return Collections.emptyMap ();
return properties;
}
@Override
public Map getPatternProperties () {
// todo escape regex \
Map patternProperties = schemaObject.convert (
PATTERN_PROPERTIES, new MapJsonSchemasConverter (context));
if (patternProperties == null) {
return Collections.emptyMap ();
}
return patternProperties;
}
@Override
public @Nullable JsonSchema getAdditionalProperties () {
return getJsonSchemaOf (ADDITIONAL_PROPERTIES);
}
@Override
public @Nullable JsonSchema getUnevaluatedProperties () {
return getJsonSchemaOf (UNEVALUATED_PROPERTIES);
}
@Override
public @Nullable Map getDependencies () {
return schemaObject.convert (DEPENDENCIES, new MapDependencyConverter (context));
}
@Override
public @Nullable Map getDependentSchemas () {
return schemaObject.convert (DEPENDENT_SCHEMAS, new MapJsonSchemasConverter (context));
}
@Override
public @Nullable Map> getDependentRequired () {
return schemaObject.convert (DEPENDENT_REQUIRED, new MapSetStringsOrEmptyConverter (ResponseType.NULL));
}
@Override
public @Nullable JsonSchema getPropertyNames () {
return getJsonSchemaOf (PROPERTY_NAMES);
}
@Override
public @Nullable JsonSchema getJsonSchema (String property) {
return schemaProperties.convert (property, new JsonSchemaConverter (context));
}
@Override
public Collection getEnum () {
Object raw = schemaObject.getRawValue (ENUM);
if (raw == null)
return Collections.emptyList ();
else if (raw instanceof Collection) {
List instances = new ArrayList<> ();
int index = 0;
for (Object o : Types.asCol (raw)) {
JsonInstance instance = new JsonInstance (getLocation ().append (ENUM).append (index), o);
instances.add (instance);
index++;
}
return Collections.unmodifiableCollection(instances);
}
// todo
throw new RuntimeException ();
}
@Override
public @Nullable JsonInstance getConst () {
if (!schemaObject.hasProperty (CONST)) {
return null;
}
Object raw = schemaObject.getRawValue (CONST);
return new JsonInstance (getLocation ().append (CONST), raw);
}
@Override
public Collection getType () {
boolean exists = schemaObject.hasProperty (TYPE);
if (!exists)
return Collections.emptyList ();
Object raw = schemaObject.getRawValue (TYPE);
if (raw instanceof String) {
String type = Types.convert ("", raw, String.class);
return Collections.singletonList (type);
}
else if (raw instanceof Collection) {
return Collections.unmodifiableCollection(Types.asCol(raw));
}
// todo
throw new RuntimeException ();
}
@Override
public Collection getAllOf () {
Collection allOf = getJsonSchemasOf (ALL_OF);
if (allOf == null)
return Collections.emptyList ();
return allOf;
}
@Override
public Collection getAnyOf () {
Collection anyOf = getJsonSchemasOf (ANY_OF);
if (anyOf == null)
return Collections.emptyList ();
return anyOf;
}
@Override
public Collection getOneOf () {
Collection oneOf = getJsonSchemasOf (ONE_OF);
if (oneOf == null)
return Collections.emptyList ();
return oneOf;
}
@Override
public @Nullable JsonSchema getNot () {
return getJsonSchemaOf (NOT);
}
@Override
public @Nullable String getFormat () {
return schemaObject.convert (FORMAT, new StringNullableConverter ());
}
@Override
public @Nullable JsonSchema getIf () {
return getJsonSchemaOf (IF);
}
@Override
public @Nullable JsonSchema getThen () {
return getJsonSchemaOf (THEN);
}
@Override
public @Nullable JsonSchema getElse () {
return getJsonSchemaOf (ELSE);
}
@Override
public String toString () {
return String.format ("%s", schemaObject.getLocation ());
}
private @Nullable JsonSchema getJsonSchemaOf (String property) {
return schemaObject.convert (property, new JsonSchemaConverter (context));
}
private @Nullable Collection getJsonSchemasOf (String property) {
return schemaObject.convert (property, new JsonSchemasConverter (context));
}
private Bucket getBucketProperties (Bucket schemaBucket) {
Bucket bucket = schemaBucket.convert (PROPERTIES, new BucketConverter (schemaBucket));
if (bucket == null)
return Bucket.empty ();
return bucket;
}
}