in johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java [601:744]
private Object toObject(final Object baseInstance, final JsonValue jsonValue,
final Type type, final Adapter itemConverter, final JsonPointerTracker jsonPointer,
final Type rootType) {
if (jsonValue == null) {
return getNullValue(type);
}
JsonValue.ValueType valueType = jsonValue.getValueType();
if (JsonValue.ValueType.NULL == valueType) {
return null;
}
if (type == Boolean.class || type == boolean.class) {
if (JsonValue.ValueType.TRUE == valueType) {
return true;
}
if (JsonValue.ValueType.FALSE == valueType) {
return false;
}
final String snippet = config.getSnippet().of(jsonValue);
final String description = ExceptionMessages.description(valueType);
throw new MapperException("Unable to parse " + description + " to boolean: " + snippet);
}
if (config.isTreatByteArrayAsBase64() && jsonValue.getValueType() == JsonValue.ValueType.STRING && (type == byte[].class /*|| type == Byte[].class*/)) {
return Base64.getDecoder().decode(((JsonString) jsonValue).getString());
}
if (config.isTreatByteArrayAsBase64URL() && jsonValue.getValueType() == JsonValue.ValueType.STRING && (type == byte[].class /*|| type == Byte[].class*/)) {
return Base64.getUrlDecoder().decode(((JsonString) jsonValue).getString());
}
if (Object.class == type) { // handling specific types here to keep exception in standard handling
if (JsonValue.ValueType.TRUE == valueType) {
return true;
}
if (JsonValue.ValueType.FALSE == valueType) {
return false;
}
if (JsonNumber.class.isInstance(jsonValue)) {
return toNumberValue(JsonNumber.class.cast(jsonValue));
}
if (JsonString.class.isInstance(jsonValue)) {
return JsonString.class.cast(jsonValue).getString();
}
}
if (type == Character.class || type == char.class) {
return convertTo(Class.class.cast(type), (JsonString.class.cast(jsonValue).getString()));
}
if (JsonObject.class.isInstance(jsonValue)) {
if (JsonObject.class == type || JsonStructure.class == type || JsonValue.class == type) {
return jsonValue;
}
final boolean typedAdapter = !ConverterAdapter.class.isInstance(itemConverter) && TypeAwareAdapter.class.isInstance(itemConverter);
final Object object = buildObject(
baseInstance != null ? baseInstance.getClass() : (
typedAdapter ? TypeAwareAdapter.class.cast(itemConverter).getTo() : type),
JsonObject.class.cast(jsonValue), type instanceof Class,
jsonPointer, getSkippedConverters());
return typedAdapter ? itemConverter.to(object) : object;
} else if (JsonArray.class.isInstance(jsonValue)) {
if (JsonArray.class == type || JsonStructure.class == type || JsonValue.class == type) {
return jsonValue;
}
return buildArray(type, JsonArray.class.cast(jsonValue), itemConverter, null, jsonPointer, rootType);
} else if (JsonNumber.class.isInstance(jsonValue)) {
if (JsonNumber.class == type || JsonValue.class == type) {
return jsonValue;
}
final JsonNumber number = JsonNumber.class.cast(jsonValue);
if (type == Long.class || type == long.class) {
return number.longValueExact();
}
if (type == OptionalLong.class) {
return OptionalLong.of(number.longValueExact());
}
if (type == Float.class || type == float.class) {
return (float) number.doubleValue();
}
if (type == Double.class || type == double.class) {
return number.doubleValue();
}
if (type == OptionalDouble.class) {
return OptionalDouble.of(number.doubleValue());
}
if (type == BigInteger.class) {
return number.bigIntegerValue();
}
if (type == BigDecimal.class || Number.class == type) {
return number.bigDecimalValue();
}
if (type == Integer.class || type == int.class) {
return number.intValueExact();
}
if (type == OptionalInt.class) {
return OptionalInt.of(number.intValueExact());
}
if (type == Short.class || type == short.class) {
final int intValue = number.intValue();
short shortVal = (short) intValue;
if (intValue != shortVal) {
throw new java.lang.ArithmeticException("Overflow");
}
return shortVal;
}
if (type == Byte.class || type == byte.class) {
final int intValue = number.intValueExact();
Validator.validateByte(intValue);
return (byte) intValue;
}
} else if (JsonString.class.isInstance(jsonValue)) {
if (JsonString.class == type || JsonValue.class == type) {
return jsonValue;
}
final String string = JsonString.class.cast(jsonValue).getString();
if (itemConverter == null) {
// check whether we have a jsonPointer to a previously deserialised object
if (isDedup() && !String.class.equals(type)) {
Object o = jsonPointers == null ? null : jsonPointers.get(string);
if (o != null) {
return o;
}
}
return convertTo(type, string);
}
return itemConverter.to(string);
}
final String snippet = config.getSnippet().of(jsonValue);
final String description = ExceptionMessages.description(valueType);
throw new MapperException("Unable to parse " + description + " to " + type + ": " + snippet);
}