Skip to content

Commit 8dc67c4

Browse files
committed
HV-1701 Add integer type specific min/max validators
- Add specific validators for min/max constraints and byte/short/integer types as the existing common number one makes additional actions that can be omitted in this case.
1 parent 6a0aa40 commit 8dc67c4

File tree

12 files changed

+230
-6
lines changed

12 files changed

+230
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.internal.constraintvalidators.bv.number.bound;
8+
9+
/**
10+
* Check that the number being validated is less than or equal to the maximum
11+
* value specified.
12+
*
13+
* @author Marko Bekhta
14+
*/
15+
public class MaxValidatorForByte extends AbstractMaxValidator<Byte> {
16+
17+
@Override
18+
protected int compare(Byte number) {
19+
return NumberComparatorHelper.compare( number.longValue(), maxValue );
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.internal.constraintvalidators.bv.number.bound;
8+
9+
/**
10+
* Check that the number being validated is less than or equal to the maximum
11+
* value specified.
12+
*
13+
* @author Marko Bekhta
14+
*/
15+
public class MaxValidatorForInteger extends AbstractMaxValidator<Integer> {
16+
17+
@Override
18+
protected int compare(Integer number) {
19+
return NumberComparatorHelper.compare( number.longValue(), maxValue );
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.internal.constraintvalidators.bv.number.bound;
8+
9+
/**
10+
* Check that the number being validated is less than or equal to the maximum
11+
* value specified.
12+
*
13+
* @author Marko Bekhta
14+
*/
15+
public class MaxValidatorForShort extends AbstractMaxValidator<Short> {
16+
17+
@Override
18+
protected int compare(Short number) {
19+
return NumberComparatorHelper.compare( number.longValue(), maxValue );
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.internal.constraintvalidators.bv.number.bound;
8+
9+
/**
10+
* Check that the number being validated is greater than or equal to the minimum
11+
* value specified.
12+
*
13+
* @author Marko Bekhta
14+
*/
15+
public class MinValidatorForByte extends AbstractMinValidator<Byte> {
16+
17+
@Override
18+
protected int compare(Byte number) {
19+
return NumberComparatorHelper.compare( number.longValue(), minValue );
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.internal.constraintvalidators.bv.number.bound;
8+
9+
/**
10+
* Check that the number being validated is greater than or equal to the minimum
11+
* value specified.
12+
*
13+
* @author Marko Bekhta
14+
*/
15+
public class MinValidatorForInteger extends AbstractMinValidator<Integer> {
16+
17+
@Override
18+
protected int compare(Integer number) {
19+
return NumberComparatorHelper.compare( number.longValue(), minValue );
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.internal.constraintvalidators.bv.number.bound;
8+
9+
/**
10+
* Check that the number being validated is greater than or equal to the minimum
11+
* value specified.
12+
*
13+
* @author Marko Bekhta
14+
*/
15+
public class MinValidatorForShort extends AbstractMinValidator<Short> {
16+
17+
@Override
18+
protected int compare(Short number) {
19+
return NumberComparatorHelper.compare( number.longValue(), minValue );
20+
}
21+
}

engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/bv/number/bound/NumberComparatorHelper.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,32 @@ public static int compare(Long number, long value) {
3333
}
3434

3535
public static int compare(Number number, long value, OptionalInt treatNanAs) {
36-
// In case of comparing numbers before we compare them as two longs:
37-
// 1. We need to check for floating point number as it should be treated differently in such case:
36+
// In case of comparing numbers we need to check for special cases:
37+
// 1. Floating point numbers should consider nan/infinity as values hence they should
38+
// be directed to corresponding overloaded methods:
3839
if ( number instanceof Double ) {
3940
return compare( (Double) number, value, treatNanAs );
4041
}
4142
if ( number instanceof Float ) {
4243
return compare( (Float) number, value, treatNanAs );
4344
}
4445

45-
// 2. We need to check for big numbers so that we don't lose data when converting them to long:
46+
// 2. For big numbers we don't want to lose any data so we just cast them and call corresponding methods:
4647
if ( number instanceof BigDecimal ) {
4748
return compare( (BigDecimal) number, value );
4849
}
4950
if ( number instanceof BigInteger ) {
5051
return compare( (BigInteger) number, value );
5152
}
5253

53-
return Long.compare( number.longValue(), value );
54+
// 3. For any integer types we convert them to long as we would do that anyway
55+
// when comparing with a long value. And use corresponding method for longs:
56+
if ( number instanceof Byte || number instanceof Integer || number instanceof Long || number instanceof Short ) {
57+
return compare( number.longValue(), value );
58+
}
59+
60+
// 4. As a fallback we convert the number to double:
61+
return compare( number.doubleValue(), value, treatNanAs );
5462
}
5563

5664
public static int compare(Double number, long value, OptionalInt treatNanAs) {

engine/src/main/java/org/hibernate/validator/internal/metadata/core/ConstraintHelper.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,22 @@
115115
import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForMap;
116116
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForBigDecimal;
117117
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForBigInteger;
118+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForByte;
118119
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForDouble;
119120
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForFloat;
121+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForInteger;
120122
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForLong;
121123
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForNumber;
124+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForShort;
122125
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForBigDecimal;
123126
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForBigInteger;
127+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForByte;
124128
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForDouble;
125129
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForFloat;
130+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForInteger;
126131
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForLong;
127132
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForNumber;
133+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForShort;
128134
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForBigDecimal;
129135
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForBigInteger;
130136
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForDouble;
@@ -427,20 +433,26 @@ public ConstraintHelper() {
427433
putConstraints( tmpConstraints, Max.class, Arrays.asList(
428434
MaxValidatorForBigDecimal.class,
429435
MaxValidatorForBigInteger.class,
436+
MaxValidatorForByte.class,
430437
MaxValidatorForDouble.class,
431438
MaxValidatorForFloat.class,
439+
MaxValidatorForInteger.class,
432440
MaxValidatorForLong.class,
433441
MaxValidatorForNumber.class,
442+
MaxValidatorForShort.class,
434443
MaxValidatorForCharSequence.class,
435444
MaxValidatorForMonetaryAmount.class
436445
) );
437446
putConstraints( tmpConstraints, Min.class, Arrays.asList(
438447
MinValidatorForBigDecimal.class,
439448
MinValidatorForBigInteger.class,
449+
MinValidatorForByte.class,
440450
MinValidatorForDouble.class,
441451
MinValidatorForFloat.class,
452+
MinValidatorForInteger.class,
442453
MinValidatorForLong.class,
443454
MinValidatorForNumber.class,
455+
MinValidatorForShort.class,
444456
MinValidatorForCharSequence.class,
445457
MinValidatorForMonetaryAmount.class
446458
) );
@@ -458,10 +470,13 @@ public ConstraintHelper() {
458470
putConstraints( tmpConstraints, Min.class, Arrays.asList(
459471
MinValidatorForBigDecimal.class,
460472
MinValidatorForBigInteger.class,
473+
MinValidatorForByte.class,
461474
MinValidatorForDouble.class,
462475
MinValidatorForFloat.class,
476+
MinValidatorForInteger.class,
463477
MinValidatorForLong.class,
464478
MinValidatorForNumber.class,
479+
MinValidatorForShort.class,
465480
MinValidatorForCharSequence.class
466481
) );
467482
}

engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/bv/BaseMinMaxValidatorForNumberTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,51 @@ protected void testValidatorBigInteger(ConstraintValidator<?, BigInteger> constr
7575
assertEquals( constraint.isValid( BigInteger.valueOf( 1560000000 ), null ), !isMax );
7676
}
7777

78+
protected void testValidatorByte(ConstraintValidator<?, Byte> constraint, boolean inclusive, boolean isMax) {
79+
if ( inclusive ) {
80+
assertTrue( constraint.isValid( (byte) 15, null ) );
81+
}
82+
else {
83+
assertFalse( constraint.isValid( (byte) 15, null ) );
84+
}
85+
86+
assertTrue( constraint.isValid( null, null ) );
87+
assertEquals( constraint.isValid( (byte) 14, null ), isMax );
88+
assertEquals( constraint.isValid( (byte) 16, null ), !isMax );
89+
assertEquals( constraint.isValid( Byte.MIN_VALUE, null ), isMax );
90+
assertEquals( constraint.isValid( Byte.MAX_VALUE, null ), !isMax );
91+
}
92+
93+
protected void testValidatorShort(ConstraintValidator<?, Short> constraint, boolean inclusive, boolean isMax) {
94+
if ( inclusive ) {
95+
assertTrue( constraint.isValid( (short) 15, null ) );
96+
}
97+
else {
98+
assertFalse( constraint.isValid( (short) 15, null ) );
99+
}
100+
101+
assertTrue( constraint.isValid( null, null ) );
102+
assertEquals( constraint.isValid( (short) 14, null ), isMax );
103+
assertEquals( constraint.isValid( (short) 16, null ), !isMax );
104+
assertEquals( constraint.isValid( Short.MIN_VALUE, null ), isMax );
105+
assertEquals( constraint.isValid( Short.MAX_VALUE, null ), !isMax );
106+
}
107+
108+
protected void testValidatorInteger(ConstraintValidator<?, Integer> constraint, boolean inclusive, boolean isMax) {
109+
if ( inclusive ) {
110+
assertTrue( constraint.isValid( 15, null ) );
111+
}
112+
else {
113+
assertFalse( constraint.isValid( 15, null ) );
114+
}
115+
116+
assertTrue( constraint.isValid( null, null ) );
117+
assertEquals( constraint.isValid( 14, null ), isMax );
118+
assertEquals( constraint.isValid( 16, null ), !isMax );
119+
assertEquals( constraint.isValid( Integer.MIN_VALUE, null ), isMax );
120+
assertEquals( constraint.isValid( Integer.MAX_VALUE, null ), !isMax );
121+
}
122+
78123
protected void testValidatorLong(ConstraintValidator<?, Long> constraint, boolean inclusive, boolean isMax) {
79124
if ( inclusive ) {
80125
assertTrue( constraint.isValid( 15L, null ) );

engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/bv/MaxValidatorForNumberTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.AbstractMaxValidator;
1818
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForBigDecimal;
1919
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForBigInteger;
20+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForByte;
2021
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForDouble;
2122
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForFloat;
23+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForInteger;
2224
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForLong;
2325
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForNumber;
26+
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForShort;
2427
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.AbstractDecimalMaxValidator;
2528
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForBigDecimal;
2629
import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForBigInteger;
@@ -140,6 +143,18 @@ private void testMax(Max m, boolean inclusive) {
140143
constraint.initialize( m );
141144
testValidatorBigInteger( constraint, inclusive, true );
142145

146+
constraint = new MaxValidatorForByte();
147+
constraint.initialize( m );
148+
testValidatorByte( constraint, inclusive, true );
149+
150+
constraint = new MaxValidatorForShort();
151+
constraint.initialize( m );
152+
testValidatorShort( constraint, inclusive, true );
153+
154+
constraint = new MaxValidatorForInteger();
155+
constraint.initialize( m );
156+
testValidatorInteger( constraint, inclusive, true );
157+
143158
constraint = new MaxValidatorForLong();
144159
constraint.initialize( m );
145160
testValidatorLong( constraint, inclusive, true );

0 commit comments

Comments
 (0)