diff --git a/README.md b/README.md index a980461..f1dbc60 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,6 @@ You can find the current docs on our [website](https://docs.javawebstack.org/fra org.javawebstack validator - 1.0.1 + 1.0.2 ``` diff --git a/pom.xml b/pom.xml index b40ff0a..aa85f6f 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ 8 8 - 1.0.1-SNAPSHOT + 1.0.2-SNAPSHOT org.javawebstack @@ -44,15 +44,8 @@ org.javawebstack abstract-data - 1.0.4 + 1.0.6 - - - org.yaml - snakeyaml - 1.33 - - com.sun.mail javax.mail @@ -61,7 +54,7 @@ org.junit.jupiter junit-jupiter-engine - 5.8.1 + 5.10.0 test diff --git a/src/main/java/org/javawebstack/validator/Validator.java b/src/main/java/org/javawebstack/validator/Validator.java index e0cdef6..ea51609 100644 --- a/src/main/java/org/javawebstack/validator/Validator.java +++ b/src/main/java/org/javawebstack/validator/Validator.java @@ -2,8 +2,8 @@ import org.javawebstack.abstractdata.AbstractArray; import org.javawebstack.abstractdata.AbstractElement; -import org.javawebstack.abstractdata.AbstractMapper; import org.javawebstack.abstractdata.AbstractNull; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.abstractdata.mapper.MapperTypeSpec; import org.javawebstack.validator.rule.*; @@ -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); @@ -44,8 +45,12 @@ public class Validator { registerRuleType("email", EmailRule.Validator.class, EmailRule.class); registerRuleType("regex", RegexRule.Validator.class, RegexRule.class); registerRuleType("uuid", UUIDRule.Validator.class, UUIDRule.class); + registerRuleType("charset", CharsetRule.Validator.class, CharsetRule.class); + registerRuleType("word_count", WordCountRule.Validator.class, WordCountRule.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); @@ -118,20 +123,18 @@ public static Validator getValidator(Class type) { return validator; } - public static T map(ValidationContext context, Class type, AbstractElement element, AbstractMapper mapper) { + public static T map(ValidationContext context, Class type, AbstractElement element, Mapper mapper) { Validator validator = getValidator(type); ValidationResult result = validator.validate(context, element); if (!result.isValid()) throw new ValidationException(result); - return mapper.fromAbstract(element, type); + return mapper.map(element, type); } public static T map(ValidationContext context, Class type, AbstractElement element) { - return map(context, type, element, new AbstractMapper()); + return map(context, type, element, new Mapper()); } - private final Map rules = new HashMap<>(); - public Validator rule(String[] key, ValidationRule... rules) { return rule(key, Arrays.asList(rules)); } @@ -321,7 +324,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/CharsetRule.java b/src/main/java/org/javawebstack/validator/rule/CharsetRule.java new file mode 100644 index 0000000..ffa1215 --- /dev/null +++ b/src/main/java/org/javawebstack/validator/rule/CharsetRule.java @@ -0,0 +1,77 @@ +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; +import java.util.Locale; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface CharsetRule { + + String value() default ""; + boolean upper() default false; + boolean lower() default false; + boolean numeric() default false; + boolean accents() default false; + + class Validator implements ValidationRule { + + private static final String ALPHA = "abcdefghijklmnopqrstuvwxyz"; + private static final String ACCENTS = "äëïöüéàèùâêîôûç"; + + private final String charset; + + public Validator(CharsetRule rule) { + this(makeCharset(rule)); + } + + public Validator(String charset) { + this.charset = charset; + } + + public Validator(String[] params) { + this(params.length > 0 ? params[0] : ""); + } + + public String validate(ValidationContext context, Field field, AbstractElement value) { + if (value == null || value.isNull()) + return null; + if (!value.isPrimitive()) + return "Not a string value"; + char[] chars = value.string().toCharArray(); + for(int i=0; i 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/main/java/org/javawebstack/validator/rule/WordCountRule.java b/src/main/java/org/javawebstack/validator/rule/WordCountRule.java new file mode 100644 index 0000000..1427f94 --- /dev/null +++ b/src/main/java/org/javawebstack/validator/rule/WordCountRule.java @@ -0,0 +1,53 @@ +package org.javawebstack.validator.rule; + +import org.javawebstack.abstractdata.AbstractElement; +import org.javawebstack.validator.ValidationContext; + +import java.lang.reflect.Field; + +public @interface WordCountRule { + + int value(); + int max() default 1; + String separator() default " "; + + class Validator implements ValidationRule { + + private final int min; + private final int max; + private final String separator; + + public Validator(WordCountRule rule) { + this(rule.value(), rule.max(), rule.separator()); + } + + public Validator(int min, int max, String separator) { + this.min = min; + this.max = Math.min(min, max); + this.separator = separator; + } + + public Validator(String[] params) { + this( + params.length > 0 ? Integer.parseInt(params[0]) : 1, + params.length > 1 ? Integer.parseInt(params[0]) : 1, + params.length > 2 ? params[2] : " " + ); + } + + public String validate(ValidationContext context, Field field, AbstractElement value) { + if (value == null || value.isNull()) + return null; + if (!value.isPrimitive()) + return "Not a string value"; + int wordCount = value.string().split(separator).length; + if (wordCount < min) + return String.format("Less than the minimum word count (%d < %d)", wordCount, min); + if (wordCount > max) + return String.format("More than maximum word count (%d > %d)", wordCount, max); + return null; + } + + } + +} diff --git a/src/test/java/test/org/javawebstack/validator/AnnotationTest.java b/src/test/java/test/org/javawebstack/validator/AnnotationTest.java index da114ec..1ea98b2 100644 --- a/src/test/java/test/org/javawebstack/validator/AnnotationTest.java +++ b/src/test/java/test/org/javawebstack/validator/AnnotationTest.java @@ -1,7 +1,7 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; import org.javawebstack.validator.rule.IntegerRule; @@ -16,11 +16,11 @@ public class AnnotationTest { public void testIntegerAnnotation () { Validator validator = Validator.getValidator(TestObject1.class); TestObject1 test = new TestObject1(); - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.x = 6; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.x = 1338; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } private static class TestObject1 { 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..36b75ef --- /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.mapper.Mapper; +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 Mapper().map(test)).isValid()); + test.value = "13.37"; + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(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 Mapper().map(test)).isValid()); + test.value = 10.1; + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); + } + + private class SimpleTest { + @DoubleRule + String value; + } + + private class EdgeTest { + @DoubleRule(min = 10) + Double value; + } +} diff --git a/src/test/java/test/org/javawebstack/validator/EmailRuleTest.java b/src/test/java/test/org/javawebstack/validator/EmailRuleTest.java index d6d8c44..6a05d68 100644 --- a/src/test/java/test/org/javawebstack/validator/EmailRuleTest.java +++ b/src/test/java/test/org/javawebstack/validator/EmailRuleTest.java @@ -1,6 +1,6 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.Rule; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; @@ -16,9 +16,9 @@ public void testSimpleEMailRule() { Validator validator = Validator.getValidator(TestObject1.class); TestObject1 test = new TestObject1(); test.email = "Test"; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.email = "info@javawebstack.org"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } private static class TestObject1 { diff --git a/src/test/java/test/org/javawebstack/validator/IPv4RuleTest.java b/src/test/java/test/org/javawebstack/validator/IPv4RuleTest.java index 6faebdc..c03080d 100644 --- a/src/test/java/test/org/javawebstack/validator/IPv4RuleTest.java +++ b/src/test/java/test/org/javawebstack/validator/IPv4RuleTest.java @@ -1,6 +1,6 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.Rule; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; @@ -17,13 +17,13 @@ public void testSimpleIPV4Rules() { TestObject1 test = new TestObject1(); test.ip = "ThisIsNotAnIP"; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.ip = "0.0.0.0"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.ip = "255.255.255.255"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.ip = "256.455.275.295"; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } diff --git a/src/test/java/test/org/javawebstack/validator/IPv6RuleTest.java b/src/test/java/test/org/javawebstack/validator/IPv6RuleTest.java index d46ebf2..a50da17 100644 --- a/src/test/java/test/org/javawebstack/validator/IPv6RuleTest.java +++ b/src/test/java/test/org/javawebstack/validator/IPv6RuleTest.java @@ -1,6 +1,6 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.Rule; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; @@ -17,11 +17,11 @@ public void testSimpleIPV4Rules() { // FIX IT //test.ip = "ThisIsNotAnIP"; - //assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + //assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.ip = "::1/128"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.ip = "0:0:0:0:0:0:0:0"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } diff --git a/src/test/java/test/org/javawebstack/validator/MultipleRequiredFieldTest.java b/src/test/java/test/org/javawebstack/validator/MultipleRequiredFieldTest.java index f3ddee2..f74bd26 100644 --- a/src/test/java/test/org/javawebstack/validator/MultipleRequiredFieldTest.java +++ b/src/test/java/test/org/javawebstack/validator/MultipleRequiredFieldTest.java @@ -1,6 +1,6 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.Rule; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; @@ -15,7 +15,7 @@ public void testSimpleMultipleRules() { Validator validator = Validator.getValidator(TestObject1.class); TestObject1 test = new TestObject1(); test.name = "Test"; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } diff --git a/src/test/java/test/org/javawebstack/validator/MultipleRuleTest.java b/src/test/java/test/org/javawebstack/validator/MultipleRuleTest.java index 825d800..915d67f 100644 --- a/src/test/java/test/org/javawebstack/validator/MultipleRuleTest.java +++ b/src/test/java/test/org/javawebstack/validator/MultipleRuleTest.java @@ -1,6 +1,6 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.Rule; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; @@ -15,11 +15,11 @@ public class MultipleRuleTest { public void testSimpleMultipleRules() { Validator validator = Validator.getValidator(TestObject1.class); TestObject1 test = new TestObject1(); - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.name = "Test"; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.name = "123"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } diff --git a/src/test/java/test/org/javawebstack/validator/NumericRuleTest.java b/src/test/java/test/org/javawebstack/validator/NumericRuleTest.java index eb6eabd..228fb12 100644 --- a/src/test/java/test/org/javawebstack/validator/NumericRuleTest.java +++ b/src/test/java/test/org/javawebstack/validator/NumericRuleTest.java @@ -1,6 +1,6 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.Rule; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; @@ -16,9 +16,9 @@ public void testSimpleNumericRule() { Validator validator = Validator.getValidator(TestObject1.class); TestObject1 test = new TestObject1(); test.email = "abc"; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.email = "123"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } private static class TestObject1 { diff --git a/src/test/java/test/org/javawebstack/validator/RequiredRuleTest.java b/src/test/java/test/org/javawebstack/validator/RequiredRuleTest.java index fd7d2b2..2f01694 100644 --- a/src/test/java/test/org/javawebstack/validator/RequiredRuleTest.java +++ b/src/test/java/test/org/javawebstack/validator/RequiredRuleTest.java @@ -1,6 +1,6 @@ package test.org.javawebstack.validator; -import org.javawebstack.abstractdata.AbstractMapper; +import org.javawebstack.abstractdata.mapper.Mapper; import org.javawebstack.validator.Rule; import org.javawebstack.validator.ValidationContext; import org.javawebstack.validator.Validator; @@ -16,10 +16,10 @@ public class RequiredRuleTest { public void testSimpleRequiredRule() { Validator validator = Validator.getValidator(TestObject1.class); TestObject1 test = new TestObject1(); - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.name = "Test"; test.password = "123456"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } @Test @@ -27,25 +27,25 @@ public void testEmptyStringOption() { Validator validator = Validator.getValidator(TestObject1.class); TestObject1 test = new TestObject1(); test.name = ""; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.name = "Test"; test.password = ""; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); } @Test public void testInnerRequiredRule() { Validator validator = Validator.getValidator(TestObject2.class); TestObject2 test = new TestObject2(); - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.inners = new TestObject2.Inner[0]; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.inners = new TestObject2.Inner[]{ new TestObject2.Inner() }; - assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); test.inners[0].name = "Test"; - assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid()); + assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid()); }