/*
* Before to verify if the given value is inside the bounds, we need to convert the value
* to the units used by the parameter descriptor. The first part of this block verifies
* the validity of the unit argument, so we execute it even if 'value' is null.
*/
UnitConverter converter = null;
Object convertedValue = value;
if (unit != null) {
final Unit<?> def = descriptor.getUnit();
if (def == null) {
final String name = getName(descriptor);
throw new InvalidParameterValueException(Errors.format(Errors.Keys.UnitlessParameter_1, name), name, unit);
}
if (!unit.equals(def)) {
final short expectedID = getUnitMessageID(def);
if (getUnitMessageID(unit) != expectedID) {
throw new IllegalArgumentException(Errors.format(expectedID, unit));
}
/*
* Verify the type of the user's value before to perform the unit conversion,
* because the conversion will create a new object not necessarily of the same type.
*/
if (value != null) {
if (!valueClass.isInstance(value)) {
final String name = getName(descriptor);
throw new InvalidParameterValueException(
Errors.format(Errors.Keys.IllegalParameterValueClass_3,
name, valueClass, value.getClass()), name, value);
}
/*
* From this point we will perform the actual unit conversion. The value may be either
* a Number instance, or an array of numbers (typically an array of type double[]). In
* the array case, we will store the converted values in a new array of the same type.
*/
try {
converter = unit.getConverterToAny(def);
} catch (ConversionException e) {
throw new IllegalArgumentException(Errors.format(Errors.Keys.IncompatibleUnits_2, unit, def), e);
}
Class<?> componentType = valueClass.getComponentType();
if (componentType == null) {
/*
* Usual case where the value is not an array. Convert the value directly.
* Note that the value can only be a number because the unit is associated
* to MeasurementRange, which accepts only numbers.
*/
Number n = converter.convert(((Number) value).doubleValue());
try {
convertedValue = Numbers.cast(n, (Class<? extends Number>) valueClass);
} catch (IllegalArgumentException e) {
throw new InvalidParameterValueException(e.getLocalizedMessage(), getName(descriptor), value);
}
} else {
/*
* The value is an array. Creates a new array and store the converted values
* using Array reflection.
*/
final int length = Array.getLength(value);
convertedValue = Array.newInstance(componentType, length);
componentType = Numbers.primitiveToWrapper(componentType);
for (int i=0; i<length; i++) {
Number n = (Number) Array.get(value, i);
n = converter.convert(n.doubleValue()); // Value in units that we can compare.
try {
n = Numbers.cast(n, (Class<? extends Number>) componentType);
} catch (IllegalArgumentException e) {
throw new InvalidParameterValueException(e.getLocalizedMessage(),
getName(descriptor) + '[' + i + ']', value);