Skip to content

Commit 140353a

Browse files
committed
Max for Integer, Long, BigDecimal using _type attribute switch
1 parent 1e57dc7 commit 140353a

File tree

4 files changed

+102
-2
lines changed

4 files changed

+102
-2
lines changed

validator/src/main/java/io/avaje/validation/adapter/ValidationContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,7 @@ interface AdapterCreateRequest {
161161
Map<String, Object> attributes();
162162

163163
Message message();
164+
165+
String targetType();
164166
}
165167
}

validator/src/main/java/io/avaje/validation/core/CoreAdapterBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ record Request(
114114

115115
) implements ValidationContext.AdapterCreateRequest {
116116

117+
@Override
118+
public String targetType() {
119+
return (String)attributes.get("_type");
120+
}
121+
117122
@Override
118123
public ValidationContext.Message message() {
119124
return ctx.message(attributes);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package io.avaje.validation.core.adapters;
2+
3+
import io.avaje.validation.adapter.AbstractConstraintAdapter;
4+
import io.avaje.validation.adapter.ValidationContext.AdapterCreateRequest;
5+
6+
import java.math.BigDecimal;
7+
8+
class NumMax {
9+
10+
static abstract class MaxIntegerBase<T> extends AbstractConstraintAdapter<T> {
11+
12+
protected final long value;
13+
14+
MaxIntegerBase(AdapterCreateRequest request) {
15+
super(request);
16+
final var attributes = request.attributes();
17+
this.value = (long) attributes.get("value");
18+
}
19+
20+
MaxIntegerBase(AdapterCreateRequest request, long value) {
21+
super(request);
22+
this.value = value;
23+
}
24+
}
25+
26+
static final class IntegerAdapter extends MaxIntegerBase<Integer> {
27+
28+
IntegerAdapter(AdapterCreateRequest request) {
29+
super(request);
30+
}
31+
32+
IntegerAdapter(AdapterCreateRequest request, long value) {
33+
super(request, value);
34+
}
35+
36+
@Override
37+
public boolean isValid(Integer number) {
38+
// null values are valid
39+
return number == null || number <= value;
40+
}
41+
}
42+
43+
static final class LongAdapter extends MaxIntegerBase<Long> {
44+
45+
LongAdapter(AdapterCreateRequest request) {
46+
super(request);
47+
}
48+
49+
LongAdapter(AdapterCreateRequest request, long value) {
50+
super(request, value);
51+
}
52+
53+
@Override
54+
public boolean isValid(Long number) {
55+
// null values are valid
56+
return number == null || number <= value;
57+
}
58+
}
59+
60+
static final class BigDecimalAdapter extends MaxIntegerBase<BigDecimal> {
61+
62+
private final BigDecimal bdMax;
63+
BigDecimalAdapter(AdapterCreateRequest request) {
64+
super(request);
65+
this.bdMax = BigDecimal.valueOf(value);
66+
}
67+
68+
BigDecimalAdapter(AdapterCreateRequest request, long value) {
69+
super(request, value);
70+
this.bdMax = BigDecimal.valueOf(value);
71+
}
72+
73+
@Override
74+
public boolean isValid(BigDecimal number) {
75+
// null values are valid
76+
return number == null || number.compareTo(bdMax) <= 0;
77+
}
78+
}
79+
}

validator/src/main/java/io/avaje/validation/core/adapters/NumberAdapters.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,41 @@
77
import java.util.Optional;
88

99
import io.avaje.validation.adapter.AbstractConstraintAdapter;
10+
import io.avaje.validation.adapter.ValidationAdapter;
1011
import io.avaje.validation.adapter.ValidationContext;
1112
import io.avaje.validation.adapter.ValidationContext.AdapterCreateRequest;
1213

1314
public final class NumberAdapters {
1415
private NumberAdapters() {}
1516

1617
public static final ValidationContext.AnnotationFactory FACTORY =
17-
request->switch (request.annotationType().getSimpleName()) {
18+
request -> switch (request.annotationType().getSimpleName()) {
1819
case "Digits" -> new DigitsAdapter(request);
1920
case "Positive" -> new PositiveAdapter(request, false);
2021
case "PositiveOrZero" -> new PositiveAdapter(request, true);
2122
case "Negative" -> new NegativeAdapter(request, false);
2223
case "NegativeOrZero" -> new NegativeAdapter(request, true);
23-
case "Max" -> new MaxAdapter(request);
24+
case "Max" -> forMax(request);
2425
case "Min" -> new MinAdapter(request);
2526
case "DecimalMax" -> new DecimalMaxAdapter(request);
2627
case "DecimalMin" -> new DecimalMinAdapter(request);
2728
case "Range" -> new RangeAdapter(request);
2829
default -> null;
2930
};
3031

32+
private static ValidationAdapter<?> forMax(AdapterCreateRequest request) {
33+
final String targetType = request.targetType();
34+
if (targetType == null) {
35+
return new MaxAdapter(request);
36+
}
37+
return switch (targetType) {
38+
case "Integer" -> new NumMax.IntegerAdapter(request);
39+
case "Long" -> new NumMax.LongAdapter(request);
40+
case "BigDecimal" -> new NumMax.BigDecimalAdapter(request);
41+
default -> new MaxAdapter(request);
42+
};
43+
}
44+
3145
private static final class DecimalMaxAdapter extends AbstractConstraintAdapter<Number> {
3246

3347
private final BigDecimal value;

0 commit comments

Comments
 (0)