if (!jsonValue.isObject())
throw new JsonException("Unsupported type of jsonValue for parameter of method " + clazz.getName() + "#"
+ method.getName());
JsonValue childJsonValue = jsonValue.getElement(key);
if (childJsonValue == null)
continue;
// if one of known primitive type or array of primitive type
if (JsonUtils.isKnownType(methodParameterClazz))
{
method.invoke(object, new Object[]{createObjectKnownTypes(methodParameterClazz, childJsonValue)});
}
else
{
Types type = JsonUtils.getType(methodParameterClazz);
// other type Collection, Map or Object[].
if (type != null)
{
switch (type)
{
case ARRAY_OBJECT : {
Object array = createArray(methodParameterClazz, childJsonValue);
method.invoke(object, new Object[]{array});
}
break;
case COLLECTION : {
Type[] genericParameterTypes = method.getGenericParameterTypes();
Class<?> parameterizedTypeClass = null;
if (genericParameterTypes.length == 1)
{
if (genericParameterTypes[0] instanceof ParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType)genericParameterTypes[0];
try
{
// Collection can't be parameterized by other Collection,
// Array, etc.
parameterizedTypeClass = (Class<?>)parameterizedType.getActualTypeArguments()[0];
}
catch (ClassCastException e)
{
throw new JsonException("Unsupported parameter in method " + clazz.getName() + "#"
+ method.getName()
+ ". This type of Collection can't be restored from JSON source.\n"
+ "Collection is parameterized by wrong Type: " + parameterizedType + ".");
}
}
else
{
throw new JsonException("Unsupported parameter in method " + clazz.getName() + "#"
+ method.getName() + ". Collection is not parameterized. "
+ "Collection<?> is not supported. \nCollection must be parameterized by"
+ " any types, or by JavaBean with 'get' and 'set' methods.");
}
}
Constructor<?> constructor = null;
if (methodParameterClazz.isInterface()
|| Modifier.isAbstract(methodParameterClazz.getModifiers()))
{
try
{
constructor =
ArrayList.class.asSubclass(methodParameterClazz).getConstructor(
new Class[]{Collection.class});
}
catch (Exception e)
{
try
{
constructor =
HashSet.class.asSubclass(methodParameterClazz).getConstructor(
new Class[]{Collection.class});
}
catch (Exception e1)
{
try
{
constructor =
LinkedList.class.asSubclass(methodParameterClazz).getConstructor(
new Class[]{Collection.class});
}
catch (Exception e2)
{
// ignore exception here
}
}
}
}
else
{
constructor = methodParameterClazz.getConstructor(new Class[]{Collection.class});
}
if (constructor == null)
throw new JsonException("Can't find satisfied constructor for : " + methodParameterClazz
+ ", method : " + clazz.getName() + "#" + method.getName());
ArrayList<Object> sourceCollection = new ArrayList<Object>(childJsonValue.size());
Iterator<JsonValue> values = childJsonValue.getElements();
while (values.hasNext())
{
JsonValue v = values.next();
if (!JsonUtils.isKnownType(parameterizedTypeClass))
sourceCollection.add(createObject(parameterizedTypeClass, v));
else
sourceCollection.add(createObjectKnownTypes(parameterizedTypeClass, v));
}
constructor.newInstance(sourceCollection);
method.invoke(object, constructor.newInstance(sourceCollection));
}
break;
case MAP : {
Type[] genericParameterTypes = method.getGenericParameterTypes();
Class<?> parameterizedTypeClass = null;
if (genericParameterTypes.length == 1)
{
if (genericParameterTypes[0] instanceof ParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType)genericParameterTypes[0];
if (!String.class
.isAssignableFrom((Class<?>)parameterizedType.getActualTypeArguments()[0]))
throw new JsonException("Unsupported parameter in method " + clazz.getName() + "#"
+ method.getName() + ". Key of Map must be String.");
try
{
parameterizedTypeClass = (Class<?>)parameterizedType.getActualTypeArguments()[1];
}
catch (Exception e)
{
throw new JsonException("Unsupported parameter in method " + clazz.getName() + "#"
+ method.getName() + ". This type of Map can't be restored from JSON source.\n"
+ "Map is parameterized by wrong Type: " + parameterizedType + ".");
}
}
else
{
throw new JsonException("Unsupported parameter in method " + clazz.getName() + "#"
+ method.getName() + ". Map is not parameterized. "
+ "Map<Sting, ?> is not supported. \nMap must be parameterized by"
+ "String and any types or JavaBean with 'get' and 'set' methods.");
}
}
Constructor<?> constructor = null;
if (methodParameterClazz.isInterface()
|| Modifier.isAbstract(methodParameterClazz.getModifiers()))
{
try
{
constructor =
HashMap.class.asSubclass(methodParameterClazz).getConstructor(new Class[]{Map.class});
}
catch (Exception e)
{
try
{
constructor =
Hashtable.class.asSubclass(methodParameterClazz).getConstructor(
new Class[]{Map.class});
}
catch (Exception e1)
{
try
{
constructor =
LinkedHashMap.class.asSubclass(methodParameterClazz).getConstructor(
new Class[]{Map.class});
}
catch (Exception e2)
{
// ignore exception here
}
}
}
}
else
{
constructor = methodParameterClazz.getConstructor(new Class[]{Map.class});
}
if (constructor == null)
throw new JsonException("Can't find satisfied constructor for : " + methodParameterClazz
+ ", method : " + clazz.getName() + "#" + method.getName());
HashMap<String, Object> sourceMap = new HashMap<String, Object>(childJsonValue.size());
Iterator<String> keys = childJsonValue.getKeys();
while (keys.hasNext())
{
String k = keys.next();
JsonValue v = childJsonValue.getElement(k);
if (!JsonUtils.isKnownType(parameterizedTypeClass))
sourceMap.put(k, createObject(parameterizedTypeClass, v));
else
sourceMap.put(k, createObjectKnownTypes(parameterizedTypeClass, v));
}