Package com.alibaba.toolkit.util.typeconvert

Source Code of com.alibaba.toolkit.util.typeconvert.ConvertManager$ChainImpl

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* 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 com.alibaba.toolkit.util.typeconvert;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import com.alibaba.toolkit.util.enumeration.Enum;
import com.alibaba.toolkit.util.enumeration.EnumConverter;
import com.alibaba.toolkit.util.enumeration.FlagSet;
import com.alibaba.toolkit.util.enumeration.FlagSetConverter;
import com.alibaba.toolkit.util.typeconvert.converters.BigDecimalConverter;
import com.alibaba.toolkit.util.typeconvert.converters.BigIntegerConverter;
import com.alibaba.toolkit.util.typeconvert.converters.BooleanConverter;
import com.alibaba.toolkit.util.typeconvert.converters.ByteConverter;
import com.alibaba.toolkit.util.typeconvert.converters.CharacterConverter;
import com.alibaba.toolkit.util.typeconvert.converters.DoubleConverter;
import com.alibaba.toolkit.util.typeconvert.converters.FloatConverter;
import com.alibaba.toolkit.util.typeconvert.converters.IntegerConverter;
import com.alibaba.toolkit.util.typeconvert.converters.LongConverter;
import com.alibaba.toolkit.util.typeconvert.converters.ObjectArrayConverter;
import com.alibaba.toolkit.util.typeconvert.converters.ObjectConverter;
import com.alibaba.toolkit.util.typeconvert.converters.ShortConverter;
import com.alibaba.toolkit.util.typeconvert.converters.SqlDateConverter;
import com.alibaba.toolkit.util.typeconvert.converters.SqlTimeConverter;
import com.alibaba.toolkit.util.typeconvert.converters.SqlTimestampConverter;
import com.alibaba.toolkit.util.typeconvert.converters.StringConverter;

/**
* <code>Converter</code>的管理器.
*
* @author Michael Zhou
* @version $Id: ConvertManager.java,v 1.1 2003/07/03 07:26:36 baobao Exp $
*/
public class ConvertManager {
    private static final Object NO_DEFAULT_VALUE = new Object();
    private              Map    registry         = Collections.synchronizedMap(new HashMap());
    private              Map    aliases          = Collections.synchronizedMap(new HashMap());

    /** 创建一个转换器. */
    public ConvertManager() {
        register(BigDecimal.class, new BigDecimalConverter());
        register(BigInteger.class, new BigIntegerConverter());
        register(Boolean.class, new BooleanConverter());
        register(Byte.class, new ByteConverter());
        register(Character.class, new CharacterConverter());
        register(Double.class, new DoubleConverter());
        register(Float.class, new FloatConverter());
        register(Integer.class, new IntegerConverter());
        register(Long.class, new LongConverter());
        register(Short.class, new ShortConverter());
        register(Date.class, new SqlDateConverter());
        register(Time.class, new SqlTimeConverter());
        register(Timestamp.class, new SqlTimestampConverter());
        register(String.class, new StringConverter());
        register(Object[].class, new ObjectArrayConverter());
        register(Object.class, new ObjectConverter());
        register(Enum.class, new EnumConverter());
        register(FlagSet.class, new FlagSetConverter());

        // 登记别名.
        registerAlias("string", String.class);
        registerAlias("enum", Enum.class);
    }

    /**
     * 登录一个转换器.
     *
     * @param type      转换器的目标类型
     * @param converter 转换器对象
     */
    public void register(Class type, Converter converter) {
        synchronized (registry) {
            if (Boolean.class.equals(type) || Boolean.TYPE.equals(type)) {
                internalRegister(Boolean.class, converter);
                internalRegister(Boolean.TYPE, converter);
            } else if (Byte.class.equals(type) || Byte.TYPE.equals(type)) {
                internalRegister(Byte.class, converter);
                internalRegister(Byte.TYPE, converter);
            } else if (Character.class.equals(type) || Character.TYPE.equals(type)) {
                internalRegister(Character.class, converter);
                internalRegister(Character.TYPE, converter);
            } else if (Double.class.equals(type) || Double.TYPE.equals(type)) {
                internalRegister(Double.class, converter);
                internalRegister(Double.TYPE, converter);
            } else if (Float.class.equals(type) || Float.TYPE.equals(type)) {
                internalRegister(Float.class, converter);
                internalRegister(Float.TYPE, converter);
            } else if (Integer.class.equals(type) || Integer.TYPE.equals(type)) {
                internalRegister(Integer.class, converter);
                internalRegister(Integer.TYPE, converter);
            } else if (Long.class.equals(type) || Long.TYPE.equals(type)) {
                internalRegister(Long.class, converter);
                internalRegister(Long.TYPE, converter);
            } else if (Short.class.equals(type) || Short.TYPE.equals(type)) {
                internalRegister(Short.class, converter);
                internalRegister(Short.TYPE, converter);
            } else {
                internalRegister(type, converter);
            }
        }
    }

    /**
     * 登记别名.
     *
     * @param alias 别名
     * @param type  目标类型
     */
    public void registerAlias(String alias, Class type) {
        synchronized (aliases) {
            if (alias != null && type != null && !aliases.containsKey(alias)) {
                aliases.put(alias, type);
            }
        }
    }

    /**
     * 内部过程: 登记一个转换器. 不检查primitive类型, 不同步.
     *
     * @param type      转换器的目标类型
     * @param converter 转换器对象
     */
    private void internalRegister(Class type, Converter converter) {
        LinkedList converters = (LinkedList) registry.get(type);

        if (converters == null) {
            converters = new LinkedList();
            registry.put(type, converters);
        }

        if (!converters.contains(converter)) {
            converters.addFirst(converter);
            registerAlias(type.getName(), type);
        }
    }

    /**
     * 将指定值转换成<code>boolean</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public boolean asBoolean(Object value) {
        return ((Boolean) asType(Boolean.class, value)).booleanValue();
    }

    /**
     * 将指定值转换成<code>boolean</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public boolean asBoolean(Object value, boolean defaultValue) {
        return ((Boolean) asType(Boolean.class, value, new Boolean(defaultValue))).booleanValue();
    }

    /**
     * 将指定值转换成<code>byte</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public byte asByte(Object value) {
        return ((Byte) asType(Byte.class, value)).byteValue();
    }

    /**
     * 将指定值转换成<code>byte</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public byte asByte(Object value, byte defaultValue) {
        return ((Byte) asType(Byte.class, value, new Byte(defaultValue))).byteValue();
    }

    /**
     * 将指定值转换成<code>char</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public char asChar(Object value) {
        return ((Character) asType(Character.class, value)).charValue();
    }

    /**
     * 将指定值转换成<code>char</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public char asChar(Object value, char defaultValue) {
        return ((Character) asType(Character.class, value, new Character(defaultValue))).charValue();
    }

    /**
     * 将指定值转换成<code>double</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public double asDouble(Object value) {
        return ((Double) asType(Double.class, value)).doubleValue();
    }

    /**
     * 将指定值转换成<code>double</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public double asDouble(Object value, double defaultValue) {
        return ((Double) asType(Double.class, value, new Double(defaultValue))).doubleValue();
    }

    /**
     * 将指定值转换成<code>float</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public float asFloat(Object value) {
        return ((Float) asType(Float.class, value)).floatValue();
    }

    /**
     * 将指定值转换成<code>float</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public float asFloat(Object value, float defaultValue) {
        return ((Float) asType(Float.class, value, new Float(defaultValue))).floatValue();
    }

    /**
     * 将指定值转换成<code>int</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public int asInt(Object value) {
        return ((Integer) asType(Integer.class, value)).intValue();
    }

    /**
     * 将指定值转换成<code>int</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public int asInt(Object value, int defaultValue) {
        return ((Integer) asType(Integer.class, value, new Integer(defaultValue))).intValue();
    }

    /**
     * 将指定值转换成<code>long</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public long asLong(Object value) {
        return ((Long) asType(Long.class, value)).longValue();
    }

    /**
     * 将指定值转换成<code>long</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public long asLong(Object value, long defaultValue) {
        return ((Long) asType(Long.class, value, new Long(defaultValue))).longValue();
    }

    /**
     * 将指定值转换成<code>short</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public short asShort(Object value) {
        return ((Short) asType(Short.class, value)).shortValue();
    }

    /**
     * 将指定值转换成<code>short</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public short asShort(Object value, short defaultValue) {
        return ((Short) asType(Short.class, value, new Short(defaultValue))).shortValue();
    }

    /**
     * 将指定值转换成<code>String</code>类型.
     *
     * @param value 要转换的值
     * @return 转换后的值
     */
    public String asString(Object value) {
        return (String) asType(String.class, value);
    }

    /**
     * 将指定值转换成<code>String</code>类型.
     *
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public String asString(Object value, String defaultValue) {
        return (String) asType(String.class, value, defaultValue);
    }

    /**
     * 将指定值转换成指定类型.
     *
     * @param targetType 要转换的目标类型
     * @param value      要转换的值
     * @return 转换后的值
     */
    public Object asType(Object targetType, Object value) {
        return asType(targetType, value, NO_DEFAULT_VALUE);
    }

    /**
     * 将指定值转换成指定类型.
     *
     * @param targetType   要转换的目标类型
     * @param value        要转换的值
     * @param defaultValue 默认值
     * @return 转换后的值
     */
    public Object asType(Object targetType, Object value, Object defaultValue) {
        try {
            return new ChainImpl(this, getTargetType(targetType)).convert(value);
        } catch (ConvertFailedException e) {
            if (e.isDefaultValueSet()) {
                return defaultValue == NO_DEFAULT_VALUE ? e.getDefaultValue() : defaultValue;
            }

            throw e;
        }
    }

    /**
     * 将指定值转换成指定类型. 即使转换失败, 也不会返回默认值, 而抛出一个异常.
     *
     * @param targetType 要转换的目标类型
     * @param value      要转换的值
     * @return 转换后的值
     */
    public Object asTypeWithoutDefaultValue(Object targetType, Object value) {
        return new ChainImpl(this, getTargetType(targetType)).convert(value);
    }

    /**
     * 取得target type类对象.
     *
     * @param targetType target type类或别名
     * @return target type类对象
     */
    private Class getTargetType(Object targetType) {
        if (targetType instanceof Class) {
            return (Class) targetType;
        }

        if (targetType instanceof String) {
            Class type = (Class) aliases.get(targetType);

            if (type != null) {
                return type;
            }
        }

        throw new IllegalArgumentException("Invalid targetType " + targetType);
    }

    /**
     * 转换器链. 依次尝试: Convertible.getConverter(targetType), targetType对应的转换器,
     * targetType的基类(不包括Object类)对应的转换器, targetType的接口对应的转换器, Object类所对应的转换器.
     */
    private class ChainImpl implements ConvertChain {
        private static final int STATE_START       = 0;
        private static final int STATE_TARGET_TYPE = STATE_START + 1;
        private static final int STATE_BASE_TYPE   = STATE_TARGET_TYPE + 1;
        private static final int STATE_INTERFACE   = STATE_BASE_TYPE + 1;
        private static final int STATE_OBJECT      = STATE_INTERFACE + 1;
        private static final int STATE_END         = STATE_OBJECT + 1;
        private final ConvertManager manager;
        private final TypeInfo       targetTypeInfo;
        private int state = STATE_START;
        private Convertible previousConvertibleValue;
        private Iterator    converterIterator;
        private Iterator    superclassIterator;
        private Iterator    interfaceIterator;

        /**
         * 创建转换链.
         *
         * @param manager    创建此链的<code>ConvertManager</code>
         * @param targetType 转换的目标类型
         */
        ChainImpl(ConvertManager manager, Class targetType) {
            this.manager = manager;
            this.targetTypeInfo = TypeInfo.getTypeInfo(targetType);
        }

        /**
         * 取得创建此链的<code>ConvertManager</code>.
         *
         * @return 创建此链的<code>ConvertManager</code>
         */
        public ConvertManager getConvertManager() {
            return manager;
        }

        /**
         * 取得转换的目标类型.
         *
         * @return 目标类型
         */
        public Class getTargetType() {
            return targetTypeInfo.getType();
        }

        /**
         * 将控制交给链中的下一个转换器, 转换指定的值到指定的类型.
         *
         * @param value 要转换的值
         * @return 转换后的值
         */
        public Object convert(Object value) {
            Class targetType = targetTypeInfo.getType();

            // 优先处理实现Convertible接口的value值,
            // 并防止对同一个convertible value反复调用其converter
            if (value instanceof Convertible && !value.equals(previousConvertibleValue)) {
                Converter converter = ((Convertible) value).getConverter(targetType);

                if (converter != null) {
                    previousConvertibleValue = (Convertible) value;
                    return converter.convert(value, this);
                }
            }

            // 开始状态
            if (state == STATE_START) {
                state++; // 进入STATE_TARGET_TYPE状态
                converterIterator = getConverterIterator(targetType);
            }

            // 处理targetType对应的转换器
            if (state == STATE_TARGET_TYPE) {
                if (!hasNext(converterIterator)) {
                    state++; // 进入STATE_BASE_TYPE状态
                    superclassIterator = targetTypeInfo.getSuperclasses().iterator();
                    converterIterator = getSuperclassConverterIterator();
                }
            }

            // 处理targetType的基类对应的转换器
            if (state == STATE_BASE_TYPE) {
                if (!hasNext(converterIterator)) {
                    converterIterator = getSuperclassConverterIterator();

                    if (!hasNext(converterIterator)) {
                        state++; // 进入STATE_INTERFACE状态
                        interfaceIterator = targetTypeInfo.getInterfaces().iterator();
                        converterIterator = getInterfaceConverterIterator();
                    }
                }
            }

            // 处理targetType的接口对应的转换器
            if (state == STATE_INTERFACE) {
                if (!hasNext(converterIterator)) {
                    converterIterator = getInterfaceConverterIterator();

                    if (!hasNext(converterIterator)) {
                        state++; // 进入STATE_OBJECT状态

                        if (!Object.class.equals(targetTypeInfo.getType())) {
                            converterIterator = getConverterIterator(Object.class);
                        }
                    }
                }
            }

            // 处理Object类对应的转换器
            if (state == STATE_OBJECT) {
                if (!hasNext(converterIterator)) {
                    state++; // 进入STATE_END状态
                }
            }

            // 开始转换
            if (state != STATE_END) {
                Converter converter = (Converter) converterIterator.next();

                return converter.convert(value, this);
            }

            // 如果找不到converter, 则失败
            throw new ConvertFailedException();
        }

        /**
         * 取得指定类型的所有转换器.
         *
         * @param type 要查找转换器的类型
         * @return 转换器的<code>Iterator</code>, 如果不存在, 则返回<code>null</code>
         */
        private Iterator getConverterIterator(Class type) {
            LinkedList converters = (LinkedList) registry.get(type);

            if (converters != null && converters.size() > 0) {
                return converters.iterator();
            }

            return null;
        }

        /**
         * 取得targetType基类(不包括Object类)的转换器.
         *
         * @return 基类的转换器的<code>Iterator</code>, 如果不存在, 则返回<code>null</code>
         */
        private Iterator getSuperclassConverterIterator() {
            Iterator iterator = null;

            while (superclassIterator.hasNext()) {
                Class superclass = (Class) superclassIterator.next();

                if (!superclass.equals(Object.class)) {
                    iterator = getConverterIterator(superclass);

                    if (hasNext(iterator)) {
                        return iterator;
                    }
                }
            }

            return null;
        }

        /**
         * 取得targetType接口的转换器.
         *
         * @return 接口的转换器的<code>Iterator</code>, 如果不存在, 则返回<code>null</code>
         */
        private Iterator getInterfaceConverterIterator() {
            Iterator iterator = null;

            while (interfaceIterator.hasNext()) {
                iterator = getConverterIterator((Class) interfaceIterator.next());

                if (hasNext(iterator)) {
                    return iterator;
                }
            }

            return null;
        }

        /**
         * 检查iterator是否存在下一个元素.
         *
         * @param iterator 要检查的iterator
         * @return 如果iterator为<code>null</code>, 或iterator已经走到底, 则返回
         *         <code>false</code>
         */
        private boolean hasNext(Iterator iterator) {
            return iterator != null && iterator.hasNext();
        }
    }
}
TOP

Related Classes of com.alibaba.toolkit.util.typeconvert.ConvertManager$ChainImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.