package net.enilink.composition.properties.komma; import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; import java.util.Map; public class ConversionUtil { /** * A mapping of known primitive wrappers. */ private static final Map<Class<?>, Class<?>> primitiveWrappers; static { primitiveWrappers = new HashMap<Class<?>, Class<?>>(); primitiveWrappers.put(boolean.class, Boolean.class); primitiveWrappers.put(char.class, Character.class); primitiveWrappers.put(byte.class, Byte.class); primitiveWrappers.put(short.class, Short.class); primitiveWrappers.put(int.class, Integer.class); primitiveWrappers.put(long.class, Long.class); primitiveWrappers.put(float.class, Float.class); primitiveWrappers.put(double.class, Double.class); } /** * Determines primitive wrapper class for a primitive type. * * @return Wrapper class, or "null" if class is no primitive type. */ public static Class<?> wrapperType(Class<?> type) { if (type.isPrimitive()) { return primitiveWrappers.get(type); } return type; } /** * Evaluates the given object as a String and trims it if the trim flag is * true. * * @param value * an object to interpret as a String * @param trim * if true this returned string value is trimmed of whitespace * using String.trim(). * * @return the String value implied by the given object as returned by the * toString() method, or "null" if the object is null. */ public static String stringValue(Object value, boolean trim) { String result; if (value == null) { result = ""; } else { result = value.toString(); if (trim) { result = result.trim(); } } return result; } /** * Evaluates the given object as a long integer. * * @param value * an object to interpret as a long integer * * @return the long integer value implied by the given object * * @throws NumberFormatException * if the given object can't be understood as a long integer */ public static long longValue(Object value) throws NumberFormatException { if (value == null) return 0; Class<?> c = value.getClass(); if (c.getSuperclass() == Number.class) { return ((Number) value).longValue(); } if (c == Character.class) { return ((Character) value).charValue(); } if (c == Boolean.class) { return ((Boolean) value).booleanValue() ? 1 : 0; } return Long.parseLong(stringValue(value, true)); } /** * Evaluates the given object as a double-precision floating-point number. * * @param value * an object to interpret as a double * * @return the double value implied by the given object * * @throws NumberFormatException * if the given object can't be understood as a double */ public static double doubleValue(Object value) throws NumberFormatException { if (value == null) return 0.0; Class<?> c = value.getClass(); if (c.getSuperclass() == Number.class) { return ((Number) value).doubleValue(); } if (c == Character.class) { return ((Character) value).charValue(); } if (c == Boolean.class) { return ((Boolean) value).booleanValue() ? 1 : 0; } String s = stringValue(value, true); return (s.length() == 0) ? 0.0 : Double.parseDouble(s); } /** * Evaluates the given object as a BigDecimal. * * @param value * an object to interpret as a BigDecimal * * @return the BigDecimal value implied by the given object * * @throws NumberFormatException * if the given object can't be understood as a BigDecimal */ public static BigDecimal bigDecValue(Object value) throws NumberFormatException { if (value == null) return new BigDecimal(0); Class<?> c = value.getClass(); if (c == BigDecimal.class) { return (BigDecimal) value; } if (c == BigInteger.class) { return new BigDecimal((BigInteger) value); } if (c.getSuperclass() == Number.class) { return new BigDecimal(((Number) value).doubleValue()); } if (c == Character.class) { return BigDecimal.valueOf(((Character) value).charValue()); } if (c == Boolean.class) { return BigDecimal.valueOf(((Boolean) value).booleanValue() ? 1 : 0); } return new BigDecimal(stringValue(value, true)); } /** * Evaluates the given object as a BigInteger. * * @param value * an object to interpret as a BigInteger * * @return the BigInteger value implied by the given object * * @throws NumberFormatException * if the given object can't be understood as a BigInteger */ public static BigInteger bigIntValue(Object value) throws NumberFormatException { if (value == null) return new BigInteger(new byte[] { 0 }); Class<?> c = value.getClass(); if (c == BigInteger.class) { return (BigInteger) value; } if (c == BigDecimal.class) { return ((BigDecimal) value).toBigInteger(); } if (c.getSuperclass() == Number.class) { return BigInteger.valueOf(((Number) value).longValue()); } if (c == Character.class) { return BigInteger.valueOf(((Character) value).charValue()); } if (c == Boolean.class) { return BigInteger.valueOf(((Boolean) value).booleanValue() ? 1 : 0); } return new BigInteger(stringValue(value, true)); } /* * FIXME: check for String-conversion! old - String set: true, String empty: * false new - String set and "true" (case insensitive): true, else: false */ public static Boolean booleanValue(Object value) { if (value == null) return Boolean.FALSE; if ((value instanceof Boolean) && Boolean.FALSE.equals(value) || (value instanceof Number) && ((Number) value).intValue() == 0 || (value instanceof String) && !Boolean.parseBoolean((String) value) || (value instanceof Character) && ((Character) value).charValue() == 0) { return Boolean.FALSE; } return Boolean.TRUE; } /** * Returns the value converted numerically to the given class type. * * @param toType * class type to be converted to * @param value * an object to be converted to the given type * @param defaultValue * value returned in the event that no conversion is possible to * the given type * * @return converted value of the type given, or defaultValue if the value * cannot be converted to the given type. */ public static Object convertValue(Class<?> toType, Object value, Object defaultValue) { Object result; if (value != null) { if (toType == Integer.class || toType == Integer.TYPE) { result = new Integer((int) longValue(value)); } else if (toType == Double.class || toType == Double.TYPE) { result = new Double(doubleValue(value)); } else if (toType == Boolean.class || toType == Boolean.TYPE) { result = booleanValue(value) ? Boolean.TRUE : Boolean.FALSE; } else if (toType == Byte.class || toType == Byte.TYPE) { result = new Byte((byte) longValue(value)); } else if (toType == Character.class || toType == Character.TYPE) { result = new Character((char) longValue(value)); } else if (toType == Short.class || toType == Short.TYPE) { result = new Short((short) longValue(value)); } else if (toType == Long.class || toType == Long.TYPE) { result = new Long(longValue(value)); } else if (toType == Float.class || toType == Float.TYPE) { result = new Float(doubleValue(value)); } else if (toType == BigInteger.class) { result = bigIntValue(value); } else if (toType == BigDecimal.class) { result = bigDecValue(value); } else if (toType == String.class) { result = stringValue(value, false); } else { result = value; } } else { result = defaultValue; } return result; } }