Skip to content

Commit ebe2ae2

Browse files
authored
Merge pull request #10 from JavaWebStack/dev
Release 1.0.2
2 parents 42bd524 + d91e2fc commit ebe2ae2

File tree

16 files changed

+293
-53
lines changed

16 files changed

+293
-53
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ You can find the current docs on our [website](https://docs.javawebstack.org/fra
2222
<dependency>
2323
<groupId>org.javawebstack</groupId>
2424
<artifactId>validator</artifactId>
25-
<version>1.0.1</version>
25+
<version>1.0.2</version>
2626
</dependency>
2727
```

pom.xml

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<properties>
88
<maven.compiler.source>8</maven.compiler.source>
99
<maven.compiler.target>8</maven.compiler.target>
10-
<buildVersion>1.0.1-SNAPSHOT</buildVersion>
10+
<buildVersion>1.0.2-SNAPSHOT</buildVersion>
1111
</properties>
1212

1313
<groupId>org.javawebstack</groupId>
@@ -44,15 +44,8 @@
4444
<dependency>
4545
<groupId>org.javawebstack</groupId>
4646
<artifactId>abstract-data</artifactId>
47-
<version>1.0.4</version>
47+
<version>1.0.6</version>
4848
</dependency>
49-
<!--- Temporary fix for transitive vulnerabilities -->
50-
<dependency>
51-
<groupId>org.yaml</groupId>
52-
<artifactId>snakeyaml</artifactId>
53-
<version>1.33</version>
54-
</dependency>
55-
<!--- ============================================ -->
5649
<dependency>
5750
<groupId>com.sun.mail</groupId>
5851
<artifactId>javax.mail</artifactId>
@@ -61,7 +54,7 @@
6154
<dependency>
6255
<groupId>org.junit.jupiter</groupId>
6356
<artifactId>junit-jupiter-engine</artifactId>
64-
<version>5.8.1</version>
57+
<version>5.10.0</version>
6558
<scope>test</scope>
6659
</dependency>
6760
</dependencies>

src/main/java/org/javawebstack/validator/Validator.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import org.javawebstack.abstractdata.AbstractArray;
44
import org.javawebstack.abstractdata.AbstractElement;
5-
import org.javawebstack.abstractdata.AbstractMapper;
65
import org.javawebstack.abstractdata.AbstractNull;
6+
import org.javawebstack.abstractdata.mapper.Mapper;
77
import org.javawebstack.abstractdata.mapper.MapperTypeSpec;
88
import org.javawebstack.validator.rule.*;
99

@@ -33,6 +33,7 @@ public class Validator {
3333
registerRuleType("ipv6", IPv6AddressRule.Validator.class, IPv6AddressRule.class);
3434
registerRuleType("int", IntegerRule.Validator.class, IntegerRule.class);
3535
registerRuleType("integer", IntegerRule.Validator.class, IntegerRule.class);
36+
registerRuleType("double", DoubleRule.Validator.class, DoubleRule.class);
3637
registerRuleType("numeric", NumericRule.Validator.class, NumericRule.class);
3738
registerRuleType("num", NumericRule.Validator.class, NumericRule.class);
3839
registerRuleType("date", DateRule.Validator.class, DateRule.class);
@@ -44,8 +45,12 @@ public class Validator {
4445
registerRuleType("email", EmailRule.Validator.class, EmailRule.class);
4546
registerRuleType("regex", RegexRule.Validator.class, RegexRule.class);
4647
registerRuleType("uuid", UUIDRule.Validator.class, UUIDRule.class);
48+
registerRuleType("charset", CharsetRule.Validator.class, CharsetRule.class);
49+
registerRuleType("word_count", WordCountRule.Validator.class, WordCountRule.class);
4750
}
4851

52+
private final Map<String[], ValidationConfig> rules = new HashMap<>();
53+
4954
public static void registerRuleType(String name, Class<? extends ValidationRule> type, Class<? extends Annotation> annotationClass) {
5055
if (!ruleAnnotationClasses.containsKey(type) && annotationClass != null)
5156
ruleAnnotationClasses.put(type, annotationClass);
@@ -118,20 +123,18 @@ public static Validator getValidator(Class<?> type) {
118123
return validator;
119124
}
120125

121-
public static <T> T map(ValidationContext context, Class<T> type, AbstractElement element, AbstractMapper mapper) {
126+
public static <T> T map(ValidationContext context, Class<T> type, AbstractElement element, Mapper mapper) {
122127
Validator validator = getValidator(type);
123128
ValidationResult result = validator.validate(context, element);
124129
if (!result.isValid())
125130
throw new ValidationException(result);
126-
return mapper.fromAbstract(element, type);
131+
return mapper.map(element, type);
127132
}
128133

129134
public static <T> T map(ValidationContext context, Class<T> type, AbstractElement element) {
130-
return map(context, type, element, new AbstractMapper());
135+
return map(context, type, element, new Mapper());
131136
}
132137

133-
private final Map<String[], ValidationConfig> rules = new HashMap<>();
134-
135138
public Validator rule(String[] key, ValidationRule... rules) {
136139
return rule(key, Arrays.asList(rules));
137140
}
@@ -321,7 +324,7 @@ private static Map<String[], ValidationConfig> getClassRules(Field field, Class<
321324
return rules;
322325
}
323326
if (type.equals(Double.class) || type.equals(Float.class)) {
324-
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new NumericRule.Validator())));
327+
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new DoubleRule.Validator(Double.MIN_VALUE, Double.MAX_VALUE))));
325328
return rules;
326329
}
327330
if (type.equals(UUID.class)) {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package org.javawebstack.validator.rule;
2+
3+
import org.javawebstack.abstractdata.AbstractElement;
4+
import org.javawebstack.validator.ValidationContext;
5+
6+
import java.lang.annotation.ElementType;
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.RetentionPolicy;
9+
import java.lang.annotation.Target;
10+
import java.lang.reflect.Field;
11+
import java.util.Locale;
12+
13+
@Target(ElementType.FIELD)
14+
@Retention(RetentionPolicy.RUNTIME)
15+
public @interface CharsetRule {
16+
17+
String value() default "";
18+
boolean upper() default false;
19+
boolean lower() default false;
20+
boolean numeric() default false;
21+
boolean accents() default false;
22+
23+
class Validator implements ValidationRule {
24+
25+
private static final String ALPHA = "abcdefghijklmnopqrstuvwxyz";
26+
private static final String ACCENTS = "äëïöüéàèùâêîôûç";
27+
28+
private final String charset;
29+
30+
public Validator(CharsetRule rule) {
31+
this(makeCharset(rule));
32+
}
33+
34+
public Validator(String charset) {
35+
this.charset = charset;
36+
}
37+
38+
public Validator(String[] params) {
39+
this(params.length > 0 ? params[0] : "");
40+
}
41+
42+
public String validate(ValidationContext context, Field field, AbstractElement value) {
43+
if (value == null || value.isNull())
44+
return null;
45+
if (!value.isPrimitive())
46+
return "Not a string value";
47+
char[] chars = value.string().toCharArray();
48+
for(int i=0; i<chars.length; i++) {
49+
char c = chars[i];
50+
if(!charset.contains(String.valueOf(c))) {
51+
return String.format("Forbidden character '%c' at position %d", c, i);
52+
}
53+
}
54+
return null;
55+
}
56+
57+
private static String makeCharset(CharsetRule rule) {
58+
StringBuilder sb = new StringBuilder(rule.value());
59+
if(rule.lower()) {
60+
sb.append(ALPHA);
61+
if(rule.accents())
62+
sb.append(ACCENTS);
63+
}
64+
if(rule.upper()) {
65+
sb.append(ALPHA.toUpperCase(Locale.ROOT));
66+
if(rule.accents())
67+
sb.append(ACCENTS.toUpperCase(Locale.ROOT));
68+
}
69+
if(rule.numeric()) {
70+
sb.append("1234567890");
71+
}
72+
return sb.toString();
73+
}
74+
75+
}
76+
77+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.javawebstack.validator.rule;
2+
3+
import org.javawebstack.abstractdata.AbstractElement;
4+
import org.javawebstack.validator.ValidationContext;
5+
6+
import java.lang.annotation.ElementType;
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.RetentionPolicy;
9+
import java.lang.annotation.Target;
10+
import java.lang.reflect.Field;
11+
12+
@Target(ElementType.FIELD)
13+
@Retention(RetentionPolicy.RUNTIME)
14+
public @interface DoubleRule {
15+
16+
double min() default Double.MIN_VALUE;
17+
double max() default Double.MAX_VALUE;
18+
19+
class Validator implements ValidationRule {
20+
21+
private final double min;
22+
private final double max;
23+
24+
public Validator(DoubleRule rule) {
25+
this(rule.min(), rule.max());
26+
}
27+
28+
public Validator(double min, double max) {
29+
this.min = min;
30+
this.max = max;
31+
}
32+
33+
public Validator(String[] params) {
34+
double min = Double.MIN_VALUE;
35+
double max = Double.MAX_VALUE;
36+
if (params.length > 0)
37+
min = Double.parseDouble(params[0]);
38+
if (params.length > 1)
39+
max = Double.parseDouble(params[1]);
40+
this.min = min;
41+
this.max = max;
42+
}
43+
44+
public String validate(ValidationContext context, Field field, AbstractElement value) {
45+
if (value == null || value.isNull())
46+
return null;
47+
double v;
48+
if (value.isNumber()) {
49+
v = value.number().doubleValue();
50+
} else if (value.isString()) {
51+
try {
52+
v = Double.parseDouble(value.string());
53+
} catch (NumberFormatException ex) {
54+
return "Not a double value";
55+
}
56+
} else {
57+
return "Not a double value";
58+
}
59+
if (v < min)
60+
return String.format("Smaller than the minimum value (%f < %f)", v, min);
61+
if (v > max)
62+
return String.format("Greater than the maximum value (%f > %f)", v, max);
63+
return null;
64+
}
65+
66+
public String toString() {
67+
return "Validator{" +
68+
"min=" + min +
69+
", max=" + max +
70+
'}';
71+
}
72+
73+
}
74+
}

src/main/java/org/javawebstack/validator/rule/IntegerRule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
@Retention(RetentionPolicy.RUNTIME)
1717
public @interface IntegerRule {
1818
int min();
19-
int max();
19+
int max() default Integer.MAX_VALUE;
2020
int step() default 1;
2121

2222
class Validator implements ValidationRule {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.javawebstack.validator.rule;
2+
3+
import org.javawebstack.abstractdata.AbstractElement;
4+
import org.javawebstack.validator.ValidationContext;
5+
6+
import java.lang.reflect.Field;
7+
8+
public @interface WordCountRule {
9+
10+
int value();
11+
int max() default 1;
12+
String separator() default " ";
13+
14+
class Validator implements ValidationRule {
15+
16+
private final int min;
17+
private final int max;
18+
private final String separator;
19+
20+
public Validator(WordCountRule rule) {
21+
this(rule.value(), rule.max(), rule.separator());
22+
}
23+
24+
public Validator(int min, int max, String separator) {
25+
this.min = min;
26+
this.max = Math.min(min, max);
27+
this.separator = separator;
28+
}
29+
30+
public Validator(String[] params) {
31+
this(
32+
params.length > 0 ? Integer.parseInt(params[0]) : 1,
33+
params.length > 1 ? Integer.parseInt(params[0]) : 1,
34+
params.length > 2 ? params[2] : " "
35+
);
36+
}
37+
38+
public String validate(ValidationContext context, Field field, AbstractElement value) {
39+
if (value == null || value.isNull())
40+
return null;
41+
if (!value.isPrimitive())
42+
return "Not a string value";
43+
int wordCount = value.string().split(separator).length;
44+
if (wordCount < min)
45+
return String.format("Less than the minimum word count (%d < %d)", wordCount, min);
46+
if (wordCount > max)
47+
return String.format("More than maximum word count (%d > %d)", wordCount, max);
48+
return null;
49+
}
50+
51+
}
52+
53+
}

src/test/java/test/org/javawebstack/validator/AnnotationTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package test.org.javawebstack.validator;
22

33

4-
import org.javawebstack.abstractdata.AbstractMapper;
4+
import org.javawebstack.abstractdata.mapper.Mapper;
55
import org.javawebstack.validator.ValidationContext;
66
import org.javawebstack.validator.Validator;
77
import org.javawebstack.validator.rule.IntegerRule;
@@ -16,11 +16,11 @@ public class AnnotationTest {
1616
public void testIntegerAnnotation () {
1717
Validator validator = Validator.getValidator(TestObject1.class);
1818
TestObject1 test = new TestObject1();
19-
assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid());
19+
assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid());
2020
test.x = 6;
21-
assertTrue(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid());
21+
assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid());
2222
test.x = 1338;
23-
assertFalse(validator.validate(new ValidationContext(), new AbstractMapper().toAbstract(test)).isValid());
23+
assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid());
2424
}
2525

2626
private static class TestObject1 {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package test.org.javawebstack.validator;
2+
3+
import org.javawebstack.abstractdata.mapper.Mapper;
4+
import org.javawebstack.validator.ValidationContext;
5+
import org.javawebstack.validator.Validator;
6+
import org.javawebstack.validator.rule.DoubleRule;
7+
import org.junit.jupiter.api.Test;
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
public class DoubleRuleTest {
11+
@Test
12+
public void testSimple() {
13+
Validator validator = Validator.getValidator(SimpleTest.class);
14+
SimpleTest test = new SimpleTest();
15+
test.value = "hello world";
16+
assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid());
17+
test.value = "13.37";
18+
assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid());
19+
}
20+
21+
@Test
22+
public void testEdgeCases() {
23+
Validator validator = Validator.getValidator(EdgeTest.class);
24+
EdgeTest test = new EdgeTest();
25+
test.value = 9.9;
26+
assertFalse(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid());
27+
test.value = 10.1;
28+
assertTrue(validator.validate(new ValidationContext(), new Mapper().map(test)).isValid());
29+
}
30+
31+
private class SimpleTest {
32+
@DoubleRule
33+
String value;
34+
}
35+
36+
private class EdgeTest {
37+
@DoubleRule(min = 10)
38+
Double value;
39+
}
40+
}

0 commit comments

Comments
 (0)