Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 47 additions & 28 deletions src/main/java/org/javawebstack/validator/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.javawebstack.abstractdata.AbstractNull;
import org.javawebstack.validator.rule.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
Expand All @@ -19,30 +20,35 @@ public class Validator {
private static final Map<String, Constructor<? extends ValidationRule>> validationRules = new HashMap<>();
private static final Map<Class<?>, Validator> validators = new HashMap<>();

private static final Map<Class<? extends ValidationRule>, Class<? extends Annotation>> ruleAnnotationClasses = new HashMap<>();

static {
registerRuleType("string", StringRule.class);
registerRuleType("boolean", BooleanRule.class);
registerRuleType("bool", BooleanRule.class);
registerRuleType("enum", EnumRule.class);
registerRuleType("required", RequiredRule.class);
registerRuleType("req", RequiredRule.class);
registerRuleType("ipv4", IPv4AddressRule.class);
registerRuleType("ipv6", IPv6AddressRule.class);
registerRuleType("int", IntegerRule.class);
registerRuleType("integer", IntegerRule.class);
registerRuleType("numeric", NumericRule.class);
registerRuleType("num", NumericRule.class);
registerRuleType("date", DateRule.class);
registerRuleType("array", ArrayRule.class);
registerRuleType("list", ArrayRule.class);
registerRuleType("alpha", AlphaRule.class);
registerRuleType("alpha_num", AlphaNumRule.class);
registerRuleType("alpha_dash", AlphaDashRule.class);
registerRuleType("email", EmailRule.class);
registerRuleType("regex", RegexRule.class);
registerRuleType("string", StringRule.Validator.class, StringRule.class);
registerRuleType("boolean", BooleanRule.Validator.class, BooleanRule.class);
registerRuleType("bool", BooleanRule.Validator.class, BooleanRule.class);
registerRuleType("enum", EnumRule.Validator.class, EnumRule.class);
registerRuleType("required", RequiredRule.Validator.class, RequiredRule.class);
registerRuleType("req", RequiredRule.Validator.class, RequiredRule.class);
registerRuleType("ipv4", IPv4AddressRule.Validator.class, IPv4AddressRule.class);
registerRuleType("ipv6", IPv6AddressRule.Validator.class, IPv6AddressRule.class);
registerRuleType("int", IntegerRule.Validator.class, IntegerRule.class);
registerRuleType("integer", IntegerRule.Validator.class, IntegerRule.class);
registerRuleType("numeric", NumericRule.Validator.class, NumericRule.class);
registerRuleType("num", NumericRule.Validator.class, NumericRule.class);
registerRuleType("date", DateRule.Validator.class, DateRule.class);
registerRuleType("array", ArrayRule.Validator.class, ArrayRule.class);
registerRuleType("list", ArrayRule.Validator.class, ArrayRule.class);
registerRuleType("alpha", AlphaRule.Validator.class, AlphaRule.class);
registerRuleType("alpha_num", AlphaNumRule.Validator.class, AlphaNumRule.class);
registerRuleType("alpha_dash", AlphaDashRule.Validator.class, AlphaDashRule.class);
registerRuleType("email", EmailRule.Validator.class, EmailRule.class);
registerRuleType("regex", RegexRule.Validator.class, RegexRule.class);
registerRuleType("uuid", UUIDRule.Validator.class, UUIDRule.class);
}

public static void registerRuleType(String name, Class<? extends ValidationRule> type) {
public static void registerRuleType(String name, Class<? extends ValidationRule> type, Class<? extends Annotation> annotationClass) {
if (!ruleAnnotationClasses.containsKey(type) && annotationClass != null)
ruleAnnotationClasses.put(type, annotationClass);
try {
Constructor<? extends ValidationRule> constructor = type.getDeclaredConstructor(String[].class);
constructor.setAccessible(true);
Expand Down Expand Up @@ -296,31 +302,31 @@ private static Map<String[], ValidationConfig> getClassRules(Field field, Class<
if (type.equals(Long.class))
return rules;
if (type.equals(Timestamp.class) || type.equals(java.util.Date.class)) {
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new DateRule(new String[]{}))));
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new DateRule.Validator(new String[]{}))));
return rules;
}
if (type.equals(Date.class)) {
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new DateRule(new String[]{"date"}))));
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new DateRule.Validator(new String[]{"date"}))));
return rules;
}
if (type.equals(Boolean.class)) {
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new BooleanRule())));
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new BooleanRule.Validator())));
return rules;
}
if (type.equals(Integer.class)) {
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new IntegerRule(Integer.MIN_VALUE, Integer.MAX_VALUE))));
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new IntegerRule.Validator(Integer.MIN_VALUE, Integer.MAX_VALUE))));
return rules;
}
if (type.equals(Double.class) || type.equals(Float.class)) {
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new NumericRule())));
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new NumericRule.Validator())));
return rules;
}
if (type.equals(UUID.class)) {
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new UUIDRule())));
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new UUIDRule.Validator())));
return rules;
}
if (type.isEnum()) {
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new EnumRule((Class<? extends Enum<?>>) type))));
rules.put(new String[0], new ValidationConfig(field, Collections.singletonList(new EnumRule.Validator((Class<? extends Enum<?>>) type))));
return rules;
}
if (type.isArray()) {
Expand Down Expand Up @@ -352,6 +358,19 @@ private static Map<String[], ValidationConfig> getClassRules(Field field, Class<
if (r.size() > 0)
addMapRules(f, rules, new String[]{name}, r);
}
ruleAnnotationClasses.entrySet().stream().distinct().forEach(annotation -> {
Annotation a = f.getDeclaredAnnotation(annotation.getValue());
if (a != null) {
List<ValidationRule> r = new ArrayList<>();
try {
Constructor<ValidationRule> constructor = (Constructor<ValidationRule>) annotation.getKey().getDeclaredConstructor(annotation.getValue());
constructor.setAccessible(true);
r.add(constructor.newInstance(a));
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException ignored) {}
if (r.size() > 0)
addMapRules(f, rules, new String[]{name}, r);
}
});
}
return rules;
}
Expand Down
29 changes: 20 additions & 9 deletions src/main/java/org/javawebstack/validator/rule/AlphaDashRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,32 @@
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;

/**
* Rule: alpha_dash
*/
public class AlphaDashRule implements ValidationRule {
@Override
public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AlphaDashRule {
class Validator implements ValidationRule {
public Validator(AlphaDashRule rule) {}
public Validator() {}

@Override
public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;

String pattern = "[A-Za-z0-9-_]*";
if (!value.string().matches(pattern))
return "Value must only contain alpha-numeric characters as well as dashes and underscores.";
String pattern = "[A-Za-z0-9-_]*";
if (!value.string().matches(pattern))
return "Value must only contain alpha-numeric characters as well as dashes and underscores.";

return null;
return null;
}
}
}
29 changes: 20 additions & 9 deletions src/main/java/org/javawebstack/validator/rule/AlphaNumRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,32 @@
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;

/**
* Rule: alpha_num
*/
public class AlphaNumRule implements ValidationRule {
@Override
public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AlphaNumRule {
class Validator implements ValidationRule {
public Validator(AlphaNumRule rule) {}
public Validator() {}

@Override
public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;

String pattern = "[A-Za-z0-9]*";
if (!value.string().matches(pattern))
return "Value must only contain alpha-numeric characters.";
String pattern = "[A-Za-z0-9]*";
if (!value.string().matches(pattern))
return "Value must only contain alpha-numeric characters.";

return null;
return null;
}
}
}
29 changes: 20 additions & 9 deletions src/main/java/org/javawebstack/validator/rule/AlphaRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,32 @@
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;

/**
* Rule: alpha
*/
public class AlphaRule implements ValidationRule {
@Override
public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AlphaRule {
class Validator implements ValidationRule {
public Validator(AlphaRule rule) {}
public Validator() {}

@Override
public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;

String pattern = "[A-Za-z]*";
if (!value.string().matches(pattern))
return "Value must only contain alphabetic characters.";
String pattern = "[A-Za-z]*";
if (!value.string().matches(pattern))
return "Value must only contain alphabetic characters.";

return null;
return null;
}
}
}
75 changes: 44 additions & 31 deletions src/main/java/org/javawebstack/validator/rule/ArrayRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,55 @@
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;

/**
* Rule: array, list
*/
public class ArrayRule implements ValidationRule {

private final int min;
private final int max;

public ArrayRule(int min, int max) {
this.min = min;
this.max = max;
}

public ArrayRule(String[] params) {
int min = 0;
int max = Integer.MAX_VALUE;
if (params.length > 0)
min = Integer.parseInt(params[0]);
if (params.length > 1)
max = Integer.parseInt(params[1]);
this.min = min;
this.max = max;
}

public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ArrayRule {
int min();
int max();

class Validator implements ValidationRule {
private final int min;
private final int max;

public Validator(ArrayRule rule) {
this(rule.min(), rule.max());
}

public Validator(int min, int max) {
this.min = min;
this.max = max;
}

public Validator(String[] params) {
int min = 0;
int max = Integer.MAX_VALUE;
if (params.length > 0)
min = Integer.parseInt(params[0]);
if (params.length > 1)
max = Integer.parseInt(params[1]);
this.min = min;
this.max = max;
}

public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;
if (!value.isArray())
return "Not an array";
if (value.array().size() < min)
return String.format("Shorter than minimum array length (%d < %d)", value.array().size(), min);
if (value.array().size() > max)
return String.format("Longer than maximum array length (%d > %d)", value.array().size(), max);
return null;
if (!value.isArray())
return "Not an array";
if (value.array().size() < min)
return String.format("Shorter than minimum array length (%d < %d)", value.array().size(), min);
if (value.array().size() > max)
return String.format("Longer than maximum array length (%d > %d)", value.array().size(), max);
return null;
}
}

}
30 changes: 21 additions & 9 deletions src/main/java/org/javawebstack/validator/rule/BooleanRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,31 @@
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;

/**
* Rule: boolean, bool
*/
public class BooleanRule implements ValidationRule {
public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;
if (value.isBoolean())
return null;
if (value.isString() && (value.string().equals("true") || value.string().equals("false")))
return null;
return "Not a boolean value";
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BooleanRule {
class Validator implements ValidationRule {
public Validator(BooleanRule rule) {}

public Validator() {}

public String validate(ValidationContext context, Field field, AbstractElement value) {
if (value == null || value.isNull())
return null;
if (value.isBoolean())
return null;
if (value.isString() && (value.string().equals("true") || value.string().equals("false")))
return null;
return "Not a boolean value";
}
}
}
Loading