From a8d8be968eebf7ccd258bcf5b4a66eaa1d37363e Mon Sep 17 00:00:00 2001 From: Sebastian Toepfer <61313468+sebastian-toepfer@users.noreply.github.com> Date: Wed, 11 Oct 2023 05:18:55 +0200 Subject: [PATCH 1/2] remove ConstraintViolation --- .../jsonschema/Validator.java | 7 +- .../jsonschema/core/DefaultJsonSchema.java | 61 +++------------- .../jsonschema/core/DefaultValidator.java | 12 ++-- .../jsonschema/core/EmptyJsonSchema.java | 4 +- .../jsonschema/core/FalseJsonSchema.java | 4 +- .../jsonschema/core/TrueJsonSchema.java | 4 +- .../AllOfCondition.java} | 22 ++---- .../ApplicatorBasedCondtion.java} | 20 ++++-- .../AssertionBasedCondition.java} | 20 +++--- .../jsonschema/core/codition/Condition.java | 6 +- .../NoCondition.java} | 11 +-- .../UnfulfillableCondition.java} | 12 ++-- .../core/constraint/AnyConstraint.java | 59 --------------- .../AdditionalPropertiesKeywordType.java | 2 +- .../vocab/applicator/ItemsKeywordType.java | 6 +- .../PatternPropertiesKeywordType.java | 2 +- .../applicator/PrefixItemsKeywordType.java | 2 +- .../applicator/PropertiesKeywordType.java | 2 +- .../core/vocab/core/RefKeywordType.java | 2 +- .../ExclusiveMaximumKeywordType.java | 21 ++---- .../ExclusiveMinimumKeywordType.java | 21 ++---- .../validation/MaxLengthKeywordType.java | 20 ++---- .../vocab/validation/MaximumKeywordType.java | 21 ++---- .../validation/MinLengthKeywordType.java | 20 ++---- .../vocab/validation/MinimumKeywordType.java | 21 ++---- .../validation/MultipleOfKeywordType.java | 24 ++----- .../vocab/validation/PatternKeywordType.java | 20 ++---- .../vocab/validation/TypeKeywordType.java | 48 ++++--------- .../core/DefaultJsonSchemaTest.java | 9 ++- .../jsonschema/core/EmptyJsonSchemaTest.java | 3 +- .../jsonschema/core/FalseJsonSchemaTest.java | 3 +- .../jsonschema/core/TrueJsonSchemaTest.java | 3 +- .../JsonTestSuiteTestCaseProvider.java | 5 +- .../core/vocab/ConstraintAssertionTest.java | 71 ------------------- 34 files changed, 149 insertions(+), 419 deletions(-) rename core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/{constraint/AllOfConstraint.java => codition/AllOfCondition.java} (66%) rename core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/{constraint/UnfulfillableConstraint.java => codition/ApplicatorBasedCondtion.java} (68%) rename core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/{vocab/ConstraintAssertion.java => codition/AssertionBasedCondition.java} (74%) rename api/src/main/java/io/github/sebastiantoepfer/jsonschema/ConstraintViolation.java => core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/Condition.java (89%) rename core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/{constraint/Constraint.java => codition/NoCondition.java} (81%) rename core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/{constraint/NoConstraint.java => codition/UnfulfillableCondition.java} (77%) delete mode 100644 core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/AnyConstraint.java delete mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/ConstraintAssertionTest.java diff --git a/api/src/main/java/io/github/sebastiantoepfer/jsonschema/Validator.java b/api/src/main/java/io/github/sebastiantoepfer/jsonschema/Validator.java index 26c6305e..d0e6b869 100644 --- a/api/src/main/java/io/github/sebastiantoepfer/jsonschema/Validator.java +++ b/api/src/main/java/io/github/sebastiantoepfer/jsonschema/Validator.java @@ -27,14 +27,13 @@ import jakarta.json.JsonReader; import jakarta.json.JsonValue; import java.io.StringReader; -import java.util.Collection; public interface Validator { - default Collection validate(final String data) { + default boolean isValid(final String data) { try (final JsonReader reader = Json.createReader(new StringReader(data))) { - return validate(reader.readValue()); + return isValid(reader.readValue()); } } - Collection validate(final JsonValue data); + boolean isValid(final JsonValue data); } 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 8160a61f..c69923c5 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,21 +26,18 @@ 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.codition.AllOfCondition; +import io.github.sebastiantoepfer.jsonschema.core.codition.ApplicatorBasedCondtion; +import io.github.sebastiantoepfer.jsonschema.core.codition.AssertionBasedCondition; +import io.github.sebastiantoepfer.jsonschema.core.codition.Condition; 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.Objects; import java.util.Optional; import java.util.stream.Stream; @@ -59,7 +56,7 @@ public Validator validator() { .map(this::asContraint) .flatMap(Optional::stream) .collect( - collectingAndThen(toList(), constraints -> new DefaultValidator(new AllOfConstraint<>(constraints))) + collectingAndThen(toList(), constraints -> new DefaultValidator(new AllOfCondition<>(constraints))) ); } @@ -82,55 +79,15 @@ private Stream keywords() { return asJsonObject().entrySet().stream().map(property -> keywords.createKeywordFor(this, property)); } - private Optional> asContraint(final Keyword keyword) { - final Constraint result; + private Optional> asContraint(final Keyword keyword) { + final Condition result; if (keyword.hasCategory(Keyword.KeywordCategory.ASSERTION)) { - result = new AssertionConstraint(keyword.asAssertion()); + result = new AssertionBasedCondition(keyword.asAssertion()); } else if (keyword.hasCategory(Keyword.KeywordCategory.APPLICATOR)) { - result = new ApplicatorConstaint(keyword.asApplicator()); + result = new ApplicatorBasedCondtion(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/DefaultValidator.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/DefaultValidator.java index 62d35a2e..2f7c4c03 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/DefaultValidator.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/DefaultValidator.java @@ -23,23 +23,21 @@ */ package io.github.sebastiantoepfer.jsonschema.core; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.Validator; -import io.github.sebastiantoepfer.jsonschema.core.constraint.Constraint; +import io.github.sebastiantoepfer.jsonschema.core.codition.Condition; import jakarta.json.JsonValue; -import java.util.Collection; import java.util.Objects; final class DefaultValidator implements Validator { - private final Constraint contraint; + private final Condition contraint; - public DefaultValidator(final Constraint contraint) { + public DefaultValidator(final Condition contraint) { this.contraint = Objects.requireNonNull(contraint); } @Override - public Collection validate(final JsonValue data) { - return contraint.violationsBy(data); + public boolean isValid(final JsonValue data) { + return contraint.isFulfilledBy(data); } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchema.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchema.java index 59d4a79b..1282dd9e 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchema.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchema.java @@ -24,7 +24,7 @@ package io.github.sebastiantoepfer.jsonschema.core; import io.github.sebastiantoepfer.jsonschema.Validator; -import io.github.sebastiantoepfer.jsonschema.core.constraint.NoConstraint; +import io.github.sebastiantoepfer.jsonschema.core.codition.NoCondition; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.JsonValue; import java.util.Optional; @@ -37,7 +37,7 @@ public EmptyJsonSchema() { @Override public Validator validator() { - return new DefaultValidator(new NoConstraint<>()); + return new DefaultValidator(new NoCondition<>()); } @Override diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchema.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchema.java index 42b46b2c..942b6e9d 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchema.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchema.java @@ -24,7 +24,7 @@ package io.github.sebastiantoepfer.jsonschema.core; import io.github.sebastiantoepfer.jsonschema.Validator; -import io.github.sebastiantoepfer.jsonschema.core.constraint.UnfulfillableConstraint; +import io.github.sebastiantoepfer.jsonschema.core.codition.UnfulfillableCondition; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.JsonValue; import java.util.Optional; @@ -37,7 +37,7 @@ public FalseJsonSchema() { @Override public Validator validator() { - return new DefaultValidator(new UnfulfillableConstraint<>()); + return new DefaultValidator(new UnfulfillableCondition<>()); } @Override diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchema.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchema.java index 525f2154..598e17d1 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchema.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchema.java @@ -24,7 +24,7 @@ package io.github.sebastiantoepfer.jsonschema.core; import io.github.sebastiantoepfer.jsonschema.Validator; -import io.github.sebastiantoepfer.jsonschema.core.constraint.NoConstraint; +import io.github.sebastiantoepfer.jsonschema.core.codition.NoCondition; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import jakarta.json.JsonValue; import java.util.Optional; @@ -37,7 +37,7 @@ public TrueJsonSchema() { @Override public Validator validator() { - return new DefaultValidator(new NoConstraint<>()); + return new DefaultValidator(new NoCondition<>()); } @Override diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/AllOfConstraint.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AllOfCondition.java similarity index 66% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/AllOfConstraint.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AllOfCondition.java index 657b557a..3c9168b8 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/AllOfConstraint.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AllOfCondition.java @@ -21,25 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.constraint; +package io.github.sebastiantoepfer.jsonschema.core.codition; import static java.util.Arrays.asList; -import static java.util.function.Predicate.not; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import java.util.Collection; import java.util.List; -import java.util.Set; -public final class AllOfConstraint implements Constraint { +public final class AllOfCondition implements Condition { - private final List> contraints; + private final List> contraints; - public AllOfConstraint(final Constraint... constraints) { + public AllOfCondition(final Condition... constraints) { this(asList(constraints)); } - public AllOfConstraint(final Collection> contraints) { + public AllOfCondition(final Collection> contraints) { if (contraints.isEmpty()) { throw new IllegalArgumentException("min one constraint must be provided!"); } @@ -47,12 +44,7 @@ public AllOfConstraint(final Collection> contrai } @Override - public Collection violationsBy(final T value) { - return contraints - .stream() - .map(c -> c.violationsBy(value)) - .filter(not(Collection::isEmpty)) - .findFirst() - .orElseGet(Set::of); + public boolean isFulfilledBy(final T value) { + return contraints.stream().allMatch(c -> c.isFulfilledBy(value)); } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/UnfulfillableConstraint.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/ApplicatorBasedCondtion.java similarity index 68% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/UnfulfillableConstraint.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/ApplicatorBasedCondtion.java index 78f27e04..a8794c67 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/UnfulfillableConstraint.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/ApplicatorBasedCondtion.java @@ -21,16 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.constraint; +package io.github.sebastiantoepfer.jsonschema.core.codition; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; -import java.util.Collection; -import java.util.Set; +import io.github.sebastiantoepfer.jsonschema.keyword.Applicator; +import jakarta.json.JsonValue; +import java.util.Objects; -public final class UnfulfillableConstraint implements Constraint { +public final class ApplicatorBasedCondtion implements Condition { + + private final Applicator applicator; + + public ApplicatorBasedCondtion(final Applicator applicator) { + this.applicator = Objects.requireNonNull(applicator); + } @Override - public Collection violationsBy(final T value) { - return Set.of(new ConstraintViolation()); + public boolean isFulfilledBy(final JsonValue value) { + return applicator.applyTo(value); } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/ConstraintAssertion.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AssertionBasedCondition.java similarity index 74% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/ConstraintAssertion.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AssertionBasedCondition.java index 8c01a472..f9efa858 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/ConstraintAssertion.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AssertionBasedCondition.java @@ -21,18 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.vocab; +package io.github.sebastiantoepfer.jsonschema.core.codition; -import io.github.sebastiantoepfer.jsonschema.core.constraint.Constraint; import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import jakarta.json.JsonValue; +import java.util.Objects; + +public final class AssertionBasedCondition implements Condition { + + private final Assertion assertion; + + public AssertionBasedCondition(final Assertion assertion) { + this.assertion = Objects.requireNonNull(assertion); + } -/** - * only simplify pitest :) - */ -public interface ConstraintAssertion extends Assertion, Constraint { @Override - default boolean isValidFor(JsonValue instance) { - return violationsBy(instance).isEmpty(); + public boolean isFulfilledBy(final JsonValue value) { + return assertion.isValidFor(value); } } diff --git a/api/src/main/java/io/github/sebastiantoepfer/jsonschema/ConstraintViolation.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/Condition.java similarity index 89% rename from api/src/main/java/io/github/sebastiantoepfer/jsonschema/ConstraintViolation.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/Condition.java index 06a3d018..293895eb 100644 --- a/api/src/main/java/io/github/sebastiantoepfer/jsonschema/ConstraintViolation.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/Condition.java @@ -21,6 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema; +package io.github.sebastiantoepfer.jsonschema.core.codition; -public final class ConstraintViolation {} +public interface Condition { + boolean isFulfilledBy(T value); +} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/Constraint.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/NoCondition.java similarity index 81% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/Constraint.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/NoCondition.java index 18bc877f..dd935fc4 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/Constraint.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/NoCondition.java @@ -21,11 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.constraint; +package io.github.sebastiantoepfer.jsonschema.core.codition; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; -import java.util.Collection; +public final class NoCondition implements Condition { -public interface Constraint { - Collection violationsBy(T value); + @Override + public boolean isFulfilledBy(final T value) { + return true; + } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/NoConstraint.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/UnfulfillableCondition.java similarity index 77% rename from core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/NoConstraint.java rename to core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/UnfulfillableCondition.java index 1c0ffc7d..38163878 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/NoConstraint.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/UnfulfillableCondition.java @@ -21,16 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package io.github.sebastiantoepfer.jsonschema.core.constraint; +package io.github.sebastiantoepfer.jsonschema.core.codition; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; -import java.util.Collection; -import java.util.Set; - -public final class NoConstraint implements Constraint { +public final class UnfulfillableCondition implements Condition { @Override - public Collection violationsBy(final T value) { - return Set.of(); + public boolean isFulfilledBy(final T value) { + return false; } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/AnyConstraint.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/AnyConstraint.java deleted file mode 100644 index e4454126..00000000 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/constraint/AnyConstraint.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.constraint; - -import static java.util.Arrays.asList; -import static java.util.stream.Collectors.toSet; - -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -public class AnyConstraint implements Constraint { - - private final List> contraints; - - public AnyConstraint(final Constraint... constraints) { - this(asList(constraints)); - } - - public AnyConstraint(final Collection> contraints) { - if (contraints.isEmpty()) { - throw new IllegalArgumentException("min one constraint must be provided!"); - } - this.contraints = List.copyOf(contraints); - } - - @Override - public Collection violationsBy(final T value) { - final Collection result; - if (contraints.stream().anyMatch(c -> c.violationsBy(value).isEmpty())) { - result = Set.of(); - } else { - result = contraints.stream().map(c -> c.violationsBy(value)).flatMap(Collection::stream).collect(toSet()); - } - return result; - } -} diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/AdditionalPropertiesKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/AdditionalPropertiesKeywordType.java index 064b76e9..0f2b5b40 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/AdditionalPropertiesKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/AdditionalPropertiesKeywordType.java @@ -75,7 +75,7 @@ private boolean additionalPropertiesMatches(final JsonObject instance) { final JsonSchema additionalPropertiesSchema = new DefaultJsonSchemaFactory().create(additionalProperties); return findPropertiesForValidation(instance) .map(Map.Entry::getValue) - .allMatch(value -> additionalPropertiesSchema.validator().validate(value).isEmpty()); + .allMatch(value -> additionalPropertiesSchema.validator().isValid(value)); } @Override diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordType.java index cf404f16..1c230e7f 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/ItemsKeywordType.java @@ -114,11 +114,7 @@ public boolean applyTo(final JsonValue instance) { private boolean matchesSchema(final JsonArray items) { final Validator itemValidator = validator(); - return items - .stream() - .skip(startIndexFor(items) + 1L) - .map(itemValidator::validate) - .allMatch(Collection::isEmpty); + return items.stream().skip(startIndexFor(items) + 1L).allMatch(itemValidator::isValid); } private int startIndexFor(final JsonArray value) { diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PatternPropertiesKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PatternPropertiesKeywordType.java index 8d35c465..303be0d9 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PatternPropertiesKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PatternPropertiesKeywordType.java @@ -93,7 +93,7 @@ private boolean propertyMatches(final Map.Entry property) { .filter(e -> e.getKey().matcher(property.getKey()).find()) .map(Map.Entry::getValue) .map(JsonSchemas::load) - .allMatch(schema -> schema.validator().validate(property.getValue()).isEmpty()); + .allMatch(schema -> schema.validator().isValid(property.getValue())); } @Override diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PrefixItemsKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PrefixItemsKeywordType.java index fcb028c9..fdafd1f8 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PrefixItemsKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PrefixItemsKeywordType.java @@ -94,7 +94,7 @@ public boolean applyTo(final JsonValue instance) { private boolean matchesSchemas(final JsonArray instance) { boolean result = true; for (int i = 0; i < Math.min(schemas.size(), instance.size()); i++) { - result &= schemas.get(i).validator().validate(instance.get(i)).isEmpty(); + result &= schemas.get(i).validator().isValid(instance.get(i)); if (!result) { break; } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PropertiesKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PropertiesKeywordType.java index 936ff2d8..a62813e2 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PropertiesKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/applicator/PropertiesKeywordType.java @@ -82,7 +82,7 @@ private boolean propertiesMatches(final JsonObject instance) { private boolean propertyMatches(final Map.Entry property) { return ( !schemas.containsKey(property.getKey()) || - JsonSchemas.load(schemas.get(property.getKey())).validator().validate(property.getValue()).isEmpty() + JsonSchemas.load(schemas.get(property.getKey())).validator().isValid(property.getValue()) ); } 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 11a8240d..1dd63936 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 @@ -70,7 +70,7 @@ private RefKeyword(final JsonSchema schema, final JsonString uri) { @Override public boolean applyTo(final JsonValue instance) { - return retrieveJsonSchema().validator().validate(instance).isEmpty(); + return retrieveJsonSchema().validator().isValid(instance); } @Override diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordType.java index 1fd6c958..233790fa 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMaximumKeywordType.java @@ -23,18 +23,14 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonNumber; import jakarta.json.JsonValue; import java.math.BigDecimal; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; final class ExclusiveMaximumKeywordType implements KeywordType { @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class ExclusiveMaximumKeyword implements ConstraintAssertion { + private class ExclusiveMaximumKeyword implements Assertion { private final BigDecimal max; @@ -67,14 +63,11 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - final Collection result; - if (!InstanceType.NUMBER.isInstance(value) || max.compareTo(((JsonNumber) value).bigDecimalValue()) > 0) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + public boolean isValidFor(final JsonValue instance) { + return ( + !InstanceType.NUMBER.isInstance(instance) || + max.compareTo(((JsonNumber) instance).bigDecimalValue()) > 0 + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordType.java index 561d5b64..e59ede7b 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/ExclusiveMinimumKeywordType.java @@ -23,18 +23,14 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonNumber; import jakarta.json.JsonValue; import java.math.BigDecimal; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; final class ExclusiveMinimumKeywordType implements KeywordType { @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class ExclusiveMinimumKeyword implements ConstraintAssertion { + private class ExclusiveMinimumKeyword implements Assertion { private final BigDecimal min; @@ -67,14 +63,11 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - final Collection result; - if (!InstanceType.NUMBER.isInstance(value) || min.compareTo(((JsonNumber) value).bigDecimalValue()) < 0) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + public boolean isValidFor(final JsonValue instance) { + return ( + !InstanceType.NUMBER.isInstance(instance) || + min.compareTo(((JsonNumber) instance).bigDecimalValue()) < 0 + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordType.java index 2a022d33..ca0b1e36 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaxLengthKeywordType.java @@ -23,18 +23,14 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonNumber; import jakarta.json.JsonString; import jakarta.json.JsonValue; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; class MaxLengthKeywordType implements KeywordType { @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class MaxLengthKeyword implements ConstraintAssertion { + private class MaxLengthKeyword implements Assertion { private final JsonNumber value; @@ -67,17 +63,11 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue instance) { - final Collection result; - if ( + public boolean isValidFor(final JsonValue instance) { + return ( !InstanceType.STRING.isInstance(instance) || ((JsonString) instance).getChars().codePoints().count() <= value.longValue() - ) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordType.java index c78f2197..d95d7376 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MaximumKeywordType.java @@ -23,18 +23,14 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonNumber; import jakarta.json.JsonValue; import java.math.BigDecimal; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; final class MaximumKeywordType implements KeywordType { @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class MaximumKeyword implements ConstraintAssertion { + private class MaximumKeyword implements Assertion { private final BigDecimal max; @@ -67,14 +63,11 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - final Collection result; - if (!InstanceType.NUMBER.isInstance(value) || max.compareTo(((JsonNumber) value).bigDecimalValue()) >= 0) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + public boolean isValidFor(final JsonValue instance) { + return ( + !InstanceType.NUMBER.isInstance(instance) || + max.compareTo(((JsonNumber) instance).bigDecimalValue()) >= 0 + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordType.java index 0f5b91d7..f503f0f8 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinLengthKeywordType.java @@ -23,18 +23,14 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonNumber; import jakarta.json.JsonString; import jakarta.json.JsonValue; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; class MinLengthKeywordType implements KeywordType { @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class MinLengthKeyword implements ConstraintAssertion { + private class MinLengthKeyword implements Assertion { private final JsonNumber value; @@ -67,17 +63,11 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue instance) { - final Collection result; - if ( + public boolean isValidFor(final JsonValue instance) { + return ( !InstanceType.STRING.isInstance(instance) || ((JsonString) instance).getChars().codePoints().count() >= value.longValue() - ) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordType.java index 0f09579d..21c0baa1 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MinimumKeywordType.java @@ -23,18 +23,14 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonNumber; import jakarta.json.JsonValue; import java.math.BigDecimal; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; final class MinimumKeywordType implements KeywordType { @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class MinimumKeyword implements ConstraintAssertion { + private class MinimumKeyword implements Assertion { private final BigDecimal min; @@ -67,14 +63,11 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - final Collection result; - if (!InstanceType.NUMBER.isInstance(value) || min.compareTo(((JsonNumber) value).bigDecimalValue()) <= 0) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + public boolean isValidFor(final JsonValue instance) { + return ( + !InstanceType.NUMBER.isInstance(instance) || + min.compareTo(((JsonNumber) instance).bigDecimalValue()) <= 0 + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordType.java index e2a6f962..aa9fa431 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/MultipleOfKeywordType.java @@ -23,18 +23,14 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonNumber; import jakarta.json.JsonValue; import java.math.BigDecimal; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; final class MultipleOfKeywordType implements KeywordType { @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class MultipleOfKeyword implements ConstraintAssertion { + private class MultipleOfKeyword implements Assertion { private final BigDecimal multipleOf; @@ -67,19 +63,13 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - final Collection result; - if ( - !InstanceType.NUMBER.isInstance(value) || + public boolean isValidFor(final JsonValue instance) { + return ( + !InstanceType.NUMBER.isInstance(instance) || BigDecimal.ZERO.equals( - ((JsonNumber) value).bigDecimalValue().remainder(multipleOf).stripTrailingZeros() + ((JsonNumber) instance).bigDecimalValue().remainder(multipleOf).stripTrailingZeros() ) - ) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordType.java index 9066c6e9..877b0a2f 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/PatternKeywordType.java @@ -23,17 +23,13 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; import io.github.sebastiantoepfer.jsonschema.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonString; import jakarta.json.JsonValue; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Objects; import java.util.regex.Pattern; @@ -53,7 +49,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { } } - private class PatternKeyword implements ConstraintAssertion { + private class PatternKeyword implements Assertion { private final Pattern pattern; @@ -67,14 +63,10 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - final List result; - if (!InstanceType.STRING.isInstance(value) || pattern.matcher(((JsonString) value).getString()).find()) { - result = Collections.emptyList(); - } else { - result = List.of(new ConstraintViolation()); - } - return result; + public boolean isValidFor(final JsonValue instance) { + return ( + !InstanceType.STRING.isInstance(instance) || pattern.matcher(((JsonString) instance).getString()).find() + ); } } } diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordType.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordType.java index 0a00beef..05b2212c 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordType.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/vocab/validation/TypeKeywordType.java @@ -23,24 +23,17 @@ */ package io.github.sebastiantoepfer.jsonschema.core.vocab.validation; -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.InstanceType; import io.github.sebastiantoepfer.jsonschema.JsonSchema; -import io.github.sebastiantoepfer.jsonschema.core.constraint.AnyConstraint; -import io.github.sebastiantoepfer.jsonschema.core.constraint.Constraint; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; +import io.github.sebastiantoepfer.jsonschema.core.codition.Condition; +import io.github.sebastiantoepfer.jsonschema.keyword.Assertion; import io.github.sebastiantoepfer.jsonschema.keyword.Keyword; import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType; import jakarta.json.JsonArray; import jakarta.json.JsonString; import jakarta.json.JsonValue; -import java.util.Collection; import java.util.Locale; import java.util.Objects; -import java.util.Set; /** * see: https://json-schema.org/understanding-json-schema/reference/type.html @@ -57,7 +50,7 @@ public Keyword createKeyword(final JsonSchema schema, final JsonValue value) { return new TypeKeyword(value); } - private final class TypeKeyword implements ConstraintAssertion, Constraint { + private final class TypeKeyword implements Assertion { private final JsonValue definition; @@ -71,11 +64,11 @@ public boolean hasName(final String name) { } @Override - public Collection violationsBy(final JsonValue value) { - return new JsonMappedTypeConstaint(definition).violationsBy(value); + public boolean isValidFor(final JsonValue instance) { + return new JsonMappedTypeConstaint(definition).isFulfilledBy(instance); } - private static final class JsonMappedTypeConstaint implements Constraint { + private static final class JsonMappedTypeConstaint implements Condition { private final JsonValue definition; @@ -84,17 +77,17 @@ public JsonMappedTypeConstaint(final JsonValue definition) { } @Override - public Collection violationsBy(final JsonValue value) { - final Constraint typeContraint = + public boolean isFulfilledBy(final JsonValue value) { + final Condition typeContraint = switch (definition.getValueType()) { case STRING -> new JsonStringTypeConstraint((JsonString) definition); default -> new JsonArrayTypeConstraint(definition.asJsonArray()); }; - return typeContraint.violationsBy(value); + return typeContraint.isFulfilledBy(value); } } - private static final class JsonArrayTypeConstraint implements Constraint { + private static final class JsonArrayTypeConstraint implements Condition { private final JsonArray types; @@ -103,16 +96,12 @@ public JsonArrayTypeConstraint(final JsonArray types) { } @Override - public Collection violationsBy(final JsonValue value) { - return types - .stream() - .map(JsonMappedTypeConstaint::new) - .collect(collectingAndThen(toList(), AnyConstraint::new)) - .violationsBy(value); + public boolean isFulfilledBy(final JsonValue value) { + return types.stream().map(JsonMappedTypeConstaint::new).anyMatch(c -> c.isFulfilledBy(value)); } } - private static final class JsonStringTypeConstraint implements Constraint { + private static final class JsonStringTypeConstraint implements Condition { private final String type; @@ -121,15 +110,8 @@ public JsonStringTypeConstraint(final JsonString type) { } @Override - public Collection violationsBy(final JsonValue value) { - final InstanceType instanceType = InstanceType.valueOf(type); - final Collection result; - if (instanceType.isInstance(value)) { - result = Set.of(); - } else { - result = Set.of(new ConstraintViolation()); - } - return result; + public boolean isFulfilledBy(final JsonValue value) { + return InstanceType.valueOf(type).isInstance(value); } } } 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 8dec8483..dd07c2ab 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 @@ -26,7 +26,6 @@ import static com.github.npathai.hamcrestopt.OptionalMatchers.isEmpty; import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; @@ -48,22 +47,22 @@ class DefaultJsonSchemaTest { @Test void should_be_valid_an_empty_array() { - assertThat(schema.validator().validate(JsonValue.EMPTY_JSON_ARRAY), is(empty())); + assertThat(schema.validator().isValid(JsonValue.EMPTY_JSON_ARRAY), is(true)); } @Test void should_be_valid_an_integer_array() { - assertThat(schema.validator().validate(Json.createArrayBuilder().add(1).add(2).build()), is(empty())); + assertThat(schema.validator().isValid(Json.createArrayBuilder().add(1).add(2).build()), is(true)); } @Test void should_be_invalid_an_string_array() { - assertThat(schema.validator().validate(Json.createArrayBuilder().add("a").add("b").build()), is(not(empty()))); + assertThat(schema.validator().isValid(Json.createArrayBuilder().add("a").add("b").build()), is(not(true))); } @Test void should_be_invalid_for_object() { - assertThat(schema.validator().validate(JsonValue.EMPTY_JSON_OBJECT), is(not(empty()))); + assertThat(schema.validator().isValid(JsonValue.EMPTY_JSON_OBJECT), is(not(true))); } @Test diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchemaTest.java index 657e981b..b3057564 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchemaTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/EmptyJsonSchemaTest.java @@ -24,7 +24,6 @@ package io.github.sebastiantoepfer.jsonschema.core; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; import jakarta.json.JsonValue; @@ -36,6 +35,6 @@ class EmptyJsonSchemaTest { @ParameterizedTest @ArgumentsSource(JsonValuesArguments.class) void should_be_valid_for_everything(final JsonValue value) { - assertThat(new EmptyJsonSchema().validator().validate(value), is(empty())); + assertThat(new EmptyJsonSchema().validator().isValid(value), is(true)); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchemaTest.java index 9819fcf6..cdd8215c 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchemaTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/FalseJsonSchemaTest.java @@ -24,7 +24,6 @@ package io.github.sebastiantoepfer.jsonschema.core; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; @@ -37,6 +36,6 @@ class FalseJsonSchemaTest { @ParameterizedTest @ArgumentsSource(JsonValuesArguments.class) void should_be_invalid_for_everything(final JsonValue value) { - assertThat(new FalseJsonSchema().validator().validate(value), is(not(empty()))); + assertThat(new FalseJsonSchema().validator().isValid(value), is(not(true))); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchemaTest.java index 36f5ff5b..0ca73b20 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchemaTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/TrueJsonSchemaTest.java @@ -24,7 +24,6 @@ package io.github.sebastiantoepfer.jsonschema.core; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; import jakarta.json.JsonValue; @@ -36,6 +35,6 @@ class TrueJsonSchemaTest { @ParameterizedTest @ArgumentsSource(JsonValuesArguments.class) void should_be_valid_for_everything(final JsonValue value) { - assertThat(new TrueJsonSchema().validator().validate(value), is(empty())); + assertThat(new TrueJsonSchema().validator().isValid(value), is(true)); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java index 0656f74c..2ea4fb8a 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java @@ -99,10 +99,7 @@ public JsonSchemaTest(final JsonValue schema, final JsonObject test) { @Override public boolean isValid() { - return ( - JsonSchemas.load(schema).validator().validate(test.get("data")).isEmpty() == - test.getBoolean("valid") - ); + return (JsonSchemas.load(schema).validator().isValid(test.get("data")) == test.getBoolean("valid")); } @Override diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/ConstraintAssertionTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/ConstraintAssertionTest.java deleted file mode 100644 index 6561f6cd..00000000 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/vocab/ConstraintAssertionTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -import io.github.sebastiantoepfer.jsonschema.ConstraintViolation; -import io.github.sebastiantoepfer.jsonschema.core.constraint.Constraint; -import io.github.sebastiantoepfer.jsonschema.core.vocab.ConstraintAssertion; -import jakarta.json.JsonValue; -import java.util.Collection; -import java.util.Objects; -import java.util.Set; -import org.junit.jupiter.api.Test; - -class ConstraintAssertionTest { - - @Test - void should_return_true_if_constraint_doesnt_find_any_violations() { - assertThat(new PitTestHappyMaker(value -> Set.of()).isValidFor(JsonValue.TRUE), is(true)); - } - - @Test - void should_return_false_if_constraint_find_any_violations() { - assertThat( - new PitTestHappyMaker(value -> Set.of(new ConstraintViolation())).isValidFor(JsonValue.TRUE), - is(false) - ); - } - - private static class PitTestHappyMaker implements ConstraintAssertion { - - private final Constraint constraint; - - public PitTestHappyMaker(final Constraint constraint) { - this.constraint = Objects.requireNonNull(constraint); - } - - @Override - public boolean hasName(final String name) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Collection violationsBy(final JsonValue value) { - return constraint.violationsBy(value); - } - } -} From 06c5d7525985255fb8d9a86620a6a9b085154775 Mon Sep 17 00:00:00 2001 From: Sebastian Toepfer <61313468+sebastian-toepfer@users.noreply.github.com> Date: Wed, 11 Oct 2023 05:19:43 +0200 Subject: [PATCH 2/2] allow empty allOf condition --- .../jsonschema/core/codition/AllOfCondition.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AllOfCondition.java b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AllOfCondition.java index 3c9168b8..3350866f 100644 --- a/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AllOfCondition.java +++ b/core/src/main/java/io/github/sebastiantoepfer/jsonschema/core/codition/AllOfCondition.java @@ -37,9 +37,6 @@ public AllOfCondition(final Condition... constraints) { } public AllOfCondition(final Collection> contraints) { - if (contraints.isEmpty()) { - throw new IllegalArgumentException("min one constraint must be provided!"); - } this.contraints = List.copyOf(contraints); }