All Downloads are FREE. Search and download functionalities are using the official Maven repository.

play.data.validation.Validation Maven / Gradle / Ivy

There is a newer version: 2.6.3
Show newest version
package play.data.validation;

import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
import play.exceptions.UnexpectedException;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Pattern;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;

public class Validation {

    public static final ThreadLocal current = new ThreadLocal<>();
    List errors = new ArrayList<>();
    boolean keep;

    protected Validation() {
    }

    /**
     * @return The current validation helper
     */
    public static Validation current() {
        return current.get();
    }

    /**
     * @return The list of all errors
     */
    @SuppressWarnings({"unused"})
    public static List errors() {
        Validation validation = current.get();
        if (validation == null)
            return emptyList();
        
        return new ArrayList(validation.errors) {

            public Error forKey(String key) {
                return Validation.error(key);
            }

            public List allForKey(String key) {
                return Validation.errors(key);
            }
        };
    }

    /**
     * @return All errors keyed by field name
     */
    public Map> errorsMap() {
        Map> result = new LinkedHashMap<>();
        for (Error error : errors()) {
            result.put(error.getKey(), errors(error.getKey()));
        }
        return result;
    }

    /**
     * Add an error
     * @param field Field name
     * @param message Message key
     * @param variables Message variables
     */
    public static void addError(String field, String message, String... variables) {
        insertError(Validation.current().errors.size(), field, message, variables);
    }
    
    /**
     * Insert an error at the specified position in this list.
     * @param index index at which the specified element is to be inserted
     * @param field Field name
     * @param message Message key
     * @param variables Message variables
     */
    public static void insertError(int index, String field, String message, String... variables) {
        Error error = error(field);
        if (error == null || !error.getMessageKey().equals(message)) {
            Validation.current().errors.add(index, new Error(field, message, asList(variables)));
        }
    }
    
    /**
     * Remove all errors on a field with the given message
     * @param field Field name
     * @param message Message key
     */
     public static void removeErrors(String field, String message) {
         Validation validation = current.get();
         if (validation != null) {
             Iterator it = validation.errors.iterator();
             while (it.hasNext()) {
                 Error error = it.next();
                 if (error.getKey() != null && error.getKey().equals(field) && error.getMessageKey().equals(message)) {
                     it.remove();
                 }
             }
         }
     }
     
    /**
    * Remove all errors on a field
    * @param field Field name
    */
    public static void removeErrors(String field) {
        Validation validation = current.get();
        if (validation != null) {
            validation.errors.removeIf(error -> error.getKey() != null && error.getKey().equals(field));
        }
    }
    
    

    /**
     * @return True if the current request has errors
     */
    public static boolean hasErrors() {
        Validation validation = current.get();
        return validation != null && !validation.errors.isEmpty();
    }

    /**
     * @param field The field name
     * @return true if field has some errors
     */
    public static boolean hasErrors(String field){
        return error(field) != null;
    }
    
    /**
     * @param field The field name
     * @return First error related to this field
     */
    public static Error error(String field) {
        Validation validation = current.get();
        if (validation == null)
            return null;
          
        for (Error error : validation.errors) {
            if (error.getKey() != null && error.getKey().equals(field)) {
                return error;
            }
        }
        return null;
    }

    /**
     * @param field The field name
     * @return All errors related to this field
     */
    public static List errors(String field) {
        Validation validation = current.get();
        if (validation == null)
            return emptyList();
      
        List errors = new ArrayList<>();
        for (Error error : validation.errors) {
            if (error.getKey() != null && error.getKey().equals(field)) {
                errors.add(error);
            }
        }
        return errors;
    }

    /**
     * Keep errors for the next request (will be stored in a cookie)
     */
    public static void keep() {
        current.get().keep = true;
    }

    /**
     * @param field The field name
     * @return True is there are errors related to this field
     */
    public static boolean hasError(String field) {
        return error(field) != null;
    }

    public static void clear() {
        current.get().errors.clear();
        if(ValidationPlugin.keys.get() != null){
            ValidationPlugin.keys.get().clear();
        }
    }

    // ~~~~ Integration helper
    public static Map> getValidators(Class clazz, String name) {
        Map> result = new HashMap<>();
        searchValidator(clazz, name, result);
        return result;
    }

    public static List getValidators(Class clazz, String property, String name) {
        try {
            List validators = new ArrayList<>();
            while (!clazz.equals(Object.class)) {
                try {
                    Field field = clazz.getDeclaredField(property);
                    for (Annotation annotation : field.getDeclaredAnnotations()) {
                        if (annotation.annotationType().getName().startsWith("play.data.validation")) {
                            Validator validator = new Validator(annotation);
                            validators.add(validator);
                            if (annotation.annotationType().equals(InFuture.class)) {
                                validator.params.put("reference", ((InFuture) annotation).value());
                            }
                            if (annotation.annotationType().equals(InPast.class)) {
                                validator.params.put("reference", ((InPast) annotation).value());
                            }
                        }
                    }
                    break;
                } catch (NoSuchFieldException e) {
                    clazz = clazz.getSuperclass();
                }
            }
            return validators;
        } catch (Exception e) {
            return new ArrayList<>();
        }
    }

    static void searchValidator(Class clazz, String name, Map> result) {
        for (Field field : clazz.getDeclaredFields()) {

            List validators = new ArrayList<>();
            String key = name + "." + field.getName();
            boolean containsAtValid = false;
            for (Annotation annotation : field.getDeclaredAnnotations()) {
                if (annotation.annotationType().getName().startsWith("play.data.validation")) {
                    Validator validator = new Validator(annotation);
                    validators.add(validator);
                    if (annotation.annotationType().equals(InFuture.class)) {
                        validator.params.put("reference", ((InFuture) annotation).value());
                    }
                    if (annotation.annotationType().equals(InPast.class)) {
                        validator.params.put("reference", ((InPast) annotation).value());
                    }

                }
                if (annotation.annotationType().equals(Valid.class)) {
                    containsAtValid = true;
                }
            }
            if (!validators.isEmpty()) {
                result.put(key, validators);
            }
            if (containsAtValid) {
                searchValidator(field.getType(), key, result);
            }
        }
    }

    public static class Validator {

        public Annotation annotation;
        public Map params = new HashMap<>();

        public Validator(Annotation annotation) {
            this.annotation = annotation;
        }
    }

    public static class ValidationResult {
        public boolean ok;
        public Error error;

        public ValidationResult message(String message) {
            if (error != null) {
                error = new Error(message, error.getKey(), error.getVariables());
            }
            return this;
        }

        public ValidationResult key(String key) {
            if (error != null) {
                error = new Error(error.getMessageKey(), key, error.getVariables());
            }
            return this;
        }
    }

    public static ValidationResult required(String key, Object o) {
        RequiredCheck check = new RequiredCheck();
        return applyCheck(check, key, o);
    }

    public static ValidationResult min(String key, Object o, double min) {
        MinCheck check = new MinCheck();
        check.min = min;
        return applyCheck(check, key, o);
    }

    public static ValidationResult max(String key, Object o, double max) {
        MaxCheck check = new MaxCheck();
        check.max = max;
        return applyCheck(check, key, o);
    }

    public static ValidationResult future(String key, Object o, Date reference) {
        InFutureCheck check = new InFutureCheck();
        check.reference = reference;
        return applyCheck(check, key, o);
    }

    public static ValidationResult future(String key, Object o) {
        InFutureCheck check = new InFutureCheck();
        check.reference = new Date();
        return applyCheck(check, key, o);
    }

    public static ValidationResult past(String key, Object o, Date reference) {
        InPastCheck check = new InPastCheck();
        check.reference = reference;
        return applyCheck(check, key, o);
    }

    public static ValidationResult past(String key, Object o) {
        InPastCheck check = new InPastCheck();
        check.reference = new Date();
        return applyCheck(check, key, o);
    }

    public static ValidationResult match(String key, Object o, String pattern) {
        MatchCheck check = new MatchCheck();
        check.pattern = Pattern.compile(pattern);
        return applyCheck(check, key, o);
    }

    public static ValidationResult email(String key, Object o) {
        EmailCheck check = new EmailCheck();
        return applyCheck(check, key, o);
    }

    public static ValidationResult url(String key, Object o) {
        URLCheck check = new URLCheck();
        return applyCheck(check, key, o);
    }

    public static ValidationResult phone(String key, Object o) {
        PhoneCheck check = new PhoneCheck();
        return applyCheck(check, key, o);
    }

    public static ValidationResult ipv4Address(String key, Object o) {
        IPv4AddressCheck check = new IPv4AddressCheck();
        return applyCheck(check, key, o);
    }

    public static ValidationResult ipv6Address(String key, Object o) {
        IPv6AddressCheck check = new IPv6AddressCheck();
        return applyCheck(check, key, o);
    }

    public static ValidationResult isTrue(String key, Object o) {
        IsTrueCheck check = new IsTrueCheck();
        return applyCheck(check, key, o);
    }

    public static ValidationResult range(String key, Object o, double min, double max) {
        RangeCheck check = new RangeCheck();
        check.min = min;
        check.max = max;
        return applyCheck(check, key, o);
    }

    public static ValidationResult minSize(String key, Object o, int minSize) {
        MinSizeCheck check = new MinSizeCheck();
        check.minSize = minSize;
        return applyCheck(check, key, o);
    }

    public static ValidationResult maxSize(String key, Object o, int maxSize) {
        MaxSizeCheck check = new MaxSizeCheck();
        check.maxSize = maxSize;
        return applyCheck(check, key, o);
    }

    public static ValidationResult valid(String key, Object o) {
        ValidCheck check = new ValidCheck();
        check.key = key;
        return applyCheck(check, key, o);
    }

    static ValidationResult applyCheck(AbstractAnnotationCheck check, String key, Object o) {
        try {
            ValidationResult result = new ValidationResult();
            if (!check.isSatisfied(o, o, null, null)) {
                Error error = new Error(key, check.getClass()
                        .getDeclaredField("mes").get(null)
                        + "",
                        check.getMessageVariables() == null ? emptyList() : check.getMessageVariables().values());
                Validation.current().errors.add(error);
                result.error = error;
                result.ok = false;
            } else {
                result.ok = true;
            }
            return result;
        } catch (Exception e) {
            throw new UnexpectedException(e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy