* {@link #getToType() to type}.
* @throws IllegalArgumentException
* if conversion was not possible
*/
public Object convert(Object fromObject) {
ParseResult result = StringToNumberParser.parse(fromObject,
numberFormat, toType.isPrimitive());
if (result.getPosition() != null) {
// this shouldn't happen in the pipeline as validation should catch
// it but anyone can call convert so we should return a properly
// formatted message in an exception
throw new IllegalArgumentException(StringToNumberParser
.createParseErrorMessage((String) fromObject, result
.getPosition()));
} else if (result.getNumber() == null) {
// if an error didn't occur and the number is null then it's a boxed
// type and null should be returned
return null;
}
/*
* Technically the checks for ranges aren't needed here because the
* validator should have validated this already but we shouldn't assume
* this has occurred.
*/
if (Integer.class.equals(boxedType)) {
if (StringToNumberParser.inIntegerRange(result.getNumber())) {
return new Integer(result.getNumber().intValue());
}
} else if (Double.class.equals(boxedType)) {
if (StringToNumberParser.inDoubleRange(result.getNumber())) {
return new Double(result.getNumber().doubleValue());
}
} else if (Long.class.equals(boxedType)) {
if (StringToNumberParser.inLongRange(result.getNumber())) {
return new Long(result.getNumber().longValue());
}
} else if (Float.class.equals(boxedType)) {
if (StringToNumberParser.inFloatRange(result.getNumber())) {
return new Float(result.getNumber().floatValue());
}
} else if (BigInteger.class.equals(boxedType)) {
Number n = result.getNumber();
if(n instanceof Long)
return BigInteger.valueOf(n.longValue());
else if(n instanceof BigInteger)
return n;
else if(n instanceof BigDecimal)
return ((BigDecimal) n).toBigInteger();
else
return new BigDecimal(n.doubleValue()).toBigInteger();
} else if (BigDecimal.class.equals(boxedType)) {
Number n = result.getNumber();
if(n instanceof Long)
return BigDecimal.valueOf(n.longValue());
else if(n instanceof BigInteger)
return new BigDecimal((BigInteger) n);
else if(n instanceof BigDecimal)
return n;
else if(icuBigDecimal != null && icuBigDecimal.isInstance(n)) {
try {
// Get ICU BigDecimal value and use to construct java.math.BigDecimal
int scale = ((Integer) icuBigDecimalScale.invoke(n, null)).intValue();
BigInteger unscaledValue = (BigInteger) icuBigDecimalUnscaledValue.invoke(n, null);
return new java.math.BigDecimal(unscaledValue, scale);
} catch(IllegalAccessException e) {
throw new IllegalArgumentException("Error (IllegalAccessException) converting BigDecimal using ICU"); //$NON-NLS-1$
} catch(InvocationTargetException e) {
throw new IllegalArgumentException("Error (InvocationTargetException) converting BigDecimal using ICU"); //$NON-NLS-1$
}
} else if(n instanceof Double) {
BigDecimal bd = new BigDecimal(n.doubleValue());
if(bd.scale() == 0) return bd;
throw new IllegalArgumentException("Non-integral Double value returned from NumberFormat " + //$NON-NLS-1$
"which cannot be accurately stored in a BigDecimal due to lost precision. " + //$NON-NLS-1$
"Consider using ICU4J or Java 5 which can properly format and parse these types."); //$NON-NLS-1$
}
} else if (Short.class.equals(boxedType)) {
if (StringToNumberParser.inShortRange(result.getNumber())) {
return new Short(result.getNumber().shortValue());
}
} else if (Byte.class.equals(boxedType)) {
if (StringToNumberParser.inByteRange(result.getNumber())) {
return new Byte(result.getNumber().byteValue());
}
}
if (min != null && max != null) {
throw new IllegalArgumentException(StringToNumberParser