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;