throw new CodecExceptionLineNumber(
"Could not access the type or the constructor of " +
type.getName(), valInfo);
}
try {
((JSONCodable) value).fromJSONObject(new JSONObject(oValue.toString()));
} catch (Exception ex) {
throw new CodecExceptionLineNumber(ex, valInfo);
}
} else if (field.isArray()) {
value = decodeArrayInternal(type, value, valInfo, warnings);
} else if (field.isNative()) {
if (value.getClass() != type) {
if (value.getClass() == Integer.class || value.getClass() == int.class) {
// upconvert integer values to long if the field requires long
if (type == Long.class || type == long.class || type == AtomicLong.class) {
value = new Long(((Integer) value).longValue());
}
// upconvert integer values to double if the field requires double
if (type == Double.class || type == double.class) {
value = new Double(((Integer) value));
}
// downconvert integer to short if the field requires short
if (type == Short.class || type == short.class) {
value = new Short(((Integer) value).shortValue());
}
}
// downconvert double to float if the field requires a float
if ((value.getClass() == double.class || value.getClass() == Double.class) &&
(type == float.class || type == Float.class)) {
value = new Float(((Double) value));
}
// upconvert long values to double if the field requires double
if ((value.getClass() == long.class || value.getClass() == Long.class) &&
(type == double.class || type == Double.class)) {
value = new Double(((Integer) value));
}
// upconvert float values to double if the field requires double
if ((value.getClass() == float.class || value.getClass() == Float.class) &&
(type == double.class || type == Double.class)) {
value = new Double(((Float) value));
}
if (value.getClass() == String.class) {
try {
// convert String values to int if the field requires int
if (type == Integer.class || type == int.class ||
type == AtomicInteger.class) {
value = Integer.parseInt((String) value);
}
// convert String values to long if the field requires long
if (type == long.class || type == Long.class ||
type == AtomicLong.class) {
value = Long.parseLong((String) value);
}
// convert String values to double if the field requires double
if (type == double.class || type == Double.class) {
value = Double.parseDouble((String) value);
}
// convert String values to boolean if the field requires boolean
if (type == boolean.class || type == Boolean.class ||
type == AtomicBoolean.class) {
value = Boolean.parseBoolean((String) value);
}
} catch (NumberFormatException ex) {
if (type == Integer.class || type == int.class ||
type == AtomicInteger.class) {
throw new CodecExceptionLineNumber(
"cannot convert the string to an integer", valInfo);
} else if (type == long.class || type == Long.class ||
type == AtomicLong.class) {
throw new CodecExceptionLineNumber(
"cannot convert the string to a long", valInfo);
} else if (type == double.class || type == Double.class) {
throw new CodecExceptionLineNumber(
"cannot convert the string to a double", valInfo);
} else {
throw new IllegalStateException(
"unhandled case in the NumberFormatException");
}
}
}
if (type == AtomicInteger.class) {
value = new AtomicInteger((Integer) value);
} else if (type == AtomicLong.class) {
value = new AtomicLong((Long) value);
} else if (type == AtomicBoolean.class) {
value = new AtomicBoolean((Boolean) value);
}
}
// this space left intentionally blank
} else if (field.isMap()) {
Map map;
try {
map = (Map) type.newInstance();
} catch (Exception ex) {
throw new CodecExceptionLineNumber(ex, keyInfo);
}
JSONObject jmap = (JSONObject) value;
Class vc = (Class) field.getGenericTypes()[1];
boolean va = field.isMapValueArray();
for (Iterator<String> iter = jmap.keys(); iter.hasNext(); ) {
String key = iter.next();
if (field.isInterned()) {
key = key.intern();
}
map.put(key, va ?
decodeArrayInternal(vc, jmap.get(key), jmap.getKeyLineNumber(key),
warnings)
:
decodeObjectInternal(vc, jmap.get(key), jmap.getKeyLineNumber(key),
warnings));
}
value = map;
} else if (field.isCollection()) {
Collection col;