org.primeframework.mvc.parameter.convert.AbstractGlobalConverter.java Source code

Java tutorial

Introduction

Here is the source code for org.primeframework.mvc.parameter.convert.AbstractGlobalConverter.java

Source

/*
 * Copyright (c) 2001-2007, Inversoft Inc., All Rights Reserved
 *
 * 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 org.primeframework.mvc.parameter.convert;

import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.primeframework.mvc.util.TypeTools;

/**
 * This class is the base type converter for all the type converters that handle Object types. If you are writing a
 * converter for primitive types, use the {@link org.primeframework.mvc.parameter.convert.converters.AbstractPrimitiveConverter}
 * class.
 * <p/>
 * This class mostly delegates between the various method calls by passing in default values or performing casting.
 * Each
 * method describes how it functions.
 *
 * @author Brian Pontarelli
 */
public abstract class AbstractGlobalConverter implements GlobalConverter {
    /**
     * Handles the following cases:
     * <p/>
     * <ul>
     * <li>Null - returns null</li>
     * <li>Type is an array - calls stringToArray</li>
     * <li>Type is not an array and values length is 1 or 0 - calls stringToObject</li>
     * <li>Type is an array and values length is > 1 - calls stringsToArray</li>
     * <li>Type is not an array and values length is > 1 - calls stringsToObject</li>
     * </ul>
     *
     * @param convertTo         The type to convert to.
     * @param dynamicAttributes The dynamic attributes used to assist in conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @param values            The values to convert.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    public Object convertFromStrings(Type convertTo, Map<String, String> dynamicAttributes, String expression,
            String... values) throws ConversionException, ConverterStateException {
        // Handle a zero or one String
        Class<?> rawType = TypeTools.rawType(convertTo);
        if (values == null || values.length <= 1) {
            String value = (values != null && values.length == 1) ? values[0] : null;

            if (rawType.isArray()) {
                // Punt on multi-dimensional arrays
                if (rawType.getComponentType().isArray()) {
                    throw new ConverterStateException("Converter [" + getClass() + "] does not support"
                            + " conversion to multi-dimensional arrays of type [" + convertTo + "]");
                }

                return stringToArray(value, convertTo, dynamicAttributes, expression);
            }

            return stringToObject(value, convertTo, dynamicAttributes, expression);
        }

        // Handle multiple strings
        if (rawType.isArray()) {
            // Punt on multi-dimensional arrays
            if (rawType.getComponentType().isArray()) {
                throw new ConverterStateException("Converter [" + getClass() + "] does not support"
                        + " conversion to multi-dimensional arrays of type [" + convertTo + "]");
            }

            return stringsToArray(values, convertTo, dynamicAttributes, expression);
        }

        return stringsToObject(values, convertTo, dynamicAttributes, expression);
    }

    /**
     * Gets the first parameter type is the given type is a parametrized type. If it isn't, this returns null. If the
     * type
     * has multiple parameters, only the first is returned.
     *
     * @param type The type.
     * @return The first parameter type.
     */
    protected Class<?> parameterType(Type type) {
        if (type instanceof ParameterizedType) {
            return (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
        }

        return null;
    }

    /**
     * Converts the value to a String.
     *
     * @param convertFrom       The original Type of the value.
     * @param dynamicAttributes The dynamic attributes used to assist in conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @param value             The value to convert.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    public String convertToString(Type convertFrom, Map<String, String> dynamicAttributes, String expression,
            Object value) throws ConversionException {
        // Handle null
        if (value == null) {
            return null;
        }

        // Check simple conversion
        if (value instanceof String) {
            return (String) value;
        }

        // Handle arrays
        Class<?> rawType = TypeTools.rawType(convertFrom);
        if (rawType.isArray()) {
            return arrayToString(value, convertFrom, dynamicAttributes, expression);
        }

        return objectToString(value, convertFrom, dynamicAttributes, expression);
    }

    /**
     * This performs the conversion from a single String value to an array of the given type.
     *
     * @param value             The value to convert to an array.
     * @param convertTo         The array type to convert to.
     * @param dynamicAttributes The dynamic attributes used to assist in conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    protected Object stringToArray(String value, Type convertTo, Map<String, String> dynamicAttributes,
            String expression) throws ConversionException {
        if (value == null) {
            return null;
        }

        Object finalArray;
        Class<?> rawType = TypeTools.rawType(convertTo);
        if (StringUtils.isBlank(value)) {
            finalArray = Array.newInstance(rawType.getComponentType(), 0);
        } else {
            String[] parts = value.split(",");
            finalArray = Array.newInstance(rawType.getComponentType(), parts.length);
            for (int i = 0; i < parts.length; i++) {
                Object singleValue = stringToObject(parts[i], rawType.getComponentType(), dynamicAttributes,
                        expression);
                Array.set(finalArray, i, singleValue);
            }
        }

        return finalArray;
    }

    /**
     * This performs the conversion from an array of String values to an array of the given type.
     *
     * @param values            The values to convert to an array.
     * @param convertTo         The array type to convert to.
     * @param dynamicAttributes The dynamic attributes to assist in the conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    protected Object stringsToArray(String[] values, Type convertTo, Map<String, String> dynamicAttributes,
            String expression) throws ConversionException {
        if (values == null) {
            return null;
        }

        Object finalArray;
        Class<?> rawType = TypeTools.rawType(convertTo);
        if (values.length == 0) {
            finalArray = Array.newInstance(rawType.getComponentType(), 0);
        } else {
            finalArray = Array.newInstance(rawType.getComponentType(), values.length);
            for (int i = 0; i < values.length; i++) {
                Object singleValue = stringToObject(values[i], rawType.getComponentType(), dynamicAttributes,
                        expression);
                Array.set(finalArray, i, singleValue);
            }
        }

        return finalArray;
    }

    /**
     * This performs the conversion from an array to a single String value.
     *
     * @param value             The array value to convert to a String.
     * @param convertFrom       The array type to convert from.
     * @param dynamicAttributes The dynamic attributes to assist in the conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    protected String arrayToString(Object value, Type convertFrom, Map<String, String> dynamicAttributes,
            String expression) throws ConversionException {
        Class<?> rawType = TypeTools.rawType(convertFrom);
        if (!rawType.isArray()) {
            throw new ConversionException("The convertFrom parameter must be an array type");
        }

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

        if (!value.getClass().isArray()) {
            throw new ConversionException("The value is not an array");
        }

        if (value.getClass().getComponentType().isArray()) {
            throw new ConversionException(
                    "The value is a multi-dimensional array, which is not" + " supported by the AbstractConverter");
        }

        int length = Array.getLength(value);
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < length; i++) {
            Object o = Array.get(value, i);
            str.append(convertToString(value.getClass().getComponentType(), dynamicAttributes, expression, o));
            if (i + 1 < length) {
                str.append(",");
            }
        }

        return str.toString();
    }

    /**
     * Converts the single String value to an Object.
     *
     * @param value             The String value to convert.
     * @param convertTo         The type to convert to.
     * @param dynamicAttributes The dynamic attributes to assist in the conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    protected abstract Object stringToObject(String value, Type convertTo, Map<String, String> dynamicAttributes,
            String expression) throws ConversionException, ConverterStateException;

    /**
     * Converts a String array to a single Object (not an array of Objects). Support for this method is uncommon.
     *
     * @param values            The String values to convert.
     * @param convertTo         The type to convert to.
     * @param dynamicAttributes The dynamic attributes to assist in the conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    protected abstract Object stringsToObject(String[] values, Type convertTo,
            Map<String, String> dynamicAttributes, String expression)
            throws ConversionException, ConverterStateException;

    /**
     * Converts the Object value to a String.
     *
     * @param value             The Object value to convert.
     * @param convertFrom       The type to convert from.
     * @param dynamicAttributes The dynamic attributes to assist in the conversion.
     * @param expression        The full path to the expression that is causing the conversion.
     * @return The converted value.
     * @throws ConversionException     If the conversion failed.
     * @throws ConverterStateException if the converter didn't have all of the information it needed to perform the
     *                                 conversion.
     */
    protected abstract String objectToString(Object value, Type convertFrom, Map<String, String> dynamicAttributes,
            String expression) throws ConversionException, ConverterStateException;
}