com.impetus.kundera.validation.rules.AttributeConstraintRule.java Source code

Java tutorial

Introduction

Here is the source code for com.impetus.kundera.validation.rules.AttributeConstraintRule.java

Source

/*******************************************************************************
 * * Copyright 2013 Impetus Infotech.
 *  *
 *  * Licensed under the Apache License, Version 2.0 (the "License");
 *  * you may not use this file except in compliance with the License.
 *  * You may obtain a copy of the License at
 *  *
 *  *      http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an "AS IS" BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 ******************************************************************************/
package com.impetus.kundera.validation.rules;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

import javax.validation.ValidationException;
import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.apache.commons.lang.math.NumberUtils;

import com.impetus.kundera.property.PropertyAccessorHelper;

/**
 * @author Chhavi Gangwal
 * 
 */
public class AttributeConstraintRule extends AbstractFieldRule implements FieldRule {

    /** The rules for entity type validation map. */
    static enum AttributeConstraintType {

        ASSERT_FALSE(AssertFalse.class.getSimpleName()), ASSERT_TRUE(AssertTrue.class.getSimpleName()), DECIMAL_MAX(
                DecimalMax.class.getSimpleName()), DECIMAL_MIN(DecimalMin.class.getSimpleName()), DIGITS(
                        Digits.class.getSimpleName()), FUTURE(Future.class.getSimpleName()), MAX(
                                Max.class.getSimpleName()), MIN(Min.class.getSimpleName()), NOT_NULL(
                                        NotNull.class.getSimpleName()), NULL(Null.class.getSimpleName()), PAST(
                                                Past.class.getSimpleName()), PATTERN(
                                                        Pattern.class.getSimpleName()), SIZE(
                                                                Size.class.getSimpleName());

        private String clazz;

        private static final Map<String, AttributeConstraintType> lookup = new HashMap<String, AttributeConstraintType>();

        static {
            for (AttributeConstraintType s : EnumSet.allOf(AttributeConstraintType.class)) {
                lookup.put(s.getClazz(), s);
            }
        }

        /**
         * @param clazz
         */
        private AttributeConstraintType(String clazz) {
            this.clazz = clazz;
        }

        /**
         * @return
         */
        public String getClazz() {
            return clazz;
        }

        /**
         * @param clazz
         * @return
         */
        public static AttributeConstraintType get(String clazz) {
            return lookup.get(clazz);
        }
    }

    private AttributeConstraintType getERuleType(String annotationType) {

        if (AttributeConstraintType.get(annotationType) != null) {
            return AttributeConstraintType.get(annotationType);
        } else {
            return null;
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.impetus.kundera.validation.rules.AbstractFieldRule#validate(java.
     * lang.reflect.Field, java.lang.Object)
     */
    @Override
    public boolean validate(Field f, Object validationObject) {
        boolean checkvalidation = true;

        for (Annotation annotation : f.getDeclaredAnnotations()) {

            AttributeConstraintType eruleType = getERuleType(annotation.annotationType().getSimpleName());

            if (eruleType != null) {
                Object fieldValue = PropertyAccessorHelper.getObject(validationObject, f);

                switch (eruleType) {

                case ASSERT_FALSE:
                    checkvalidation = validateFalse(fieldValue, annotation);
                    break;
                case ASSERT_TRUE:
                    checkvalidation = validateTrue(fieldValue, annotation);
                    break;
                case DECIMAL_MAX:
                    checkvalidation = validateMaxDecimal(fieldValue, annotation);
                    break;
                case DECIMAL_MIN:
                    checkvalidation = validateMinDecimal(fieldValue, annotation);
                    break;
                case DIGITS:
                    checkvalidation = validateDigits(fieldValue, annotation);
                    break;
                case FUTURE:
                    checkvalidation = validateFuture(fieldValue, annotation);
                    break;
                case MAX:
                    checkvalidation = validateMaxValue(fieldValue, annotation);
                    break;

                case MIN:
                    checkvalidation = validateMinValue(fieldValue, annotation);
                    break;
                case NOT_NULL:
                    checkvalidation = validateNotNull(fieldValue, annotation);
                    break;
                case NULL:
                    checkvalidation = validateNull(fieldValue, annotation);
                    break;
                case PAST:
                    checkvalidation = validatePast(fieldValue, annotation);
                    break;
                case PATTERN:
                    checkvalidation = validatePattern(fieldValue, annotation);
                    break;
                case SIZE:
                    checkvalidation = validateSize(fieldValue, annotation);
                    break;

                }
            }
        }

        return checkvalidation;
    }

    /**
     * Checks whether the given attribute's value is within specified limit 
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateSize(Object validationObject, Annotation annotate) {

        if (checkNullObject(validationObject)) {
            return true;
        }

        int objectSize = 0;
        int minSize = ((Size) annotate).min();
        int maxSize = ((Size) annotate).max();
        if (validationObject != null) {
            if (String.class.isAssignableFrom(validationObject.getClass())) {
                objectSize = ((String) validationObject).length();

            } else if (Collection.class.isAssignableFrom(validationObject.getClass())) {

                objectSize = ((Collection) validationObject).size();
            } else if (Map.class.isAssignableFrom(validationObject.getClass())) {
                objectSize = ((Map) validationObject).size();
            } else if (ArrayList.class.isAssignableFrom(validationObject.getClass())) {

                objectSize = ((ArrayList) validationObject).size();

            } else {
                throwValidationException(((Size) annotate).message());

            }
        }
        return objectSize <= maxSize && objectSize >= minSize;

    }

    /**
     * Checks whether the given string is a valid pattern or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validatePattern(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(((Pattern) annotate).regexp(),
                ((Pattern) annotate).flags().length);
        Matcher matcherPattern = pattern.matcher((String) validationObject);
        if (!matcherPattern.matches()) {
            throwValidationException(((Pattern) annotate).message());

        }

        return true;
    }

    /**
     * Checks whether the object is null or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validatePast(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        int res = 0;

        if (validationObject.getClass().isAssignableFrom(java.util.Date.class)) {
            Date today = new Date();
            Date pastDate = (Date) validationObject;

            res = pastDate.compareTo(today);
        } else if (validationObject.getClass().isAssignableFrom(java.util.Calendar.class)) {

            Calendar cal = Calendar.getInstance();
            Calendar pastDate = (Calendar) validationObject;
            res = pastDate.compareTo(cal);

        }
        // else
        // {
        // ruleExceptionHandler(((Past) annotate).message());
        // }
        if (res >= 0) {
            throwValidationException(((Past) annotate).message());
        }

        return true;
    }

    /**
     * Checks whether a given date is that in future or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateFuture(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        int res = 0;

        if (validationObject.getClass().isAssignableFrom(java.util.Date.class)) {
            Date today = new Date();
            Date futureDate = (Date) validationObject;

            res = futureDate.compareTo(today);
        } else if (validationObject.getClass().isAssignableFrom(java.util.Calendar.class)) {

            Calendar cal = Calendar.getInstance();
            Calendar futureDate = (Calendar) validationObject;
            res = futureDate.compareTo(cal);

        }
        // else
        // {
        // //ruleExceptionHandler(((Future) annotate).message());
        // throw new RuleValidationException(((Future)
        // annotate).message());
        // }
        if (res <= 0) {
            throwValidationException(((Future) annotate).message());
        }

        return true;
    }

    /**
     * Checks whether a given date is that in past or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateNull(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        if (!validationObject.equals(null) || validationObject != null) {
            throwValidationException(((Null) annotate).message());
        }

        return true;
    }

    /**
     * 
     * Checks whether a given date is not null
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateNotNull(Object validationObject, Annotation annotate) {

        if (validationObject == null || validationObject.equals(null)) {
            throwValidationException(((NotNull) annotate).message());
        }
        return true;
    }

    /**
     * Checks whether a given value is greater than given min value or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateMinValue(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        Long minValue = ((Min) annotate).value();
        if (checkvalidDigitTypes(validationObject.getClass())) {
            if ((NumberUtils.toLong(toString(validationObject))) < minValue) {

                throwValidationException(((Min) annotate).message());
            }
        }

        return true;
    }

    /**
     * Checks whether a given value is lesser than given max value or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateMaxValue(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        Long maxValue = ((Max) annotate).value();
        if (checkvalidDigitTypes(validationObject.getClass())) {
            if ((NumberUtils.toLong(toString(validationObject))) > maxValue) {

                throwValidationException(((Max) annotate).message());

            }
        }

        return true;
    }

    /**
     * Checks whether a given value is is a number or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateDigits(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        if (checkvalidDigitTypes(validationObject.getClass())) {
            if (!NumberUtils.isDigits(toString(validationObject))) {

                throwValidationException(((Digits) annotate).message());
            }
        }

        return true;
    }

    /**
     * Checks whether a given value is a valid minimum decimal digit when compared to given value 
     * or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateMinDecimal(Object validationObject, Annotation annotate) {

        if (validationObject != null) {
            try {
                if (checkvalidDeciDigitTypes(validationObject.getClass())) {
                    BigDecimal minValue = NumberUtils.createBigDecimal(((DecimalMin) annotate).value());
                    BigDecimal actualValue = NumberUtils.createBigDecimal(toString(validationObject));
                    int res = actualValue.compareTo(minValue);
                    if (res < 0) {
                        throwValidationException(((DecimalMin) annotate).message());
                    }

                }
            } catch (NumberFormatException nfe) {
                throw new RuleValidationException(nfe.getMessage());
            }

        }

        return true;
    }

    /**
     * Checks whether a given value is a valid maximum decimal digit when compared to given value 
     * or not
     * 
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateMaxDecimal(Object validationObject, Annotation annotate) {
        if (validationObject != null) {
            try {
                if (checkvalidDeciDigitTypes(validationObject.getClass())) {
                    BigDecimal maxValue = NumberUtils.createBigDecimal(((DecimalMax) annotate).value());
                    BigDecimal actualValue = NumberUtils.createBigDecimal(toString(validationObject));
                    int res = actualValue.compareTo(maxValue);
                    if (res > 0) {
                        throwValidationException(((DecimalMax) annotate).message());
                    }

                }
            } catch (NumberFormatException nfe) {
                throw new RuleValidationException(nfe.getMessage());
            }

        }
        return true;
    }

    /**
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateTrue(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        if (checkvalidBooleanTypes(validationObject.getClass()) && !(Boolean) validationObject) {
            throwValidationException(((AssertTrue) annotate).message());
        }

        return true;
    }

    /**
     * @param validationObject
     * @param annotate
     * @return
     */
    private boolean validateFalse(Object validationObject, Annotation annotate) {
        if (checkNullObject(validationObject)) {
            return true;
        }

        if (checkvalidBooleanTypes(validationObject.getClass()) && (Boolean) validationObject) {
            throwValidationException(((AssertFalse) annotate).message());

        }

        return true;
    }

    /**
     * @param javaType
     * @return
     */
    private boolean checkvalidDigitTypes(Class<?> javaType) {
        return javaType.isAssignableFrom(BigDecimal.class) || javaType.isAssignableFrom(byte.class)
                || javaType.isAssignableFrom(Byte.class) || javaType.isAssignableFrom(short.class)
                || javaType.isAssignableFrom(Short.class) || javaType.isAssignableFrom(int.class)
                || javaType.isAssignableFrom(Integer.class) || javaType.isAssignableFrom(long.class)
                || javaType.isAssignableFrom(Long.class);

    }

    /**
     * @param javaType
     * @return
     */
    private boolean checkvalidBooleanTypes(Class<?> javaType) {
        return javaType.isAssignableFrom(Boolean.class) || javaType.isAssignableFrom(boolean.class);

    }

    /**
     * @param javaType
     * @return
     */
    private boolean checkvalidDeciDigitTypes(Class<?> javaType) {
        return javaType.isAssignableFrom(BigDecimal.class) || javaType.isAssignableFrom(String.class)
                || javaType.isAssignableFrom(byte.class) || javaType.isAssignableFrom(Byte.class)
                || javaType.isAssignableFrom(short.class) || javaType.isAssignableFrom(Short.class)
                || javaType.isAssignableFrom(int.class) || javaType.isAssignableFrom(Integer.class)
                || javaType.isAssignableFrom(long.class) || javaType.isAssignableFrom(Long.class);

    }

    /**
     * @param validationObject
     * @return
     */
    private String toString(Object validationObject) {
        String stringObject = null;
        if (validationObject.getClass().isAssignableFrom(int.class)
                || validationObject.getClass().isAssignableFrom(Integer.class)) {
            stringObject = Integer.toString((Integer) validationObject);

        } else if (validationObject.getClass().isAssignableFrom(byte.class)
                || validationObject.getClass().isAssignableFrom(Byte.class)) {
            stringObject = Byte.toString((Byte) validationObject);
        } else if (validationObject.getClass().isAssignableFrom(short.class)
                || validationObject.getClass().isAssignableFrom(Short.class)) {
            stringObject = Short.toString((Short) validationObject);
        }

        else if (validationObject.getClass().isAssignableFrom(BigDecimal.class)) {
            stringObject = validationObject.toString();
        } else if (validationObject.getClass().isAssignableFrom(Long.class)
                || validationObject.getClass().isAssignableFrom(long.class)) {
            stringObject = Long.toString((Long) validationObject);
        }

        else if (validationObject.getClass().isAssignableFrom(String.class)
                || validationObject.getClass().isAssignableFrom(String.class)) {
            stringObject = (String) validationObject;
        }

        return stringObject;
    }

    /**
     * @param validationObject
     * @return
     */
    private boolean checkNullObject(Object validationObject) {

        return validationObject == null;
    }

    /**
     * @param message
     */
    private void throwValidationException(String message) {
        if (!message.isEmpty() || message != null) {
            throw new ValidationException(message);
        } else {
            throw new ValidationException("Constraint validation exception");
        }

    }

}