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

org.skife.config.DefaultCoercibles Maven / Gradle / Ivy

There is a newer version: 8.1.2
Show newest version
package org.skife.config;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

final class DefaultCoercibles
{

    private DefaultCoercibles()
    {
    }

    public static final Coercible CASE_INSENSITIVE_ENUM_COERCIBLE = new CaseInsensitiveEnumCoercible();

    static final Coercible BOOLEAN_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (Boolean.class.isAssignableFrom(clazz) || Boolean.TYPE.isAssignableFrom(clazz)) {
                return DefaultCoercibles.BOOLEAN_COERCER;
            }
            return null;
        }
    };

    static final Coercible BYTE_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (Byte.class.isAssignableFrom(clazz) || Byte.TYPE.isAssignableFrom(clazz)) {
                return DefaultCoercibles.BYTE_COERCER;
            }
            return null;
        }
    };

    static final Coercible SHORT_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (Short.class.isAssignableFrom(clazz) || Short.TYPE.isAssignableFrom(clazz)) {
                return DefaultCoercibles.SHORT_COERCER;
            }
            return null;
        }
    };

    static final Coercible INTEGER_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (Integer.class.isAssignableFrom(clazz) || Integer.TYPE.isAssignableFrom(clazz)) {
                return DefaultCoercibles.INTEGER_COERCER;
            }
            return null;
        }
    };

    static final Coercible LONG_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (Long.class.isAssignableFrom(clazz) || Long.TYPE.isAssignableFrom(clazz)) {
                return DefaultCoercibles.LONG_COERCER;
            }
            return null;
        }
    };

    static final Coercible FLOAT_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (Float.class.isAssignableFrom(clazz) || Float.TYPE.isAssignableFrom(clazz)) {
                return DefaultCoercibles.FLOAT_COERCER;
            }
            return null;
        }
    };

    static final Coercible DOUBLE_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (Double.class.isAssignableFrom(clazz) || Double.TYPE.isAssignableFrom(clazz)) {
                return DefaultCoercibles.DOUBLE_COERCER;
            }
            return null;
        }
    };

    static final Coercible STRING_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (String.class.equals(clazz)) {
                return DefaultCoercibles.STRING_COERCER;
            }
            return null;
        }
    };

    static final Coercible URI_COERCIBLE = new Coercible() {
        public Coercer accept(final Class clazz) {
            if (URI.class.equals(clazz)) {
                return DefaultCoercibles.URI_COERCER;
            }
            return null;
        }
    };

    /**
     * A Coercible that accepts any type with a static valueOf(String) method.
     */
    static final Coercible VALUE_OF_COERCIBLE = new Coercible() {

        private Map, Coercer> coercerMap = new HashMap, Coercer>();

        public Coercer accept(final Class type)
        {
            if (coercerMap.containsKey(type)) {
                // If a key exists, the value always gets returned. If a null value is in the map,
                // the type was seen before and deemed not worthy.
                return coercerMap.get(type);
            }

            Coercer coercer = null;
            try {
                // Method must be 'static valueOf(String)' and return the type in question.
                Method candidate = type.getMethod("valueOf", String.class);
                if (!Modifier.isStatic(candidate.getModifiers())) {
                    // not static.
                    candidate = null;
                }
                else if (!candidate.getReturnType().isAssignableFrom(type)) {
                    // does not return the right type.
                    candidate = null;
                }

                if (candidate != null) {
                    final Method valueOfMethod = candidate;

                    coercer = new Coercer() {
                        public Object coerce(final String value)
                        {
                            try {
                                return value == null ? null : valueOfMethod.invoke(null, value);
                            }
                            catch (Exception e) {
                                throw convertException(e);
                            }
                        }
                    };
                }
            }
            catch(NoSuchMethodException nsme) {
                // Don't do anything, the class does not have a method.
            }

            coercerMap.put(type, coercer);
            return coercer;
        }
    };

    /**
     * A Coercible that accepts any type with a c'tor that takes a single string parameter.
     */
    static final Coercible STRING_CTOR_COERCIBLE = new Coercible() {

        private Map, Coercer> coercerMap = new HashMap, Coercer>();

        public Coercer accept(final Class type)
        {
            if (coercerMap.containsKey(type)) {
                // If a key exists, the value always gets returned. If a null value is in the map,
                // the type was seen before and deemed not worthy.
                return coercerMap.get(type);
            }


            Coercer coercer = null;
            try {
                final Constructor ctor = type.getConstructor(String.class);

                coercer = new Coercer() {
                    public Object coerce(final String value)
                    {
                        try {
                            return value == null ? null : ctor.newInstance(value);
                        }
                        catch (Exception e) {
                            throw convertException(e);
                        }
                    }
                };
            }
            catch(NoSuchMethodException nsme) {
                // Don't do anything, the class does not have a matching c'tor
            }

            coercerMap.put(type, coercer);
            return coercer;
        }
    };

    /**
     * A Coercible that accepts any type with a c'tor that takes a single Object parameter.
     *
     * This one was lovingly prepared and added for Jodatime DateTime objects.
     */
    static final Coercible OBJECT_CTOR_COERCIBLE = new Coercible() {

        private Map, Coercer> coercerMap = new HashMap, Coercer>();

        public Coercer accept(final Class type)
        {
            if (coercerMap.containsKey(type)) {
                // If a key exists, the value always gets returned. If a null value is in the map,
                // the type was seen before and deemed not worthy.
                return coercerMap.get(type);
            }


            Coercer coercer = null;
            try {
                final Constructor ctor = type.getConstructor(Object.class);

                coercer = new Coercer() {
                    public Object coerce(final String value)
                    {
                        try {
                            return ctor.newInstance(value);
                        }
                        catch (Exception e) {
                            throw convertException(e);
                        }
                    }
                };
            }
            catch(NoSuchMethodException nsme) {
                // Don't do anything, the class does not have a matching c'tor
            }

            coercerMap.put(type, coercer);
            return coercer;
        }
    };

    static final Coercer BOOLEAN_COERCER = new Coercer() {
        public Boolean coerce(final String value) {
            return value != null ? Boolean.valueOf(value) : null;
        }
    };

    static final Coercer BYTE_COERCER = new Coercer() {
        public Byte coerce(final String value) {
            return value != null ? Byte.valueOf(value) : null;
        }
    };

    static final Coercer SHORT_COERCER = new Coercer() {
        public Short coerce(final String value) {
            return value != null ? Short.valueOf(value) : null;
        }
    };

    static final Coercer INTEGER_COERCER = new Coercer() {
        public Integer coerce(final String value) {
            return value != null ? Integer.valueOf(value) : null;
        }
    };

    static final Coercer LONG_COERCER = new Coercer() {
        public Long coerce(final String value) {
            return value != null ? Long.valueOf(value) : null;
        }
    };

    static final Coercer FLOAT_COERCER = new Coercer() {
        public Float coerce(final String value) {
            return value != null ? Float.valueOf(value) : null;
        }
    };

    static final Coercer DOUBLE_COERCER = new Coercer() {
        public Double coerce(final String value) {
            return value != null ? Double.valueOf(value) : null;
        }
    };

    static final Coercer STRING_COERCER = new Coercer() {
        public String coerce(final String value) {
            return value;
        }
    };

    static final Coercer URI_COERCER = new Coercer() {
        public URI coerce(final String value) {
            return value != null ? URI.create(value) : null;
        }
    };

    public static final RuntimeException convertException(final Throwable t)
    {
        if (t instanceof RuntimeException) {
            return (RuntimeException) t;
        }
        else if (t instanceof InvocationTargetException) {
            return convertException(((InvocationTargetException)t).getTargetException());
        }
        else {
            return new RuntimeException(t);
        }
    }
}