org.kuali.rice.krad.datadictionary.validation.ValidationUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.kuali.rice.krad.datadictionary.validation.ValidationUtils.java

Source

/**
 * Copyright 2005-2014 The Kuali Foundation
 *
 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
 *
 * 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 org.kuali.rice.krad.datadictionary.validation;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Collection;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.kuali.rice.core.api.data.DataType;
import org.kuali.rice.core.api.datetime.DateTimeService;
import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
import org.kuali.rice.krad.uif.UifConstants;

/**
 * ValidationUtils provides static utility methods for validation processing
 *
 * <p>Inherited from Kuali Student and adapted extensively</p>
 *
 * @author Kuali Rice Team (rice.collab@kuali.org)
 */
public class ValidationUtils {

    /**
     * constructs a path by appending the attribute name to the provided path
     *
     * @param attributePath - a string representation of specifically which attribute (at some depth) is being accessed
     * @param attributeName - the attribute name
     * @return the path
     */
    public static String buildPath(String attributePath, String attributeName) {
        if (StringUtils.isNotBlank(attributeName)) {
            if (StringUtils.isNotBlank(attributePath)) {
                return new StringBuilder(attributePath).append(".").append(attributeName).toString();
            }

            return attributeName;
        }
        return attributePath;
    }

    /**
     * Used to get the rightmost index value of an attribute path.
     *
     * @param attributePath
     * @return the right index of value of attribute path, -1 if path has no index
     */
    public static int getLastPathIndex(String attributePath) {
        int index = -1;

        int leftBracket = attributePath.lastIndexOf("[");
        int rightBracket = attributePath.lastIndexOf("]");

        if (leftBracket > 0 && rightBracket > leftBracket) {
            String indexString = attributePath.substring(leftBracket + 1, rightBracket);
            try {
                index = Integer.valueOf(indexString).intValue();
            } catch (NumberFormatException e) {
                // Will just return -1
            }
        }

        return index;
    }

    /**
     * compares the value provided by the user and the one specified by the {@code WhenConstraint}
     *
     * @param fieldValue the value found in the field specified by a {@code CaseConstraint}'s {@code propertyName}
     * @param whenValue the value specified by a {@code WhenConstraint}
     * @param dataType the data type of the field which caseConstraint's propertyName refers to
     * @param operator the relationship to check between the {@code fieldValue} and the {@code whenValue}
     * @param isCaseSensitive whether string comparison will be carried out in a case sensitive fashion
     * @param dateTimeService used to convert strings to dates
     * @return true if the value matches the constraint
     */
    public static boolean compareValues(Object fieldValue, Object whenValue, DataType dataType, String operator,
            boolean isCaseSensitive, DateTimeService dateTimeService) {

        boolean result = false;
        Integer compareResult = null;

        if (UifConstants.CaseConstraintOperators.HAS_VALUE.equalsIgnoreCase(operator)) {
            if (fieldValue == null) {
                return "false".equals(whenValue.toString().toLowerCase());
            }
            if (fieldValue instanceof String && ((String) fieldValue).isEmpty()) {
                return "false".equals(whenValue.toString().toLowerCase());
            }
            if (fieldValue instanceof Collection && ((Collection<?>) fieldValue).isEmpty()) {
                return "false".equals(whenValue.toString().toLowerCase());
            }
            return "true".equals(whenValue.toString().toLowerCase());
        }
        // Convert objects into appropriate data types
        if (null != dataType) {
            if (DataType.STRING.equals(dataType)) {
                String v1 = getString(fieldValue);
                String v2 = getString(whenValue);

                if (!isCaseSensitive) {
                    v1 = v1.toUpperCase();
                    v2 = v2.toUpperCase();
                }

                compareResult = v1.compareTo(v2);
            } else if (DataType.INTEGER.equals(dataType)) {
                Integer v1 = getInteger(fieldValue);
                Integer v2 = getInteger(whenValue);
                compareResult = v1.compareTo(v2);
            } else if (DataType.LONG.equals(dataType)) {
                Long v1 = getLong(fieldValue);
                Long v2 = getLong(whenValue);
                compareResult = v1.compareTo(v2);
            } else if (DataType.DOUBLE.equals(dataType)) {
                Double v1 = getDouble(fieldValue);
                Double v2 = getDouble(whenValue);
                compareResult = v1.compareTo(v2);
            } else if (DataType.FLOAT.equals(dataType)) {
                Float v1 = getFloat(fieldValue);
                Float v2 = getFloat(whenValue);
                compareResult = v1.compareTo(v2);
            } else if (DataType.BOOLEAN.equals(dataType)) {
                Boolean v1 = getBoolean(fieldValue);
                Boolean v2 = getBoolean(whenValue);
                compareResult = v1.compareTo(v2);
            } else if (DataType.DATE.equals(dataType)) {
                Date v1 = getDate(fieldValue, dateTimeService);
                Date v2 = getDate(whenValue, dateTimeService);
                compareResult = v1.compareTo(v2);
            }
        }

        if (null != compareResult) {
            if ((UifConstants.CaseConstraintOperators.EQUALS.equalsIgnoreCase(operator)
                    || UifConstants.CaseConstraintOperators.GREATER_THAN_EQUAL.equalsIgnoreCase(operator)
                    || UifConstants.CaseConstraintOperators.LESS_THAN_EQUAL.equalsIgnoreCase(operator))
                    && 0 == compareResult) {
                result = true;
            }

            if ((UifConstants.CaseConstraintOperators.NOT_EQUAL.equalsIgnoreCase(operator)
                    || UifConstants.CaseConstraintOperators.NOT_EQUALS.equalsIgnoreCase(operator)
                    || UifConstants.CaseConstraintOperators.GREATER_THAN.equalsIgnoreCase(operator))
                    && compareResult >= 1) {
                result = true;
            }

            if ((UifConstants.CaseConstraintOperators.NOT_EQUAL.equalsIgnoreCase(operator)
                    || UifConstants.CaseConstraintOperators.NOT_EQUALS.equalsIgnoreCase(operator)
                    || UifConstants.CaseConstraintOperators.LESS_THAN.equalsIgnoreCase(operator))
                    && compareResult <= -1) {
                result = true;
            }
        }

        return result;
    }

    /**
     * converts the provided object into an integer
     *
     * @param o - the object to convert
     * @return the integer value
     */
    public static Integer getInteger(Object o) {
        Integer result = null;
        if (o instanceof Integer) {
            return (Integer) o;
        }
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).intValue();
        }
        String s = o.toString();
        if (s != null && s.trim().length() > 0) {
            result = Integer.valueOf(s.trim());
        }
        return result;
    }

    /**
     * converts the provided object into a long
     *
     * @param o - the object to convert
     * @return the long value
     */
    public static Long getLong(Object o) {
        Long result = null;
        if (o instanceof Long) {
            return (Long) o;
        }
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).longValue();
        }
        String s = o.toString();
        if (s != null && s.trim().length() > 0) {
            result = Long.valueOf(s.trim());
        }
        return result;
    }

    /**
     * converts the provided object into an float
     *
     * @param o - the object to convert
     * @return the float value
     */
    public static Float getFloat(Object o) {
        Float result = null;
        if (o instanceof Float) {
            return (Float) o;
        }
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).floatValue();
        }
        String s = o.toString();
        if (s != null && s.trim().length() > 0) {
            result = Float.valueOf(s.trim());
        }
        return result;
    }

    /**
     * converts the provided object into a double
     *
     * @param o - the object to convert
     * @return the double value
     */
    public static Double getDouble(Object o) {
        Double result = null;
        if (o instanceof BigDecimal) {
            return ((BigDecimal) o).doubleValue();
        }
        if (o instanceof Double) {
            return (Double) o;
        }
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).doubleValue();
        }
        String s = o.toString();
        if (s != null && s.trim().length() > 0) {
            result = Double.valueOf(s.trim());
        }
        return result;
    }

    /**
     * determines whether the provided object is a date and tries to converts non-date values
     *
     * @param object - the object to convert/cast into a date
     * @param dateTimeService - used to convert strings to dates
     * @return a date object
     * @throws IllegalArgumentException
     */
    public static Date getDate(Object object, DateTimeService dateTimeService) throws IllegalArgumentException {
        Date result = null;
        if (object instanceof Date) {
            return (Date) object;
        }
        if (object == null) {
            return null;
        }
        String s = object.toString();
        if (s != null && s.trim().length() > 0) {
            try {
                result = dateTimeService.convertToDate(s.trim());
            } catch (ParseException e) {
                throw new IllegalArgumentException(e);
            }
        }
        return result;
    }

    /**
     * converts the provided object into a string
     *
     * @param o - the object to convert
     * @return the string value
     */
    public static String getString(Object o) {
        if (o instanceof String) {
            return (String) o;
        }
        if (o == null) {
            return null;
        }
        return o.toString();
    }

    /**
     * converts the provided object into a boolean
     *
     * @param o - the object to convert
     * @return the boolean value
     */
    public static Boolean getBoolean(Object o) {
        Boolean result = null;
        if (o instanceof Boolean) {
            return (Boolean) o;
        }
        if (o == null) {
            return null;
        }
        String s = o.toString();
        if (s != null && s.trim().length() > 0) {
            result = Boolean.parseBoolean(s.trim());
        }
        return result;
    }

    /**
     * checks whether the string contains non-whitespace characters
     *
     * @param string
     * @return true if the string contains at least one none-whitespace character, false otherwise
     */
    public static boolean hasText(String string) {

        if (string == null || string.length() < 1) {
            return false;
        }
        int stringLength = string.length();

        for (int i = 0; i < stringLength; i++) {
            char currentChar = string.charAt(i);
            if (' ' != currentChar || '\t' != currentChar || '\n' != currentChar) {
                return true;
            }
        }

        return false;
    }

    /**
     * checks whether the provided object is null or empty
     *
     * @param value - the object to check
     * @return true if the object is null or empty, false otherwise
     */
    public static boolean isNullOrEmpty(Object value) {
        return value == null || (value instanceof String && StringUtils.isBlank(((String) value).trim()));
    }

    /**
     * defines possible result values of a comparison operation
     */
    public static enum Result {
        VALID, INVALID, UNDEFINED
    }

    ;

    /**
     * attempts to convert the provided value to the given dataType
     *
     * @param value - the object to convert
     * @param dataType - the data type to convert into
     * @param dateTimeService - used to convert strings to dates
     * @return the converted value if null or successful, otherwise throws an exception
     * @throws AttributeValidationException
     */
    public static Object convertToDataType(Object value, DataType dataType, DateTimeService dateTimeService)
            throws AttributeValidationException {
        Object returnValue = value;

        if (null == value) {
            return null;
        }

        switch (dataType) {
        case BOOLEAN:
            if (!(value instanceof Boolean)) {
                returnValue = Boolean.valueOf(value.toString());

                // Since the Boolean.valueOf is exceptionally loose - it basically takes any string and makes it false
                if (!value.toString().equalsIgnoreCase("TRUE") && !value.toString().equalsIgnoreCase("FALSE")) {
                    throw new AttributeValidationException("Value " + value.toString() + " is not a boolean!");
                }
            }
            break;
        case INTEGER:
            if (!(value instanceof Number)) {
                returnValue = Integer.valueOf(value.toString());
            }
            break;
        case LONG:
            if (!(value instanceof Number)) {
                returnValue = Long.valueOf(value.toString());
            }
            break;
        case DOUBLE:
            if (!(value instanceof Number)) {
                returnValue = Double.valueOf(value.toString());
            }
            if (((Double) returnValue).isNaN()) {
                throw new AttributeValidationException("Infinite Double values are not valid!");
            }
            if (((Double) returnValue).isInfinite()) {
                throw new AttributeValidationException("Infinite Double values are not valid!");
            }
            break;
        case FLOAT:
            if (!(value instanceof Number)) {
                returnValue = Float.valueOf(value.toString());
            }
            if (((Float) returnValue).isNaN()) {
                throw new AttributeValidationException("NaN Float values are not valid!");
            }
            if (((Float) returnValue).isInfinite()) {
                throw new AttributeValidationException("Infinite Float values are not valid!");
            }
            break;
        case TRUNCATED_DATE:
        case DATE:
            if (!(value instanceof Date)) {
                try {
                    returnValue = dateTimeService.convertToDate(value.toString());
                } catch (ParseException pe) {
                    throw new AttributeValidationException("Value " + value.toString() + " is not a date!");
                }
            }
            break;
        case STRING:
        }

        return returnValue;
    }

    /**
     * checks whether the provided value is greater than the limit given
     *
     * @param value - the object to check
     * @param limit - the limit to use
     * @param <T>
     * @return one of the values in {@link  Result}
     */
    public static <T> Result isGreaterThan(T value, Comparable<T> limit) {
        return limit == null ? Result.UNDEFINED : (limit.compareTo(value) < 0 ? Result.VALID : Result.INVALID);
    }

    /**
     * checks whether the provided value is greater than or equal to the limit given
     *
     * @param value - the object to check
     * @param limit - the limit to use
     * @param <T>
     * @return one of the values in {@link  Result}
     */
    public static <T> Result isGreaterThanOrEqual(T value, Comparable<T> limit) {
        return limit == null ? Result.UNDEFINED : (limit.compareTo(value) <= 0 ? Result.VALID : Result.INVALID);
    }

    /**
     * checks whether the provided value is less than the limit given
     *
     * @param value - the object to check
     * @param limit - the limit to use
     * @param <T>
     * @return one of the values in {@link  Result}
     */
    public static <T> Result isLessThan(T value, Comparable<T> limit) {
        return limit == null ? Result.UNDEFINED : (limit.compareTo(value) > 0 ? Result.VALID : Result.INVALID);
    }

    /**
     * checks whether the provided value is greater than the limit given
     *
     * @param value - the object to check
     * @param limit - the limit to use
     * @param <T>
     * @return one of the values in {@link  Result}
     */
    public static <T> Result isLessThanOrEqual(T value, Comparable<T> limit) {
        return limit == null ? Result.UNDEFINED : (limit.compareTo(value) >= 0 ? Result.VALID : Result.INVALID);
    }

    /**
     * converts a path into an array of its path components
     *
     * @param fieldPath - a string representation of specifically which attribute (at some depth) is being accessed
     * @return the array of path components
     */
    public static String[] getPathTokens(String fieldPath) {
        return (fieldPath != null && fieldPath.contains(".") ? fieldPath.split("\\.") : new String[] { fieldPath });
    }

}