Skip to content

Commit 63fc402

Browse files
diffrent approach to validating inheritence classes
1 parent b19615d commit 63fc402

File tree

3 files changed

+104
-119
lines changed

3 files changed

+104
-119
lines changed

src/main/java/am/ik/yavi/builder/ValidatorBuilder.java

Lines changed: 14 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -15,97 +15,18 @@
1515
*/
1616
package am.ik.yavi.builder;
1717

18-
import am.ik.yavi.constraint.BigDecimalConstraint;
19-
import am.ik.yavi.constraint.BigIntegerConstraint;
20-
import am.ik.yavi.constraint.BooleanConstraint;
21-
import am.ik.yavi.constraint.ByteConstraint;
22-
import am.ik.yavi.constraint.CharSequenceConstraint;
23-
import am.ik.yavi.constraint.CharacterConstraint;
24-
import am.ik.yavi.constraint.CollectionConstraint;
25-
import am.ik.yavi.constraint.DoubleConstraint;
26-
import am.ik.yavi.constraint.FloatConstraint;
27-
import am.ik.yavi.constraint.InstantConstraint;
28-
import am.ik.yavi.constraint.IntegerConstraint;
29-
import am.ik.yavi.constraint.LocalDateConstraint;
30-
import am.ik.yavi.constraint.LocalDateTimeConstraint;
31-
import am.ik.yavi.constraint.LocalTimeConstraint;
32-
import am.ik.yavi.constraint.LongConstraint;
33-
import am.ik.yavi.constraint.MapConstraint;
34-
import am.ik.yavi.constraint.ObjectConstraint;
35-
import am.ik.yavi.constraint.OffsetDateTimeConstraint;
36-
import am.ik.yavi.constraint.ShortConstraint;
37-
import am.ik.yavi.constraint.YearConstraint;
38-
import am.ik.yavi.constraint.YearMonthConstraint;
39-
import am.ik.yavi.constraint.ZonedDateTimeConstraint;
40-
import am.ik.yavi.constraint.array.BooleanArrayConstraint;
41-
import am.ik.yavi.constraint.array.ByteArrayConstraint;
42-
import am.ik.yavi.constraint.array.CharArrayConstraint;
43-
import am.ik.yavi.constraint.array.DoubleArrayConstraint;
44-
import am.ik.yavi.constraint.array.FloatArrayConstraint;
45-
import am.ik.yavi.constraint.array.IntArrayConstraint;
46-
import am.ik.yavi.constraint.array.LongArrayConstraint;
47-
import am.ik.yavi.constraint.array.ObjectArrayConstraint;
48-
import am.ik.yavi.constraint.array.ShortArrayConstraint;
49-
import am.ik.yavi.core.BiValidator;
50-
import am.ik.yavi.core.CollectionValidator;
51-
import am.ik.yavi.core.Constraint;
52-
import am.ik.yavi.core.ConstraintCondition;
53-
import am.ik.yavi.core.ConstraintGroup;
54-
import am.ik.yavi.core.ConstraintPredicate;
55-
import am.ik.yavi.core.ConstraintPredicates;
56-
import am.ik.yavi.core.CustomConstraint;
57-
import am.ik.yavi.core.NestedCollectionValidator;
58-
import am.ik.yavi.core.NestedConstraintCondition;
59-
import am.ik.yavi.core.NestedConstraintPredicates;
60-
import am.ik.yavi.core.NestedValidator;
61-
import am.ik.yavi.core.NullAs;
62-
import am.ik.yavi.core.Validatable;
63-
import am.ik.yavi.core.Validator;
64-
import am.ik.yavi.core.ValueValidator;
65-
import am.ik.yavi.core.ViolatedArguments;
66-
import am.ik.yavi.core.ViolationMessage;
18+
import am.ik.yavi.constraint.*;
19+
import am.ik.yavi.constraint.array.*;
20+
import am.ik.yavi.core.*;
6721
import am.ik.yavi.fn.Pair;
6822
import am.ik.yavi.message.MessageFormatter;
6923
import am.ik.yavi.message.SimpleMessageFormatter;
70-
import am.ik.yavi.meta.BigDecimalConstraintMeta;
71-
import am.ik.yavi.meta.BigIntegerConstraintMeta;
72-
import am.ik.yavi.meta.BooleanConstraintMeta;
73-
import am.ik.yavi.meta.ByteConstraintMeta;
74-
import am.ik.yavi.meta.CharacterConstraintMeta;
75-
import am.ik.yavi.meta.DoubleConstraintMeta;
76-
import am.ik.yavi.meta.FloatConstraintMeta;
77-
import am.ik.yavi.meta.InstantConstraintMeta;
78-
import am.ik.yavi.meta.IntegerConstraintMeta;
79-
import am.ik.yavi.meta.LocalDateConstraintMeta;
80-
import am.ik.yavi.meta.LocalDateTimeConstraintMeta;
81-
import am.ik.yavi.meta.LocalTimeConstraintMeta;
82-
import am.ik.yavi.meta.LongConstraintMeta;
83-
import am.ik.yavi.meta.ObjectConstraintMeta;
84-
import am.ik.yavi.meta.OffsetDateTimeConstraintMeta;
85-
import am.ik.yavi.meta.ShortConstraintMeta;
86-
import am.ik.yavi.meta.StringConstraintMeta;
87-
import am.ik.yavi.meta.YearConstraintMeta;
88-
import am.ik.yavi.meta.YearMonthConstraintMeta;
89-
import am.ik.yavi.meta.ZonedDateTimeConstraintMeta;
24+
import am.ik.yavi.meta.*;
9025

9126
import java.math.BigDecimal;
9227
import java.math.BigInteger;
93-
import java.time.Instant;
94-
import java.time.LocalDate;
95-
import java.time.LocalDateTime;
96-
import java.time.LocalTime;
97-
import java.time.OffsetDateTime;
98-
import java.time.Year;
99-
import java.time.YearMonth;
100-
import java.time.ZonedDateTime;
101-
import java.util.ArrayList;
102-
import java.util.Arrays;
103-
import java.util.Collection;
104-
import java.util.Deque;
105-
import java.util.LinkedHashMap;
106-
import java.util.LinkedList;
107-
import java.util.List;
108-
import java.util.Map;
28+
import java.time.*;
29+
import java.util.*;
10930
import java.util.function.Consumer;
11031
import java.util.function.Function;
11132
import java.util.function.Predicate;
@@ -737,21 +658,22 @@ public ValidatorBuilder<T> _doubleArray(ToDoubleArray<T> f, String name,
737658
*/
738659
public <C extends T> ValidatorBuilder<T> constraintOnClass(Class<C> clazz,
739660
Validator<C> cValidator) {
740-
Validator<T> TValidator = new ValidatorBuilder<T>()
741-
.nest(clazz::cast, clazz.getName(), cValidator).build();
661+
Validatable<T> validatable = new InheritanceValidator<>(clazz, cValidator);
742662

743-
return constraintOnCondition(getClassConstraintCondition(clazz), TValidator);
663+
this.conditionalValidators
664+
.add(new Pair<>(getClassConstraintCondition(clazz), validatable));
665+
666+
return this;
744667
}
745668

746669
/**
747670
* @since 0.14.0
748671
*/
749672
public <C extends T> ValidatorBuilder<T> constraintOnClass(Class<C> clazz,
750673
ValidatorBuilderConverter<C> converter) {
751-
ValidatorBuilderConverter<T> tConverter = tValidatorBuilder -> tValidatorBuilder
752-
.nest(clazz::cast, clazz.getName(), converter);
674+
Validator<C> cValidator = converter.apply(new ValidatorBuilder<>()).build();
753675

754-
return constraintOnCondition(getClassConstraintCondition(clazz), tConverter);
676+
return constraintOnClass(clazz, cValidator);
755677
}
756678

757679
private <C extends T> ConstraintCondition<T> getClassConstraintCondition(
@@ -1025,6 +947,7 @@ protected final <N> ValidatorBuilder<T> nest(Function<T, N> nested, String name,
1025947
.forEach(this.appendNestedConditionalValidator(nested, name));
1026948
builder.collectionValidators
1027949
.forEach(appendNestedCollectionValidator(nested, name));
950+
1028951
return this;
1029952
}
1030953

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (C) 2018-2023 Toshiaki Maki <[email protected]>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package am.ik.yavi.core;
17+
18+
import java.util.Locale;
19+
20+
/**
21+
* @since 0.14.0
22+
*/
23+
public class InheritanceValidator<T, N extends T> implements Validatable<T> {
24+
private final Class<N> nClass;
25+
private final Validatable<N> validator;
26+
27+
public InheritanceValidator(Class<N> nClass, Validatable<N> validator) {
28+
this.nClass = nClass;
29+
this.validator = validator;
30+
}
31+
32+
@Override
33+
public ConstraintViolations validate(T target, Locale locale,
34+
ConstraintContext constraintContext) {
35+
final N n = nClass.cast(target);
36+
37+
return this.validator.validate(n, locale, constraintContext);
38+
}
39+
40+
@Override
41+
public Validatable<T> failFast(boolean failFast) {
42+
final Validatable<N> validatable = this.validator.failFast(failFast);
43+
return new InheritanceValidator<>(nClass, validatable);
44+
}
45+
46+
@Override
47+
public boolean isFailFast() {
48+
return this.validator.isFailFast();
49+
}
50+
}

src/test/java/am/ik/yavi/core/ConstraintOnClassTest.java

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,55 +17,67 @@ public class ConstraintOnClassTest {
1717

1818
@ParameterizedTest
1919
@MethodSource("provideValidators")
20-
void testConstraintOnConditionClass(Validator<User> validator) {
21-
User validAdmin = new Admin("admin123", "admin@gmail", 27, "yavi123");
22-
User invalidAdmin = new Admin("Niraz", "niraz@gmail", 23, "user");
20+
void testConstraintOnConditionClass(Validator<Parent> validator) {
21+
Parent validChild = new Child(23, "drawing");
22+
Parent invalidChild = new Child(6, "drawing");
2323

24-
assertThat(validator.validate(validAdmin).isValid()).isTrue();
25-
assertThat(validator.validate(invalidAdmin).isValid()).isFalse();
24+
assertThat(validator.validate(validChild).isValid()).isTrue();
25+
assertThat(validator.validate(invalidChild).isValid()).isFalse();
2626
}
2727

2828
@ParameterizedTest
2929
@MethodSource("provideValidators")
30-
void testConstraintOnNonConditionClass(Validator<User> validator) {
31-
User validUser = new User("Rawad", "rawad@gmail", 25);
32-
User invalidUser = new User("Almog", "almog@gmail", 19);
30+
void testConstraintOnNonConditionClass(Validator<Parent> validator) {
31+
Parent validParent = new Parent(35);
32+
Parent invalidParent = new Parent(19);
3333

34-
assertThat(validator.validate(validUser).isValid()).isTrue();
35-
assertThat(validator.validate(invalidUser).isValid()).isFalse();
34+
assertThat(validator.validate(validParent).isValid()).isTrue();
35+
assertThat(validator.validate(invalidParent).isValid()).isFalse();
3636
}
3737

3838
static Stream<Arguments> provideValidators() {
39-
ValidatorBuilder<User> userValidatorBuilder = ValidatorBuilder.of(User.class)
40-
.constraint(User::getAge, "age", c -> c.greaterThan(20));
41-
Function<CharSequenceConstraint<Admin, String>, CharSequenceConstraint<Admin, String>> startsWithAdmin = (
42-
CharSequenceConstraint<Admin, String> c) -> c.startsWith("yavi");
39+
ValidatorBuilder<Parent> userValidatorBuilder = ValidatorBuilder.of(Parent.class)
40+
.constraint(Parent::getAge, "age", c -> c.greaterThan(20));
41+
Function<CharSequenceConstraint<Child, String>, CharSequenceConstraint<Child, String>> equalsToDrawing = (
42+
CharSequenceConstraint<Child, String> c) -> c.equalTo("drawing");
4343

4444
return Stream
4545
.of(Arguments.of(new ValidatorBuilder<>(userValidatorBuilder)
46-
.constraintOnClass(Admin.class,
47-
ValidatorBuilder.of(Admin.class)
48-
.constraint(Admin::getGroup, "group",
49-
startsWithAdmin)
46+
.constraintOnClass(Child.class,
47+
ValidatorBuilder.of(Child.class)
48+
.constraint(Child::getHobby, "hobby",
49+
equalsToDrawing)
5050
.build())
5151
.build()), Arguments
5252
.of(new ValidatorBuilder<>(userValidatorBuilder)
53-
.constraintOnClass(Admin.class,
54-
b -> b.constraint(Admin::getGroup,
55-
"group", startsWithAdmin))
53+
.constraintOnClass(Child.class,
54+
b -> b.constraint(Child::getHobby,
55+
"hobby", equalsToDrawing))
5656
.build()));
5757
}
5858

59-
private static class Admin extends User {
60-
private String group;
59+
private static class Child extends Parent {
60+
private String hobby;
6161

62-
public Admin(String name, String email, int age, String group) {
63-
super(name, email, age);
64-
this.group = group;
62+
public Child(int age, String hobby) {
63+
super(age);
64+
this.hobby = hobby;
6565
}
6666

67-
public String getGroup() {
68-
return group;
67+
public String getHobby() {
68+
return hobby;
69+
}
70+
}
71+
72+
private static class Parent {
73+
private final int age;
74+
75+
public Parent(int age) {
76+
this.age = age;
77+
}
78+
79+
public int getAge() {
80+
return age;
6981
}
7082
}
7183
}

0 commit comments

Comments
 (0)