diff --git a/core/pom.xml b/core/pom.xml index 53dc2efd..e621343a 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -101,81 +101,18 @@ ${project.build.directory}/jsonschematests - **/tests/draft6/boolean_schema.json - **/tests/draft7/boolean_schema.json - **/tests/draft2019-09/boolean_schema.json **/tests/draft2020-12/boolean_schema.json - **/tests/draft-next/boolean_schema.json - - **/tests/draft4/type.json - **/tests/draft6/type.json - **/tests/draft7/type.json - **/tests/draft2019-09/type.json **/tests/draft2020-12/type.json - **/tests/draft-next/type.json - - **/tests/draft3/minLength.json - **/tests/draft4/minLength.json - **/tests/draft6/minLength.json - **/tests/draft7/minLength.json - **/tests/draft2019-09/minLength.json **/tests/draft2020-12/minLength.json - **/tests/draft-next/minLength.json - - **/tests/draft4/maxLength.json - **/tests/draft6/maxLength.json - **/tests/draft7/maxLength.json - **/tests/draft2019-09/maxLength.json **/tests/draft2020-12/maxLength.json - **/tests/draft-next/maxLength.json - - **/tests/draft3/pattern.json - **/tests/draft4/pattern.json - **/tests/draft6/pattern.json - **/tests/draft7/pattern.json - **/tests/draft2019-09/pattern.json **/tests/draft2020-12/pattern.json - **/tests/draft-next/pattern.json - - **/tests/draft6/minimum.json - **/tests/draft7/minimum.json - **/tests/draft2019-09/minimum.json **/tests/draft2020-12/minimum.json - **/tests/draft-next/minimum.json - - **/tests/draft6/exclusiveMinimum.json - **/tests/draft7/exclusiveMinimum.json - **/tests/draft2019-09/exclusiveMinimum.json **/tests/draft2020-12/exclusiveMinimum.json - **/tests/draft-next/exclusiveMinimum.json - - **/tests/draft6/maximum.json - **/tests/draft7/maximum.json - **/tests/draft2019-09/maximum.json **/tests/draft2020-12/maximum.json - **/tests/draft-next/maximum.json - - **/tests/draft6/exclusiveMaximum.json - **/tests/draft7/exclusiveMaximum.json - **/tests/draft2019-09/exclusiveMaximum.json **/tests/draft2020-12/exclusiveMaximum.json - **/tests/draft-next/exclusiveMaximum.json - - **/tests/draft4/multipleOf.json - **/tests/draft6/multipleOf.json - **/tests/draft7/multipleOf.json - **/tests/draft2019-09/multipleOf.json **/tests/draft2020-12/multipleOf.json - **/tests/draft-next/multipleOf.json - diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/BasicVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/BasicVocabulary.java new file mode 100644 index 00000000..4dc6adc8 --- /dev/null +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/BasicVocabulary.java @@ -0,0 +1,42 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import java.net.URI; +import java.util.Optional; + +final class BasicVocabulary implements Vocabulary { + + @Override + public URI id() { + return URI.create("http://https://github.com/sebastian-toepfer/json-schema/basic"); + } + + @Override + public Optional findKeywordTypeByName(final String name) { + return Optional.of(new UnknowKeywordType(name)); + } +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchema.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchema.java index b6086174..b211f356 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchema.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchema.java @@ -26,15 +26,23 @@ import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toList; +import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.Validator; import io.github.sebastiantoepfer.jsonschema.core.constraint.AllOfConstraint; import io.github.sebastiantoepfer.jsonschema.core.constraint.Constraint; import io.github.sebastiantoepfer.jsonschema.core.vocab.core.VocabularyKeywordType; +import io.github.sebastiantoepfer.jsonschema.keyword.Applicator; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.VocabularyDefinition; import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.VocabularyDefinitions; import jakarta.json.JsonObject; import jakarta.json.JsonValue; import java.util.Collection; +import java.util.List; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; final class DefaultJsonSchema extends AbstractJsonValueSchema { @@ -50,9 +58,8 @@ public Validator validator() { return asJsonObject() .entrySet() .stream() - .map(keyword -> keywords.createKeywordFor(this, keyword)) - .filter(Constraint.class::isInstance) - .map(k -> (Constraint) k) + .map(this::asContraint) + .flatMap(Optional::stream) .collect( collectingAndThen(toList(), constraints -> new DefaultValidator(new AllOfConstraint<>(constraints))) ); @@ -67,4 +74,57 @@ private Collection vocabulary() { .flatMap(VocabularyDefinitions::definitions) .toList(); } + + private Optional> asContraint(final Entry property) { + final Keyword keyword = keywords.createKeywordFor(this, property); + final Constraint result; + if (keyword.hasCategory(Keyword.KeywordCategory.ASSERTION)) { + result = new AssertionConstraint(keyword.asAssertion()); + } else if (keyword.hasCategory(Keyword.KeywordCategory.APPLICATOR)) { + result = new ApplicatorConstaint(keyword.asApplicator()); + } else { + result = null; + } + return Optional.ofNullable(result); + } + + private static final class AssertionConstraint implements Constraint { + + private final Assertion assertion; + + public AssertionConstraint(final Assertion assertion) { + this.assertion = Objects.requireNonNull(assertion); + } + + @Override + public Collection violationsBy(final JsonValue value) { + final Collection result; + if (assertion.isValidFor(value)) { + result = List.of(); + } else { + result = List.of(new ConstraintViolation()); + } + return result; + } + } + + private static final class ApplicatorConstaint implements Constraint { + + private final Applicator applicator; + + public ApplicatorConstaint(final Applicator applicator) { + this.applicator = Objects.requireNonNull(applicator); + } + + @Override + public Collection violationsBy(final JsonValue value) { + final Collection result; + if (applicator.applyTo(value)) { + result = List.of(); + } else { + result = List.of(new ConstraintViolation()); + } + return result; + } + } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/Keywords.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/Keywords.java index 793afba5..558ec122 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/Keywords.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/Keywords.java @@ -28,8 +28,9 @@ import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.Vocabulary; -import io.github.sebastiantoepfer.jsonschema.core.vocab.basic.BasicVocabulary; -import io.github.sebastiantoepfer.jsonschema.core.vocab.core.CoreLazyVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.applicator.ApplicatorVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.core.CoreVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.ValidationVocabulary; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.VocabularyDefinition; import jakarta.json.JsonValue; @@ -46,13 +47,16 @@ final class Keywords { private static final Map MANDANTORY_VOCABS; + private static final Collection DEFAULT_VOCABS; static { MANDANTORY_VOCABS = List - .of(new BasicVocabulary(), new CoreLazyVocabulary().vocab()) + .of(new BasicVocabulary(), new CoreVocabulary()) .stream() .collect(toMap(Vocabulary::id, Function.identity())); + + DEFAULT_VOCABS = List.of(new ValidationVocabulary(), new ApplicatorVocabulary()); } private final Collection vocabularies; @@ -69,7 +73,7 @@ public Keywords(final Collection vocabDefs) { vocabularies = Stream .concat( - MANDANTORY_VOCABS.values().stream(), + Stream.concat(MANDANTORY_VOCABS.values().stream(), DEFAULT_VOCABS.stream()), vocabDefs.stream().map(VocabularyDefinition::findVocabulary).flatMap(Optional::stream) ) .collect( diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/UnknowKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/UnknowKeywordType.java similarity index 96% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/UnknowKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/UnknowKeywordType.java index cad85212..a23d3541 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/UnknowKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/UnknowKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core; import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.keyword.DefaultAnnotation; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/OfficialVocabularies.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/OfficialVocabularies.java new file mode 100644 index 00000000..269de07c --- /dev/null +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/OfficialVocabularies.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.applicator.ApplicatorVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.content.ContentVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.core.CoreVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.format.FormatVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.meta.MetaDataVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.unevaluated.UnevaluatedVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.ValidationVocabulary; +import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies; +import java.net.URI; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +public final class OfficialVocabularies implements LazyVocabularies { + + private static final Collection OFFICEAL_VOCABS; + + static { + OFFICEAL_VOCABS = + List.of( + new CoreVocabulary(), + new ApplicatorVocabulary(), + new ValidationVocabulary(), + new MetaDataVocabulary(), + new FormatVocabulary(), + new UnevaluatedVocabulary(), + new ContentVocabulary() + ); + } + + @Override + public Optional loadVocabularyWithId(final URI id) { + return OFFICEAL_VOCABS.stream().filter(vocab -> vocab.id().equals(id)).findFirst(); + } +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ApplicatorVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ApplicatorVocabulary.java new file mode 100644 index 00000000..ff10d6ee --- /dev/null +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ApplicatorVocabulary.java @@ -0,0 +1,53 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab.applicator; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary; +import java.net.URI; +import java.util.Optional; + +public final class ApplicatorVocabulary implements Vocabulary { + + private final Vocabulary vocab; + + public ApplicatorVocabulary() { + this.vocab = + new DefaultVocabulary( + URI.create("https://json-schema.org/draft/2020-12/vocab/applicator"), + new ItemsKeywordType() + ); + } + + @Override + public URI id() { + return vocab.id(); + } + + @Override + public Optional findKeywordTypeByName(final String name) { + return vocab.findKeywordTypeByName(name); + } +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ItemsKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordType.java similarity index 80% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ItemsKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordType.java index 16a2f1fa..52b1a360 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ItemsKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordType.java @@ -21,21 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.applicator; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.JsonSchemas; import io.github.sebastiantoepfer.jsonschema.JsonSubSchema; import io.github.sebastiantoepfer.jsonschema.Validator; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Annotation; +import io.github.sebastiantoepfer.jsonschema.keyword.Applicator; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonArray; import jakarta.json.JsonValue; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Objects; @@ -51,7 +50,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { return new ItemsKeyword(schema, JsonSchemas.load(value)); } - private class ItemsKeyword implements ConstraintAssertion, JsonSubSchema { + private class ItemsKeyword implements Applicator, Annotation, JsonSubSchema { private final JsonSchema owner; private final JsonSchema schema; @@ -82,14 +81,18 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - final Collection result; - if (!InstanceType.ARRAY.isInstance(value) || matchesSchema(value.asJsonArray())) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + public Collection categories() { + return List.of(KeywordCategory.APPLICATOR, KeywordCategory.ANNOTATION); + } + + @Override + public JsonValue value() { + return JsonValue.TRUE; + } + + @Override + public boolean applyTo(final JsonValue instance) { + return !InstanceType.ARRAY.isInstance(instance) || matchesSchema(instance.asJsonArray()); } private boolean matchesSchema(final JsonArray items) { diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/content/ContentVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/content/ContentVocabulary.java new file mode 100644 index 00000000..25c46fb4 --- /dev/null +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/content/ContentVocabulary.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab.content; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary; +import java.net.URI; +import java.util.Optional; + +public final class ContentVocabulary implements Vocabulary { + + private final Vocabulary vocab; + + public ContentVocabulary() { + this.vocab = new DefaultVocabulary(URI.create("https://json-schema.org/draft/2020-12/vocab/content")); + } + + @Override + public URI id() { + return vocab.id(); + } + + @Override + public Optional findKeywordTypeByName(final String name) { + return Optional.empty(); + } +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreLazyVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreVocabulary.java similarity index 77% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreLazyVocabulary.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreVocabulary.java index 9e0ea27c..ddbfe001 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreLazyVocabulary.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreVocabulary.java @@ -24,17 +24,16 @@ package io.github.sebastiantoepfer.jsonschema.core.vocab.core; import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary; -import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies; import java.net.URI; -import java.util.Objects; import java.util.Optional; -public final class CoreLazyVocabulary implements LazyVocabularies { +public final class CoreVocabulary implements Vocabulary { private final Vocabulary vocab; - public CoreLazyVocabulary() { + public CoreVocabulary() { this.vocab = new DefaultVocabulary( URI.create("https://json-schema.org/draft/2020-12/vocab/core"), @@ -48,18 +47,13 @@ public CoreLazyVocabulary() { ); } - public Vocabulary vocab() { - return vocab; + @Override + public URI id() { + return vocab.id(); } @Override - public Optional loadVocabularyWithId(final URI id) { - final Optional result; - if (Objects.equals(id, vocab.id())) { - result = Optional.of(vocab); - } else { - result = Optional.empty(); - } - return result; + public Optional findKeywordTypeByName(final String name) { + return vocab.findKeywordTypeByName(name); } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordType.java index dfea7f9f..1cf89dd6 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordType.java @@ -23,11 +23,13 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.core; +import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.keyword.DefaultAnnotation; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import io.github.sebastiantoepfer.jsonschema.keyword.ReservedLocation; import jakarta.json.JsonValue; +import java.util.Objects; /** * @@ -42,6 +44,18 @@ public String name() { @Override public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { - return new DefaultAnnotation(name(), value); + if (InstanceType.OBJECT.isInstance(value)) { + return new DefsKeyword(); + } else { + throw new IllegalArgumentException("must be an object!"); + } + } + + private class DefsKeyword implements ReservedLocation { + + @Override + public boolean hasName(final String name) { + return Objects.equals(name(), name); + } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordType.java index 67b693b0..59674c01 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordType.java @@ -23,11 +23,15 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.core; +import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.keyword.DefaultAnnotation; +import io.github.sebastiantoepfer.jsonschema.keyword.Identifier; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import jakarta.json.JsonString; import jakarta.json.JsonValue; +import java.net.URI; +import java.util.Objects; /** * @@ -42,6 +46,29 @@ public String name() { @Override public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { - return new DefaultAnnotation(name(), value); + if (InstanceType.STRING.isInstance(value)) { + return new IdKeyword((JsonString) value); + } else { + throw new IllegalArgumentException("must be a string!"); + } + } + + private class IdKeyword implements Identifier { + + private final URI uri; + + private IdKeyword(final JsonString uri) { + this.uri = URI.create(uri.getString()); + } + + @Override + public URI asUri() { + return uri; + } + + @Override + public boolean hasName(final String name) { + return Objects.equals(name(), name); + } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordType.java index 234d814b..11a8240d 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordType.java @@ -23,11 +23,19 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.core; +import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; +import io.github.sebastiantoepfer.jsonschema.JsonSchemas; import io.github.sebastiantoepfer.jsonschema.keyword.Applicator; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import jakarta.json.Json; +import jakarta.json.JsonPointer; +import jakarta.json.JsonReader; +import jakarta.json.JsonString; import jakarta.json.JsonValue; +import java.io.IOException; +import java.net.URI; import java.util.Objects; /** @@ -43,16 +51,75 @@ public String name() { @Override public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { - return new Applicator() { - @Override - public boolean applyTo(final JsonValue instance) { - return true; //something is wrong here + if (InstanceType.STRING.isInstance(value)) { + return new RefKeyword(schema, (JsonString) value); + } else { + throw new IllegalArgumentException("must be a string"); + } + } + + private class RefKeyword implements Applicator { + + private final JsonSchema schema; + private final URI uri; + + private RefKeyword(final JsonSchema schema, final JsonString uri) { + this.schema = schema; + this.uri = URI.create(uri.getString()); + } + + @Override + public boolean applyTo(final JsonValue instance) { + return retrieveJsonSchema().validator().validate(instance).isEmpty(); + } + + @Override + public boolean hasName(final String name) { + return Objects.equals(name(), name); + } + + private JsonSchema retrieveJsonSchema() { + final JsonValue json; + try { + if (isRemote()) { + json = retrieveValueFromRemoteLocation(); + } else { + json = retrievValueFromLocalSchema(); + } + return JsonSchemas.load(json); + } catch (IOException ex) { + throw new IllegalStateException("can not load schema!", ex); + } + } + + private JsonValue retrievValueFromLocalSchema() throws IOException { + final JsonPointer pointer = createPointer(); + if (schema.getValueType() == JsonValue.ValueType.OBJECT && pointer.containsValue(schema.asJsonObject())) { + return pointer.getValue(schema.asJsonObject()); + } else { + throw new IOException("can not find referenced value."); } + } - @Override - public boolean hasName(final String name) { - return Objects.equals(name(), name); + private JsonPointer createPointer() { + final String fragment = uri.getFragment(); + final JsonPointer pointer; + if (fragment.startsWith("/")) { + pointer = Json.createPointer(fragment); + } else { + pointer = Json.createPointer("/".concat(fragment)); } - }; + return pointer; + } + + private JsonValue retrieveValueFromRemoteLocation() throws IOException { + try (final JsonReader reader = Json.createReader(uri.toURL().openStream())) { + return reader.readValue(); + } + } + + private boolean isRemote() { + return uri.getScheme() != null; + } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordType.java index a8192bec..e84d57af 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordType.java @@ -23,11 +23,15 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.core; +import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.keyword.DefaultAnnotation; +import io.github.sebastiantoepfer.jsonschema.keyword.Identifier; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import jakarta.json.JsonString; import jakarta.json.JsonValue; +import java.net.URI; +import java.util.Objects; /** * @@ -42,6 +46,29 @@ public String name() { @Override public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { - return new DefaultAnnotation(name(), value); + if (InstanceType.STRING.isInstance(value)) { + return new SchemaKeyword((JsonString) value); + } else { + throw new IllegalArgumentException("must be a string!"); + } + } + + private class SchemaKeyword implements Identifier { + + private final URI uri; + + private SchemaKeyword(final JsonString uri) { + this.uri = URI.create(uri.getString()); + } + + @Override + public URI asUri() { + return uri; + } + + @Override + public boolean hasName(final String name) { + return Objects.equals(name(), name); + } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/VocabularyKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/VocabularyKeywordType.java index 92177c7f..c7344eec 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/VocabularyKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/VocabularyKeywordType.java @@ -75,13 +75,14 @@ public final class VocabularyKeyword implements Keyword, VocabularyDefinitions { } @Override - public Collection categories() { - return List.of(); + public boolean hasName(final String name) { + return Objects.equals(name(), name); } @Override - public boolean hasName(final String name) { - return Objects.equals(name(), name); + public Collection categories() { + //is a identifier after spec ... but how to implement it as it? + return List.of(); } @Override diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/format/FormatVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/format/FormatVocabulary.java new file mode 100644 index 00000000..db418b97 --- /dev/null +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/format/FormatVocabulary.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab.format; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary; +import java.net.URI; +import java.util.Optional; + +public final class FormatVocabulary implements Vocabulary { + + private final Vocabulary vocab; + + public FormatVocabulary() { + this.vocab = new DefaultVocabulary(URI.create("https://json-schema.org/draft/2020-12/vocab/format-annotation")); + } + + @Override + public URI id() { + return vocab.id(); + } + + @Override + public Optional findKeywordTypeByName(final String name) { + return Optional.empty(); + } +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/meta/MetaDataVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/meta/MetaDataVocabulary.java new file mode 100644 index 00000000..95f6df78 --- /dev/null +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/meta/MetaDataVocabulary.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab.meta; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary; +import java.net.URI; +import java.util.Optional; + +public final class MetaDataVocabulary implements Vocabulary { + + private final Vocabulary vocab; + + public MetaDataVocabulary() { + this.vocab = new DefaultVocabulary(URI.create("https://json-schema.org/draft/2020-12/vocab/meta-data")); + } + + @Override + public URI id() { + return vocab.id(); + } + + @Override + public Optional findKeywordTypeByName(final String name) { + return Optional.empty(); + } +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/unevaluated/UnevaluatedVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/unevaluated/UnevaluatedVocabulary.java new file mode 100644 index 00000000..75bc746f --- /dev/null +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/unevaluated/UnevaluatedVocabulary.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab.unevaluated; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary; +import java.net.URI; +import java.util.Optional; + +public final class UnevaluatedVocabulary implements Vocabulary { + + private final Vocabulary vocab; + + public UnevaluatedVocabulary() { + this.vocab = new DefaultVocabulary(URI.create("https://json-schema.org/draft/2020-12/vocab/unevaluated")); + } + + @Override + public URI id() { + return vocab.id(); + } + + @Override + public Optional findKeywordTypeByName(final String name) { + return Optional.empty(); + } +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMaximumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMaximumKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordType.java index ae18dca2..1fd6c958 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMaximumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMinimumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMinimumKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordType.java index 938fa196..561d5b64 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMinimumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaxLengthKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaxLengthKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordType.java index b10564ab..2a022d33 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaxLengthKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaximumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaximumKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordType.java index b04dc35e..c78f2197 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaximumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinLengthKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinLengthKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordType.java index 010b9068..0f5b91d7 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinLengthKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinimumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinimumKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordType.java index 99ecbb78..0f09579d 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinimumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MultipleOfKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MultipleOfKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordType.java index aae9fdbf..e2a6f962 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MultipleOfKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/PatternKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordType.java similarity index 97% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/PatternKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordType.java index 800c734a..9066c6e9 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/PatternKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/TypeKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordType.java similarity index 98% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/TypeKeywordType.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordType.java index 6395b236..0a00beef 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/TypeKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toList; diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/BasicVocabulary.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ValidationVocabulary.java similarity index 79% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/BasicVocabulary.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ValidationVocabulary.java index ec37ea62..26a3ba21 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/BasicVocabulary.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ValidationVocabulary.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import io.github.sebastiantoepfer.jsonschema.Vocabulary; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; @@ -29,25 +29,23 @@ import java.net.URI; import java.util.Optional; -public final class BasicVocabulary implements Vocabulary { +public final class ValidationVocabulary implements Vocabulary { - private final DefaultVocabulary vocab; + private final Vocabulary vocab; - public BasicVocabulary() { + public ValidationVocabulary() { this.vocab = new DefaultVocabulary( - URI.create("http://https://github.com/sebastian-toepfer/json-schema/basic"), + URI.create("https://json-schema.org/draft/2020-12/vocab/validation"), new TypeKeywordType(), new MinLengthKeywordType(), new MaxLengthKeywordType(), new PatternKeywordType(), - new PatternKeywordType(), new MinimumKeywordType(), new ExclusiveMinimumKeywordType(), new MaximumKeywordType(), new ExclusiveMaximumKeywordType(), - new MultipleOfKeywordType(), - new ItemsKeywordType() + new MultipleOfKeywordType() ); } @@ -58,6 +56,6 @@ public URI id() { @Override public Optional findKeywordTypeByName(final String name) { - return Optional.of(vocab.findKeywordTypeByName(name).orElseGet(() -> new UnknowKeywordType(name))); + return vocab.findKeywordTypeByName(name); } } diff --git a/core/src/main/java/module-info.java b/core/src/main/java/module-info.java index 8b5dbe51..51f87de4 100644 --- a/core/src/main/java/module-info.java +++ b/core/src/main/java/module-info.java @@ -30,5 +30,5 @@ with io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; provides io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies - with io.github.sebastiantoepfer.jsonschema.core.vocab.core.CoreLazyVocabulary; + with io.github.sebastiantoepfer.jsonschema.core.vocab.OfficialVocabularies; } diff --git a/core/src/main/resources/META-INF/services/io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies b/core/src/main/resources/META-INF/services/io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies index 7924e0ef..701a4011 100644 --- a/core/src/main/resources/META-INF/services/io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies +++ b/core/src/main/resources/META-INF/services/io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies @@ -1 +1 @@ -io.github.sebastiantoepfer.jsonschema.core.vocab.core.CoreLazyVocabulary +io.github.sebastiantoepfer.jsonschema.core.vocab.OfficialVocabularies diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/BasicVocabularyTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/BasicVocabularyTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/BasicVocabularyTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/BasicVocabularyTest.java index c5369f86..869180d6 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/BasicVocabularyTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/BasicVocabularyTest.java @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import com.github.npathai.hamcrestopt.OptionalMatchers; +import io.github.sebastiantoepfer.jsonschema.core.BasicVocabulary; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonValue; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchemaTest.java index e0e3ac5b..cd2ec22d 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchemaTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/DefaultJsonSchemaTest.java @@ -37,12 +37,26 @@ class DefaultJsonSchemaTest { private final DefaultJsonSchema schema = new DefaultJsonSchema( - Json.createObjectBuilder().add("type", "string").build() + Json + .createObjectBuilder() + .add("type", "array") + .add("items", Json.createObjectBuilder().add("type", "integer")) + .build() ); @Test - void should_be_valid_for_string() { - assertThat(schema.validator().validate(Json.createValue("test")), is(empty())); + void should_be_valid_an_empty_array() { + assertThat(schema.validator().validate(JsonValue.EMPTY_JSON_ARRAY), is(empty())); + } + + @Test + void should_be_valid_an_integer_array() { + assertThat(schema.validator().validate(Json.createArrayBuilder().add(1).add(2).build()), is(empty())); + } + + @Test + void should_be_invalid_an_string_array() { + assertThat(schema.validator().validate(Json.createArrayBuilder().add("a").add("b").build()), is(not(empty()))); } @Test diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/KeywordsTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/KeywordsTest.java index fd6b3c02..beae460c 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/KeywordsTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/KeywordsTest.java @@ -29,8 +29,7 @@ import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertThrows; -import io.github.sebastiantoepfer.jsonschema.core.vocab.basic.BasicVocabulary; -import io.github.sebastiantoepfer.jsonschema.core.vocab.core.CoreLazyVocabulary; +import io.github.sebastiantoepfer.jsonschema.core.vocab.core.CoreVocabulary; import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.VocabularyDefinition; import java.net.URI; import java.util.Collection; @@ -42,7 +41,7 @@ class KeywordsTest { @Test void should_not_be_createbale_without_mandantory_core_vocabulary() { final Collection vocabDefs = List.of( - new VocabularyDefinition(new CoreLazyVocabulary().vocab().id(), false) + new VocabularyDefinition(new CoreVocabulary().id(), false) ); assertThrows(IllegalArgumentException.class, () -> new Keywords(vocabDefs)); } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/DefaultSchemaLoadTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/DefaultSchemaLoadTest.java new file mode 100644 index 00000000..240bed97 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/DefaultSchemaLoadTest.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.testsuite; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +import io.github.sebastiantoepfer.jsonschema.JsonSchemas; +import jakarta.json.Json; +import java.net.URI; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +class DefaultSchemaLoadTest { + + @Test + void should_load_default_json_schema() throws Exception { + assertThat( + JsonSchemas.load( + Json + .createReader(URI.create("https://json-schema.org/draft/2020-12/schema").toURL().openStream()) + .readValue() + ), + is(not(Matchers.nullValue())) + ); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/OfficialVocabulariesTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/OfficialVocabulariesTest.java new file mode 100644 index 00000000..08e48286 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/OfficialVocabulariesTest.java @@ -0,0 +1,54 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab; + +import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresentAndIs; +import static org.hamcrest.MatcherAssert.assertThat; + +import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import java.net.URI; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class OfficialVocabulariesTest { + + @ParameterizedTest + @ValueSource( + strings = { + "https://json-schema.org/draft/2020-12/vocab/core", + "https://json-schema.org/draft/2020-12/vocab/applicator", + "https://json-schema.org/draft/2020-12/vocab/validation", + "https://json-schema.org/draft/2020-12/vocab/meta-data", + "https://json-schema.org/draft/2020-12/vocab/format-annotation", + "https://json-schema.org/draft/2020-12/vocab/unevaluated", + "https://json-schema.org/draft/2020-12/vocab/content", + } + ) + void should_load_all_offical_vocabs(final String id) { + assertThat( + new OfficialVocabularies().loadVocabularyWithId(URI.create(id)).map(Vocabulary::id).map(URI::toString), + isPresentAndIs(id) + ); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ApplicatorVocabularyTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ApplicatorVocabularyTest.java new file mode 100644 index 00000000..8ad288fd --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ApplicatorVocabularyTest.java @@ -0,0 +1,41 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.vocab.applicator; + +import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresentAndIs; +import static org.hamcrest.MatcherAssert.assertThat; + +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; +import org.junit.jupiter.api.Test; + +class ApplicatorVocabularyTest { + + @Test + void should_find_items_keyword() { + assertThat( + new ApplicatorVocabulary().findKeywordTypeByName("items").map(KeywordType::name), + isPresentAndIs("items") + ); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ItemsKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordTypeTest.java similarity index 76% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ItemsKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordTypeTest.java index 52e6eedf..eca41eea 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ItemsKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordTypeTest.java @@ -21,9 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.applicator; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; import io.github.sebastiantoepfer.jsonschema.JsonSchema; @@ -54,8 +55,8 @@ void should_be_invalid_if_items_does_not_match_schema() { new DefaultJsonSchemaFactory().create(JsonValue.TRUE), Json.createObjectBuilder().add("type", "number").build() ) - .asAssertion() - .isValidFor(Json.createArrayBuilder().add(1).add("invalid").add(2).build()), + .asApplicator() + .applyTo(Json.createArrayBuilder().add(1).add("invalid").add(2).build()), is(false) ); } @@ -68,8 +69,8 @@ void should_be_valid_if_all_items_match_schema() { new DefaultJsonSchemaFactory().create(JsonValue.TRUE), Json.createObjectBuilder().add("type", "number").build() ) - .asAssertion() - .isValidFor(Json.createArrayBuilder().add(1).add(2).build()), + .asApplicator() + .applyTo(Json.createArrayBuilder().add(1).add(2).build()), is(true) ); } @@ -94,4 +95,25 @@ void should_return_his_json_valuetype() { is(JsonValue.ValueType.OBJECT) ); } + + @Test + void should_be_applicator_and_annotation() { + assertThat( + new ItemsKeywordType() + .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT) + .categories(), + contains(Keyword.KeywordCategory.APPLICATOR, Keyword.KeywordCategory.ANNOTATION) + ); + } + + @Test + void should_produces_true_if_is_applied_to_any_instance() { + assertThat( + new ItemsKeywordType() + .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT) + .asAnnotation() + .value(), + is(JsonValue.TRUE) + ); + } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreLazyVocabularyTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreVocabularyTest.java similarity index 68% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreLazyVocabularyTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreVocabularyTest.java index a862b625..34142a9b 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreLazyVocabularyTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/CoreVocabularyTest.java @@ -23,28 +23,26 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.core; -import static com.github.npathai.hamcrestopt.OptionalMatchers.isEmpty; -import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresentAndIs; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; -import io.github.sebastiantoepfer.jsonschema.Vocabulary; +import com.github.npathai.hamcrestopt.OptionalMatchers; +import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import java.net.URI; import org.junit.jupiter.api.Test; -class CoreLazyVocabularyTest { +class CoreVocabularyTest { @Test - void should_return_empty_for_non_core_id() { - assertThat(new CoreLazyVocabulary().loadVocabularyWithId(URI.create("")), isEmpty()); + void should_return_core_vocabulary_for_core_id() { + assertThat(new CoreVocabulary().id(), is(URI.create("https://json-schema.org/draft/2020-12/vocab/core"))); } @Test - void should_return_core_vocabulary_for_core_id() { + void should_load_schema_keyword() { assertThat( - new CoreLazyVocabulary() - .loadVocabularyWithId(URI.create("https://json-schema.org/draft/2020-12/vocab/core")) - .map(Vocabulary::id), - isPresentAndIs(URI.create("https://json-schema.org/draft/2020-12/vocab/core")) + new CoreVocabulary().findKeywordTypeByName("$schema").map(KeywordType::name), + OptionalMatchers.isPresentAndIs("$schema") ); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordTypeTest.java index 10131d5b..1343f69e 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/DefsKeywordTypeTest.java @@ -25,20 +25,28 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.JsonValue; import org.junit.jupiter.api.Test; class DefsKeywordTypeTest { @Test - void should_create_keyword_with_name() { - assertThat( - new DefsKeywordType() - .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT) - .hasName("$defs"), - is(true) - ); + void should_not_be_creatable_from_non_objects() { + final DefsKeywordType schema = new DefsKeywordType(); + + assertThrows(IllegalArgumentException.class, () -> schema.createKeyword(null, JsonValue.FALSE)); + } + + @Test + void should_know_his_name() { + final Keyword defs = new DefsKeywordType() + .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT); + + assertThat(defs.hasName("$defs"), is(true)); + assertThat(defs.hasName("test"), is(false)); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordTypeTest.java index e9a76126..9042615d 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/IdKeywordTypeTest.java @@ -25,20 +25,44 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; +import jakarta.json.Json; import jakarta.json.JsonValue; +import java.net.URI; import org.junit.jupiter.api.Test; class IdKeywordTypeTest { @Test - void should_create_keyword_with_name() { + void should_not_be_creatable_from_non_string() { + final IdKeywordType schema = new IdKeywordType(); + + assertThrows(IllegalArgumentException.class, () -> schema.createKeyword(null, JsonValue.FALSE)); + } + + @Test + void should_know_his_name() { + final Keyword id = new IdKeywordType() + .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), Json.createValue("/test")); + + assertThat(id.hasName("$id"), is(true)); + assertThat(id.hasName("test"), is(false)); + } + + @Test + void should_retun_his_uri() { assertThat( new IdKeywordType() - .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT) - .hasName("$id"), - is(true) + .createKeyword( + new DefaultJsonSchemaFactory().create(JsonValue.TRUE), + Json.createValue("https://json-schema.org/draft/2020-12/schema") + ) + .asIdentifier() + .asUri(), + is(URI.create("https://json-schema.org/draft/2020-12/schema")) ); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordTypeTest.java index dbbd8638..004ea800 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/RefKeywordTypeTest.java @@ -25,32 +25,75 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; +import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; +import jakarta.json.Json; import jakarta.json.JsonValue; import org.junit.jupiter.api.Test; class RefKeywordTypeTest { @Test - void should_create_keyword_with_name() { - assertThat( - new RefKeywordType() - .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT) - .hasName("$ref"), - is(true) - ); + void should_be_not_createbale_from_non_string() { + final RefKeywordType keywordType = new RefKeywordType(); + final JsonSchema schema = new DefaultJsonSchemaFactory().create(JsonValue.TRUE); + assertThrows(IllegalArgumentException.class, () -> keywordType.createKeyword(schema, JsonValue.TRUE)); } @Test - void notFinischedYet() { + void should_know_his_name() { + final Keyword ref = new RefKeywordType() + .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), Json.createValue("#")); + + assertThat(ref.hasName("$ref"), is(true)); + assertThat(ref.hasName("test"), is(false)); + } + + @Test + void should_use_local_referenced_schema_for_validation() { final Keyword keyword = new RefKeywordType() - .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.FALSE); + .createKeyword( + new DefaultJsonSchemaFactory() + .create( + Json + .createObjectBuilder() + .add( + "$defs", + Json + .createObjectBuilder() + .add("positiveInteger", Json.createObjectBuilder().add("type", "integer")) + ) + .build() + ), + Json.createValue("#/$defs/positiveInteger") + ); - assertThat(keyword.hasName("$ref"), is(true)); - assertThat(keyword.hasName("$id"), is(false)); + assertThat(keyword.asApplicator().applyTo(Json.createValue(1L)), is(true)); + assertThat(keyword.asApplicator().applyTo(Json.createValue("invalid")), is(false)); + } + + @Test + void should_use_remote_referenced_schema_for_validation() { + final Keyword keyword = new RefKeywordType() + .createKeyword( + new DefaultJsonSchemaFactory() + .create( + Json + .createObjectBuilder() + .add( + "$defs", + Json + .createObjectBuilder() + .add("positiveInteger", Json.createObjectBuilder().add("type", "integer")) + ) + .build() + ), + Json.createValue("#/$defs/positiveInteger") + ); - assertThat(keyword.asApplicator().applyTo(JsonValue.TRUE), is(true)); + assertThat(keyword.asApplicator().applyTo(Json.createValue(1L)), is(true)); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordTypeTest.java index 5f33d354..19f6198e 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/core/SchemaKeywordTypeTest.java @@ -25,20 +25,44 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; +import jakarta.json.Json; import jakarta.json.JsonValue; +import java.net.URI; import org.junit.jupiter.api.Test; class SchemaKeywordTypeTest { @Test - void should_create_keyword_with_name() { + void should_not_be_creatable_from_non_string() { + final SchemaKeywordType schema = new SchemaKeywordType(); + + assertThrows(IllegalArgumentException.class, () -> schema.createKeyword(null, JsonValue.FALSE)); + } + + @Test + void should_know_his_name() { + final Keyword schema = new SchemaKeywordType() + .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), Json.createValue("/test")); + + assertThat(schema.hasName("$schema"), is(true)); + assertThat(schema.hasName("test"), is(false)); + } + + @Test + void should_retun_his_uri() { assertThat( new SchemaKeywordType() - .createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT) - .hasName("$schema"), - is(true) + .createKeyword( + new DefaultJsonSchemaFactory().create(JsonValue.TRUE), + Json.createValue("https://json-schema.org/draft/2020-12/schema") + ) + .asIdentifier() + .asUri(), + is(URI.create("https://json-schema.org/draft/2020-12/schema")) ); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMaximumKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordTypeTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMaximumKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordTypeTest.java index 907374d7..3beab264 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMaximumKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordTypeTest.java @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.ExclusiveMaximumKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonValue; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMinimumKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordTypeTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMinimumKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordTypeTest.java index ea1d0ebd..fdfff96d 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/ExclusiveMinimumKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordTypeTest.java @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.ExclusiveMinimumKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonValue; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaxLengthKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordTypeTest.java similarity index 93% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaxLengthKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordTypeTest.java index 37d9b75f..db537124 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaxLengthKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordTypeTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -29,6 +29,8 @@ import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.MaxLengthKeywordType; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.MinLengthKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonNumber; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaximumKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordTypeTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaximumKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordTypeTest.java index 6748c608..e8ccbc6a 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MaximumKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordTypeTest.java @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.MaximumKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonValue; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinLengthKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordTypeTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinLengthKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordTypeTest.java index 807c1be3..1bb69a83 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinLengthKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordTypeTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -29,6 +29,7 @@ import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.MinLengthKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonNumber; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinimumKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordTypeTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinimumKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordTypeTest.java index 23b85aa1..c7d35244 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MinimumKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordTypeTest.java @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.MinimumKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonValue; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MultipleOfKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordTypeTest.java similarity index 96% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MultipleOfKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordTypeTest.java index 2f818951..36a10488 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/MultipleOfKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordTypeTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -29,6 +29,7 @@ import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.MultipleOfKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonValue; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/PatternKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordTypeTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/PatternKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordTypeTest.java index 57ff8dc1..09031c6d 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/PatternKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordTypeTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -29,6 +29,7 @@ import io.github.sebastiantoepfer.jsonschema.JsonSchema; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.PatternKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.Json; import jakarta.json.JsonValue; diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/TypeKeywordTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordTypeTest.java similarity index 95% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/TypeKeywordTypeTest.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordTypeTest.java index 3fc93b7d..5b56cc7a 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/basic/TypeKeywordTypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordTypeTest.java @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab.basic; +package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import io.github.sebastiantoepfer.jsonschema.core.DefaultJsonSchemaFactory; +import io.github.sebastiantoepfer.jsonschema.core.vocab.validation.TypeKeywordType; import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import jakarta.json.Json; import jakarta.json.JsonValue;