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

jetbrick.typecast.TypeCastResolver Maven / Gradle / Ivy

/**
 * Copyright 2013-2016 Guoqiang Chen, Shanghai, China. All rights reserved.
 *
 *   Author: Guoqiang Chen
 *    Email: [email protected]
 *   WebURL: https://github.com/subchen
 *
 * 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 jetbrick.typecast;

import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import jetbrick.io.resource.Resource;
import jetbrick.typecast.support.ArrayConvertor;
import jetbrick.typecast.support.BigDecimalConvertor;
import jetbrick.typecast.support.BigIntegerConvertor;
import jetbrick.typecast.support.BooleanConvertor;
import jetbrick.typecast.support.ByteConvertor;
import jetbrick.typecast.support.CalendarConvertor;
import jetbrick.typecast.support.CharacterConvertor;
import jetbrick.typecast.support.CharsetConvertor;
import jetbrick.typecast.support.ClassConvertor;
import jetbrick.typecast.support.DateConvertor;
import jetbrick.typecast.support.DoubleConvertor;
import jetbrick.typecast.support.FileConvertor;
import jetbrick.typecast.support.FloatConvertor;
import jetbrick.typecast.support.InstantConvertor;
import jetbrick.typecast.support.IntegerConvertor;
import jetbrick.typecast.support.ListConvertor;
import jetbrick.typecast.support.LocalDateConvertor;
import jetbrick.typecast.support.LocalDateTimeConvertor;
import jetbrick.typecast.support.LocalTimeConvertor;
import jetbrick.typecast.support.LocaleConvertor;
import jetbrick.typecast.support.LongConvertor;
import jetbrick.typecast.support.PathConvertor;
import jetbrick.typecast.support.PrimitiveArrayConvertor;
import jetbrick.typecast.support.ResourceConvertor;
import jetbrick.typecast.support.ShortConvertor;
import jetbrick.typecast.support.SqlDateConvertor;
import jetbrick.typecast.support.SqlTimeConvertor;
import jetbrick.typecast.support.SqlTimestampConvertor;
import jetbrick.typecast.support.StringConvertor;
import jetbrick.typecast.support.TimeZoneConvertor;
import jetbrick.typecast.support.URIConvertor;
import jetbrick.typecast.support.URLConvertor;
import jetbrick.util.JdkUtils;

@SuppressWarnings("unchecked")
public final class TypeCastResolver {
    private final Map, Convertor> pool;
    private final Map, ListConvertor> listPool;
    private final Map, ArrayConvertor> objectArrayPool;
    private final Map, PrimitiveArrayConvertor> primitiveArrayPool;

    public TypeCastResolver() {
        this.pool = new IdentityHashMap, Convertor>(64);
        this.listPool = new IdentityHashMap, ListConvertor>(64);
        this.objectArrayPool = new IdentityHashMap, ArrayConvertor>(64);
        this.primitiveArrayPool = new IdentityHashMap, PrimitiveArrayConvertor>(16);

        // number
        register(Byte.class, ByteConvertor.INSTANCE);
        register(Byte.TYPE, ByteConvertor.INSTANCE);
        register(Short.class, ShortConvertor.INSTANCE);
        register(Short.TYPE, ShortConvertor.INSTANCE);
        register(Integer.class, IntegerConvertor.INSTANCE);
        register(Integer.TYPE, IntegerConvertor.INSTANCE);
        register(Long.class, LongConvertor.INSTANCE);
        register(Long.TYPE, LongConvertor.INSTANCE);
        register(Float.class, FloatConvertor.INSTANCE);
        register(Float.TYPE, FloatConvertor.INSTANCE);
        register(Double.class, DoubleConvertor.INSTANCE);
        register(Double.TYPE, DoubleConvertor.INSTANCE);
        register(Character.class, CharacterConvertor.INSTANCE);
        register(Character.TYPE, CharacterConvertor.INSTANCE);
        register(Boolean.class, BooleanConvertor.INSTANCE);
        register(Boolean.TYPE, BooleanConvertor.INSTANCE);
        register(BigInteger.class, BigIntegerConvertor.INSTANCE);
        register(BigDecimal.class, BigDecimalConvertor.INSTANCE);

        // commons
        register(String.class, StringConvertor.INSTANCE);
        register(Class.class, ClassConvertor.INSTANCE);
        register(Charset.class, CharsetConvertor.INSTANCE);

        // date time
        register(java.util.Date.class, DateConvertor.INSTANCE);
        register(java.sql.Date.class, SqlDateConvertor.INSTANCE);
        register(java.sql.Time.class, SqlTimeConvertor.INSTANCE);
        register(java.sql.Timestamp.class, SqlTimestampConvertor.INSTANCE);
        register(Calendar.class, CalendarConvertor.INSTANCE);
        register(GregorianCalendar.class, CalendarConvertor.INSTANCE);
        register(Locale.class, LocaleConvertor.INSTANCE);
        register(TimeZone.class, TimeZoneConvertor.INSTANCE);

        // file path
        register(File.class, FileConvertor.INSTANCE);
        register(URI.class, URIConvertor.INSTANCE);
        register(URL.class, URLConvertor.INSTANCE);
        register(Resource.class, ResourceConvertor.INSTANCE);

        // others
        if (JdkUtils.IS_AT_LEAST_JAVA_7) {
            registerWhenJdk7();
        }
        if (JdkUtils.IS_AT_LEAST_JAVA_8) {
            registerWhenJdk8();
        }
    }

    private void registerWhenJdk7() {
        register(Path.class, PathConvertor.INSTANCE);
    }

    private void registerWhenJdk8() {
        register(Instant.class, InstantConvertor.INSTANCE);
        register(LocalDateTime.class, LocalDateTimeConvertor.INSTANCE);
        register(LocalDate.class, LocalDateConvertor.INSTANCE);
        register(LocalTime.class, LocalTimeConvertor.INSTANCE);
    }

    // -------- register / lookup -----------------------------------------------------------

    @SuppressWarnings("rawtypes")
    public  void register(Class type, Convertor convertor) {
        pool.put(type, convertor);

        if (type.isPrimitive()) {
            primitiveArrayPool.put(type, new PrimitiveArrayConvertor(type));
        } else {
            objectArrayPool.put(type, new ArrayConvertor(type, convertor));
            listPool.put(type, new ListConvertor(type, convertor));
        }
    }

    public void unregister(Class type) {
        pool.remove(type);

        if (type.isPrimitive()) {
            primitiveArrayPool.remove(type);
        } else {
            objectArrayPool.remove(type);
            listPool.remove(type);
        }
    }

    public  Convertor lookup(Class type) {
        return (Convertor) pool.get(type);
    }

    // -------- convert string -----------------------------------------------------------

    public  T convert(String value, Class type) {
        // fast-path
        if (value == null) {
            return null;
        }
        if (type == String.class) {
            return (T) value;
        }
        // normal-path
        Convertor c = (Convertor) pool.get(type);
        if (c != null) {
            return c.convert(value);
        }
        if (type.isArray()) {
            return (T) convertToArray(value, type.getComponentType());
        }
        throw new IllegalStateException("Unsupported cast class: " + type.getName());
    }

    public  T convertToArray(String value, Class elementType) {
        if (elementType.isPrimitive()) {
            PrimitiveArrayConvertor c = primitiveArrayPool.get(elementType);
            if (c != null) {
                return (T) c.convert(value);
            }
        } else {
            ArrayConvertor c = objectArrayPool.get(elementType);
            if (c != null) {
                return (T) c.convert(value);
            }
        }
        throw new IllegalStateException("Cannot cast to array: " + elementType.getName() + "[]");
    }

    public  List convertToList(String value, Class elementType) {
        ListConvertor c = (ListConvertor) listPool.get(elementType);
        if (c != null) {
            return c.convert(value);
        }
        throw new IllegalStateException("Cannot cast to class: List<" + elementType.getName() + ">");
    }

    // ------ convert object -------------------------------------------------------------

    public  T convert(Object value, Class type) {
        // fast-path
        if (value == null) {
            return null;
        }
        if (type.isInstance(value)) {
            return (T) value;
        }
        // normal-path
        Convertor c = (Convertor) pool.get(type);
        if (c != null) {
            return c.convert(value);
        }
        if (type.isArray()) {
            return (T) convertToArray(value, type.getComponentType());
        }
        throw new IllegalStateException("Unsupported cast class: " + type.getName());
    }

    public  T convertToArray(Object value, Class elementType) {
        if (elementType.isPrimitive()) {
            PrimitiveArrayConvertor c = primitiveArrayPool.get(elementType);
            if (c != null) {
                return (T) c.convert(value);
            }
        } else {
            ArrayConvertor c = objectArrayPool.get(elementType);
            if (c != null) {
                return (T) c.convert(value);
            }
        }
        throw new IllegalStateException("Cannot cast to array: " + elementType.getName() + "[]");
    }

    public  List convertToList(Object value, Class elementType) {
        ListConvertor c = (ListConvertor) listPool.get(elementType);
        if (c != null) {
            return c.convert(value);
        }
        throw new IllegalStateException("Cannot cast to class: List<" + elementType.getName() + ">");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy