diff --git a/src/main/java/org/javawebstack/validator/Validator.java b/src/main/java/org/javawebstack/validator/Validator.java index e0cdef6..ef0bebc 100644 --- a/src/main/java/org/javawebstack/validator/Validator.java +++ b/src/main/java/org/javawebstack/validator/Validator.java @@ -33,6 +33,7 @@ public class Validator { registerRuleType("ipv6", IPv6AddressRule.Validator.class, IPv6AddressRule.class); registerRuleType("int", IntegerRule.Validator.class, IntegerRule.class); registerRuleType("integer", IntegerRule.Validator.class, IntegerRule.class); + registerRuleType("double", DoubleRule.Validator.class, DoubleRule.class); registerRuleType("numeric", NumericRule.Validator.class, NumericRule.class); registerRuleType("num", NumericRule.Validator.class, NumericRule.class); registerRuleType("date", DateRule.Validator.class, DateRule.class); @@ -46,6 +47,8 @@ public class Validator { registerRuleType("uuid", UUIDRule.Validator.class, UUIDRule.class); } + private final Map rules = new HashMap<>(); + public static void registerRuleType(String name, Class type, Class annotationClass) { if (!ruleAnnotationClasses.containsKey(type) && annotationClass != null) ruleAnnotationClasses.put(type, annotationClass); @@ -130,8 +133,6 @@ public static T map(ValidationContext context, Class type, AbstractElemen return map(context, type, element, new AbstractMapper()); } - private final Map rules = new HashMap<>(); - public Validator rule(String[] key, ValidationRule... rules) { return rule(key, Arrays.asList(rules)); } @@ -321,7 +322,7 @@ private static Map getClassRules(Field field, Class< return rules; } if (type.equals(Double.class) || type.equals(Float.class)) { - rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new NumericRule.Validator()))); + rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new DoubleRule.Validator(Double.MIN_VALUE, Double.MAX_VALUE)))); return rules; } if (type.equals(UUID.class)) { diff --git a/src/main/java/org/javawebstack/validator/rule/DoubleRule.java b/src/main/java/org/javawebstack/validator/rule/DoubleRule.java new file mode 100644 index 0000000..ad0ba78 --- /dev/null +++ b/src/main/java/org/javawebstack/validator/rule/DoubleRule.java @@ -0,0 +1,74 @@ +package org.javawebstack.validator.rule; + +import org.javawebstack.abstractdata.AbstractElement; +import org.javawebstack.validator.ValidationContext; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Field; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface DoubleRule { + + double min() default Double.MIN_VALUE; + double max() default Double.MAX_VALUE; + + class Validator implements ValidationRule { + + private final double min; + private final double max; + + public Validator(DoubleRule rule) { + this(rule.min(), rule.max()); + } + + public Validator(double min, double max) { + this.min = min; + this.max = max; + } + + public Validator(String[] params) { + double min = Double.MIN_VALUE; + double max = Double.MAX_VALUE; + if (params.length > 0) + min = Double.parseDouble(params[0]); + if (params.length > 1) + max = Double.parseDouble(params[1]); + this.min = min; + this.max = max; + } + + public String validate(ValidationContext context, Field field, AbstractElement value) { + if (value == null || value.isNull()) + return null; + double v; + if (value.isNumber()) { + v = value.number().doubleValue(); + } else if (value.isString()) { + try { + v = Double.parseDouble(value.string()); + } catch (NumberFormatException ex) { + return "Not a double value"; + } + } else { + return "Not a double value"; + } + if (v < min) + return String.format("Smaller than the minimum value (%f < %f)", v, min); + if (v > max) + return String.format("Greater than the maximum value (%f > %f)", v, max); + return null; + } + + public String toString() { + return "Validator{" + + "min=" + min + + ", max=" + max + + '}'; + } + + } +} diff --git a/src/main/java/org/javawebstack/validator/rule/IntegerRule.java b/src/main/java/org/javawebstack/validator/rule/IntegerRule.java index d3ec861..1daebb9 100644 --- a/src/main/java/org/javawebstack/validator/rule/IntegerRule.java +++ b/src/main/java/org/javawebstack/validator/rule/IntegerRule.java @@ -16,7 +16,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface IntegerRule { int min(); - int max(); + int max() default Integer.MAX_VALUE; int step() default 1; class Validator implements ValidationRule { diff --git a/src/test/java/test/org/javawebstack/validator/DoubleRuleTest.java b/src/test/java/test/org/javawebstack/validator/DoubleRuleTest.java new file mode 100644 index 0000000..c20856c --- /dev/null +++ b/src/test/java/test/org/javawebstack/validator/DoubleRuleTest.java @@ -0,0 +1,40 @@ +package test.org.javawebstack.validator; + +import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.validator.ValidationContext; +import org.javawebstack.validator.Validator; +import org.javawebstack.validator.rule.DoubleRule; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class DoubleRuleTest { + @Test + public void testSimple() { + Validator validator = Validator.getValidator(SimpleTest.class); + SimpleTest test = new SimpleTest(); + test.value = "hello world"; + assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + test.value = "13.37"; + assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + } + + @Test + public void testEdgeCases() { + Validator validator = Validator.getValidator(EdgeTest.class); + EdgeTest test = new EdgeTest(); + test.value = 9.9; + assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + test.value = 10.1; + assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + } + + private class SimpleTest { + @DoubleRule + String value; + } + + private class EdgeTest { + @DoubleRule(min = 10) + Double value; + } +}