diff --git a/src/main/java/am/ik/yavi/builder/ValidatorBuilder.java b/src/main/java/am/ik/yavi/builder/ValidatorBuilder.java index 1e7086f6..c2624108 100644 --- a/src/main/java/am/ik/yavi/builder/ValidatorBuilder.java +++ b/src/main/java/am/ik/yavi/builder/ValidatorBuilder.java @@ -15,97 +15,18 @@ */ package am.ik.yavi.builder; -import am.ik.yavi.constraint.BigDecimalConstraint; -import am.ik.yavi.constraint.BigIntegerConstraint; -import am.ik.yavi.constraint.BooleanConstraint; -import am.ik.yavi.constraint.ByteConstraint; -import am.ik.yavi.constraint.CharSequenceConstraint; -import am.ik.yavi.constraint.CharacterConstraint; -import am.ik.yavi.constraint.CollectionConstraint; -import am.ik.yavi.constraint.DoubleConstraint; -import am.ik.yavi.constraint.FloatConstraint; -import am.ik.yavi.constraint.InstantConstraint; -import am.ik.yavi.constraint.IntegerConstraint; -import am.ik.yavi.constraint.LocalDateConstraint; -import am.ik.yavi.constraint.LocalDateTimeConstraint; -import am.ik.yavi.constraint.LocalTimeConstraint; -import am.ik.yavi.constraint.LongConstraint; -import am.ik.yavi.constraint.MapConstraint; -import am.ik.yavi.constraint.ObjectConstraint; -import am.ik.yavi.constraint.OffsetDateTimeConstraint; -import am.ik.yavi.constraint.ShortConstraint; -import am.ik.yavi.constraint.YearConstraint; -import am.ik.yavi.constraint.YearMonthConstraint; -import am.ik.yavi.constraint.ZonedDateTimeConstraint; -import am.ik.yavi.constraint.array.BooleanArrayConstraint; -import am.ik.yavi.constraint.array.ByteArrayConstraint; -import am.ik.yavi.constraint.array.CharArrayConstraint; -import am.ik.yavi.constraint.array.DoubleArrayConstraint; -import am.ik.yavi.constraint.array.FloatArrayConstraint; -import am.ik.yavi.constraint.array.IntArrayConstraint; -import am.ik.yavi.constraint.array.LongArrayConstraint; -import am.ik.yavi.constraint.array.ObjectArrayConstraint; -import am.ik.yavi.constraint.array.ShortArrayConstraint; -import am.ik.yavi.core.BiValidator; -import am.ik.yavi.core.CollectionValidator; -import am.ik.yavi.core.Constraint; -import am.ik.yavi.core.ConstraintCondition; -import am.ik.yavi.core.ConstraintGroup; -import am.ik.yavi.core.ConstraintPredicate; -import am.ik.yavi.core.ConstraintPredicates; -import am.ik.yavi.core.CustomConstraint; -import am.ik.yavi.core.NestedCollectionValidator; -import am.ik.yavi.core.NestedConstraintCondition; -import am.ik.yavi.core.NestedConstraintPredicates; -import am.ik.yavi.core.NestedValidator; -import am.ik.yavi.core.NullAs; -import am.ik.yavi.core.Validatable; -import am.ik.yavi.core.Validator; -import am.ik.yavi.core.ValueValidator; -import am.ik.yavi.core.ViolatedArguments; -import am.ik.yavi.core.ViolationMessage; +import am.ik.yavi.constraint.*; +import am.ik.yavi.constraint.array.*; +import am.ik.yavi.core.*; import am.ik.yavi.fn.Pair; import am.ik.yavi.message.MessageFormatter; import am.ik.yavi.message.SimpleMessageFormatter; -import am.ik.yavi.meta.BigDecimalConstraintMeta; -import am.ik.yavi.meta.BigIntegerConstraintMeta; -import am.ik.yavi.meta.BooleanConstraintMeta; -import am.ik.yavi.meta.ByteConstraintMeta; -import am.ik.yavi.meta.CharacterConstraintMeta; -import am.ik.yavi.meta.DoubleConstraintMeta; -import am.ik.yavi.meta.FloatConstraintMeta; -import am.ik.yavi.meta.InstantConstraintMeta; -import am.ik.yavi.meta.IntegerConstraintMeta; -import am.ik.yavi.meta.LocalDateConstraintMeta; -import am.ik.yavi.meta.LocalDateTimeConstraintMeta; -import am.ik.yavi.meta.LocalTimeConstraintMeta; -import am.ik.yavi.meta.LongConstraintMeta; -import am.ik.yavi.meta.ObjectConstraintMeta; -import am.ik.yavi.meta.OffsetDateTimeConstraintMeta; -import am.ik.yavi.meta.ShortConstraintMeta; -import am.ik.yavi.meta.StringConstraintMeta; -import am.ik.yavi.meta.YearConstraintMeta; -import am.ik.yavi.meta.YearMonthConstraintMeta; -import am.ik.yavi.meta.ZonedDateTimeConstraintMeta; +import am.ik.yavi.meta.*; import java.math.BigDecimal; import java.math.BigInteger; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetDateTime; -import java.time.Year; -import java.time.YearMonth; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Deque; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.time.*; +import java.util.*; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -737,10 +658,12 @@ public ValidatorBuilder _doubleArray(ToDoubleArray f, String name, */ public ValidatorBuilder constraintOnClass(Class clazz, Validator cValidator) { - Validator TValidator = new ValidatorBuilder() - .nest(clazz::cast, clazz.getName(), cValidator).build(); + Validatable validatable = new InheritanceValidator<>(clazz, cValidator); - return constraintOnCondition(getClassConstraintCondition(clazz), TValidator); + this.conditionalValidators + .add(new Pair<>(getClassConstraintCondition(clazz), validatable)); + + return this; } /** @@ -748,10 +671,9 @@ public ValidatorBuilder constraintOnClass(Class clazz, */ public ValidatorBuilder constraintOnClass(Class clazz, ValidatorBuilderConverter converter) { - ValidatorBuilderConverter tConverter = tValidatorBuilder -> tValidatorBuilder - .nest(clazz::cast, clazz.getName(), converter); + Validator cValidator = converter.apply(new ValidatorBuilder<>()).build(); - return constraintOnCondition(getClassConstraintCondition(clazz), tConverter); + return constraintOnClass(clazz, cValidator); } private ConstraintCondition getClassConstraintCondition( @@ -1025,6 +947,7 @@ protected final ValidatorBuilder nest(Function nested, String name, .forEach(this.appendNestedConditionalValidator(nested, name)); builder.collectionValidators .forEach(appendNestedCollectionValidator(nested, name)); + return this; } diff --git a/src/main/java/am/ik/yavi/core/InheritanceValidator.java b/src/main/java/am/ik/yavi/core/InheritanceValidator.java new file mode 100644 index 00000000..f70b8fa7 --- /dev/null +++ b/src/main/java/am/ik/yavi/core/InheritanceValidator.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018-2023 Toshiaki Maki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package am.ik.yavi.core; + +import java.util.Locale; + +/** + * @since 0.14.0 + */ +public class InheritanceValidator implements Validatable { + private final Class nClass; + private final Validatable validator; + + public InheritanceValidator(Class nClass, Validatable validator) { + this.nClass = nClass; + this.validator = validator; + } + + @Override + public ConstraintViolations validate(T target, Locale locale, + ConstraintContext constraintContext) { + final N n = nClass.cast(target); + + return this.validator.validate(n, locale, constraintContext); + } + + @Override + public Validatable failFast(boolean failFast) { + final Validatable validatable = this.validator.failFast(failFast); + return new InheritanceValidator<>(nClass, validatable); + } + + @Override + public boolean isFailFast() { + return this.validator.isFailFast(); + } +} diff --git a/src/test/java/am/ik/yavi/core/ConstraintOnClassTest.java b/src/test/java/am/ik/yavi/core/ConstraintOnClassTest.java index 09f8d46f..4d42f9c5 100644 --- a/src/test/java/am/ik/yavi/core/ConstraintOnClassTest.java +++ b/src/test/java/am/ik/yavi/core/ConstraintOnClassTest.java @@ -17,55 +17,67 @@ public class ConstraintOnClassTest { @ParameterizedTest @MethodSource("provideValidators") - void testConstraintOnConditionClass(Validator validator) { - User validAdmin = new Admin("admin123", "admin@gmail", 27, "yavi123"); - User invalidAdmin = new Admin("Niraz", "niraz@gmail", 23, "user"); + void testConstraintOnConditionClass(Validator validator) { + Parent validChild = new Child(23, "drawing"); + Parent invalidChild = new Child(6, "drawing"); - assertThat(validator.validate(validAdmin).isValid()).isTrue(); - assertThat(validator.validate(invalidAdmin).isValid()).isFalse(); + assertThat(validator.validate(validChild).isValid()).isTrue(); + assertThat(validator.validate(invalidChild).isValid()).isFalse(); } @ParameterizedTest @MethodSource("provideValidators") - void testConstraintOnNonConditionClass(Validator validator) { - User validUser = new User("Rawad", "rawad@gmail", 25); - User invalidUser = new User("Almog", "almog@gmail", 19); + void testConstraintOnNonConditionClass(Validator validator) { + Parent validParent = new Parent(35); + Parent invalidParent = new Parent(19); - assertThat(validator.validate(validUser).isValid()).isTrue(); - assertThat(validator.validate(invalidUser).isValid()).isFalse(); + assertThat(validator.validate(validParent).isValid()).isTrue(); + assertThat(validator.validate(invalidParent).isValid()).isFalse(); } static Stream provideValidators() { - ValidatorBuilder userValidatorBuilder = ValidatorBuilder.of(User.class) - .constraint(User::getAge, "age", c -> c.greaterThan(20)); - Function, CharSequenceConstraint> startsWithAdmin = ( - CharSequenceConstraint c) -> c.startsWith("yavi"); + ValidatorBuilder userValidatorBuilder = ValidatorBuilder.of(Parent.class) + .constraint(Parent::getAge, "age", c -> c.greaterThan(20)); + Function, CharSequenceConstraint> equalsToDrawing = ( + CharSequenceConstraint c) -> c.equalTo("drawing"); return Stream .of(Arguments.of(new ValidatorBuilder<>(userValidatorBuilder) - .constraintOnClass(Admin.class, - ValidatorBuilder.of(Admin.class) - .constraint(Admin::getGroup, "group", - startsWithAdmin) + .constraintOnClass(Child.class, + ValidatorBuilder.of(Child.class) + .constraint(Child::getHobby, "hobby", + equalsToDrawing) .build()) .build()), Arguments .of(new ValidatorBuilder<>(userValidatorBuilder) - .constraintOnClass(Admin.class, - b -> b.constraint(Admin::getGroup, - "group", startsWithAdmin)) + .constraintOnClass(Child.class, + b -> b.constraint(Child::getHobby, + "hobby", equalsToDrawing)) .build())); } - private static class Admin extends User { - private String group; + private static class Child extends Parent { + private String hobby; - public Admin(String name, String email, int age, String group) { - super(name, email, age); - this.group = group; + public Child(int age, String hobby) { + super(age); + this.hobby = hobby; } - public String getGroup() { - return group; + public String getHobby() { + return hobby; + } + } + + private static class Parent { + private final int age; + + public Parent(int age) { + this.age = age; + } + + public int getAge() { + return age; } } }