Open Source Repository

Home /jodd/jodd-3.3.2 | Repository Home


jodd/typeconverter/TypeConverterManagerBean.java
// Copyright (c) 2003-2012, Jodd Team (jodd.org). All Rights Reserved.

package jodd.typeconverter;

import jodd.datetime.JDateTime;
import jodd.mutable.MutableByte;
import jodd.mutable.MutableDouble;
import jodd.mutable.MutableFloat;
import jodd.mutable.MutableInteger;
import jodd.mutable.MutableLong;
import jodd.mutable.MutableShort;
import jodd.servlet.upload.FileUpload;
import jodd.typeconverter.impl.BigDecimalConverter;
import jodd.typeconverter.impl.BigIntegerConverter;
import jodd.typeconverter.impl.BooleanArrayConverter;
import jodd.typeconverter.impl.BooleanConverter;
import jodd.typeconverter.impl.ByteArrayConverter;
import jodd.typeconverter.impl.ByteConverter;
import jodd.typeconverter.impl.CalendarConverter;
import jodd.typeconverter.impl.CharacterArrayConverter;
import jodd.typeconverter.impl.CharacterConverter;
import jodd.typeconverter.impl.ClassArrayConverter;
import jodd.typeconverter.impl.ClassConverter;
import jodd.typeconverter.impl.DateConverter;
import jodd.typeconverter.impl.DoubleArrayConverter;
import jodd.typeconverter.impl.DoubleConverter;
import jodd.typeconverter.impl.FileConverter;
import jodd.typeconverter.impl.FileUploadConverter;
import jodd.typeconverter.impl.FloatArrayConverter;
import jodd.typeconverter.impl.FloatConverter;
import jodd.typeconverter.impl.IntegerArrayConverter;
import jodd.typeconverter.impl.IntegerConverter;
import jodd.typeconverter.impl.JDateTimeConverter;
import jodd.typeconverter.impl.LocaleConverter;
import jodd.typeconverter.impl.LongArrayConverter;
import jodd.typeconverter.impl.LongConverter;
import jodd.typeconverter.impl.MutableByteConverter;
import jodd.typeconverter.impl.MutableDoubleConverter;
import jodd.typeconverter.impl.MutableFloatConverter;
import jodd.typeconverter.impl.MutableIntegerConverter;
import jodd.typeconverter.impl.MutableLongConverter;
import jodd.typeconverter.impl.MutableShortConverter;
import jodd.typeconverter.impl.ShortArrayConverter;
import jodd.typeconverter.impl.ShortConverter;
import jodd.typeconverter.impl.SqlDateConverter;
import jodd.typeconverter.impl.SqlTimeConverter;
import jodd.typeconverter.impl.SqlTimestampConverter;
import jodd.typeconverter.impl.StringArrayConverter;
import jodd.typeconverter.impl.StringConverter;
import jodd.typeconverter.impl.URIConverter;
import jodd.typeconverter.impl.URLConverter;
import jodd.util.ReflectUtil;

import java.io.File;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;

/**
 * Provides dynamic object conversion to a type.
 * Contains a map of registered converters. User may add new converters.
 * Instantiable version of {@link TypeConverterManager}.
 */
public class TypeConverterManagerBean {

  private final HashMap<Class, TypeConverter> converters = new HashMap<Class, TypeConverter>(64);

  // ---------------------------------------------------------------- converter

  protected ConvertBean convertBean = new ConvertBean();

  /**
   * Returns {@link ConvertBean}.
   */
  public ConvertBean getConvertBean() {
    return convertBean;
  }

  // ---------------------------------------------------------------- methods

  public TypeConverterManagerBean() {
    registerDefaults();
  }

  /**
   * Registers default set of converters.
   */
  @SuppressWarnings( {"UnnecessaryFullyQualifiedName"})
  public void registerDefaults() {
    register(String.class, new StringConverter());
    register(String[].class, new StringArrayConverter());

    IntegerConverter integerConverter = new IntegerConverter();
    register(Integer.class, integerConverter);
    register(int.class, integerConverter);
    register(MutableInteger.class, new MutableIntegerConverter(convertBean));

    ShortConverter shortConverter = new ShortConverter();
    register(Short.class, shortConverter);
    register(short.class, shortConverter);
    register(MutableShort.class, new MutableShortConverter(convertBean));

    LongConverter longConverter = new LongConverter();
    register(Long.class, longConverter);
    register(long.class, longConverter);
    register(MutableLong.class, new MutableLongConverter(convertBean));

    ByteConverter byteConverter = new ByteConverter();
    register(Byte.class, byteConverter);
    register(byte.class, byteConverter);
    register(MutableByte.class, new MutableByteConverter(convertBean));

    FloatConverter floatConverter = new FloatConverter();
    register(Float.class, floatConverter);
    register(float.class, floatConverter);
    register(MutableFloat.class, new MutableFloatConverter(convertBean));

    DoubleConverter doubleConverter = new DoubleConverter();
    register(Double.class, doubleConverter);
    register(double.class, doubleConverter);
    register(MutableDouble.class, new MutableDoubleConverter(convertBean));

    BooleanConverter booleanConverter = new BooleanConverter();
    register(Boolean.class, booleanConverter);
    register(boolean.class, booleanConverter);

    CharacterConverter characterConverter = new CharacterConverter();
    register(Character.class, characterConverter);
    register(char.class, characterConverter);

    register(byte[].class, new ByteArrayConverter(convertBean));
    register(short[].class, new ShortArrayConverter(convertBean));
    register(int[].class, new IntegerArrayConverter(convertBean));
    register(long[].class, new LongArrayConverter(convertBean));
    register(float[].class, new FloatArrayConverter(convertBean));
    register(double[].class, new DoubleArrayConverter(convertBean));
    register(boolean[].class, new BooleanArrayConverter(convertBean));
    register(char[].class, new CharacterArrayConverter(convertBean));

    register(BigDecimal.class, new BigDecimalConverter());
    register(BigInteger.class, new BigIntegerConverter());

    register(java.util.Date.class, new DateConverter());
    register(java.sql.Date.class, new SqlDateConverter());
    register(Time.class, new SqlTimeConverter());
    register(Timestamp.class, new SqlTimestampConverter());
    register(Calendar.class, new CalendarConverter());
    register(GregorianCalendar.class, new CalendarConverter());
    register(JDateTime.class, new JDateTimeConverter());

    register(FileUpload.class, new FileUploadConverter());
    register(File.class, new FileConverter());

    register(Class.class, new ClassConverter());
    register(Class[].class, new ClassArrayConverter(convertBean));

    register(URI.class, new URIConverter());
    register(URL.class, new URLConverter());

    register(Locale.class, new LocaleConverter());
  }

  /**
   * Registers a converter for specified type.
   * User must register converter for all super-classes as well.
   *
   @param type    class that converter is for
   @param typeConverter  converter for provided class
   */
  public void register(Class type, TypeConverter typeConverter) {
    convertBean.register(type, typeConverter);
    converters.put(type, typeConverter);
  }

  public void unregister(Class type) {
    convertBean.register(type, null);
    converters.remove(type);
  }

  // ---------------------------------------------------------------- lookup

  /**
   * Retrieves converter for provided type. Only registered types are matched,
   * therefore subclasses must be also registered.
   *
   @return founded converter or <code>null</code>
   */
  public TypeConverter lookup(Class type) {
    return converters.get(type);
  }

  // ---------------------------------------------------------------- convert
  
  /**
   * Converts an object to destination type.If destination type is one of common types,
   * consider using {@link jodd.typeconverter.Convert} instead for faster approach.
   */
  @SuppressWarnings({"unchecked"})
  public <T> T convertType(Object value, Class<T> destinationType) {
    TypeConverter converter = lookup(destinationType);

    if (converter != null) {
      try {
        return (Tconverter.convert(value);
      catch (TypeConversionException tcex) {
        throw new ClassCastException("Unable to convert to type: " + destinationType.getName() '\n' + tcex.toString());
      }
    }

    // no converter

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

    // check same instances
    if (ReflectUtil.isInstanceOf(value, destinationType== true) {
      return (Tvalue;
    }

    // handle arrays
    if (destinationType.isArray()) {
      Class componentType = destinationType.getComponentType();

      // value is not an array
      if (value.getClass().isArray() == false) {
        // create single array
        T[] result = (T[]) Array.newInstance(componentType, 1);
        result[0(TconvertType(value, componentType);
        return (Tresult;
      }

      // value is an array
      Object[] array = (Object[]) value;
      T[] result = (T[]) Array.newInstance(componentType, array.length);
      for (int i = 0; i < array.length; i++) {
        result[i(TconvertType(array[i], componentType);
      }
      return (Tresult;
    }

    // handle enums
    if (destinationType.isEnum()) {
      Object[] enums = destinationType.getEnumConstants();
      String valStr = value.toString();
      for (Object e : enums) {
        if (e.toString().equals(valStr)) {
          return (Te;
        }
      }
    }

    // fail
    throw new ClassCastException("Unable to cast to type: " + destinationType.getName());
  }

}