Updated JSONObjectOutputStream to support extended generics

This commit is contained in:
Ziver Koc 2015-11-05 02:07:08 +01:00
parent 2dae3a6f01
commit 8ca2f21c7c
3 changed files with 54 additions and 13 deletions

10
Zutil.iml Normal file → Executable file
View file

@ -32,5 +32,15 @@
<jarDirectory url="file://$MODULE_DIR$/libs" recursive="false" type="SOURCES" />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library name="JUnit4">
<CLASSES>
<root url="jar://$APPLICATION_HOME_DIR$/lib/junit-4.12.jar!/" />
<root url="jar://$APPLICATION_HOME_DIR$/lib/hamcrest-core-1.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

42
src/zutil/ClassUtil.java Normal file → Executable file
View file

@ -27,8 +27,11 @@ package zutil;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
/**
* This class include some utility functions for classes
@ -83,15 +86,42 @@ public class ClassUtil {
}
/**
* @param field is the field to return the generics from
* @return the generics assigned to a specific field or a empty list
*/
public static Class<?>[] getGenericClasses(Field field){
Class[] classArray = new Class[0];
Type genericFieldType = field.getGenericType();
return getGenericClasses(field.getGenericType());
}
/**
* Traverses the class hierarchy and searches for the given super class or interface
* and returns the assigned generic types.
*
* @param c the source class
* @param superClass is the super class to search for
* @return the generics for a specific super class or a empty list if
* there is no generics or the super class is not found
*/
public static Class<?>[] getGenericClasses(Class<?> c, Class<?> superClass){
// Search for the super class
while (c.getSuperclass() != Object.class && !superClass.isAssignableFrom(c.getSuperclass()))
c = c.getSuperclass();
// Did we find the super class?
if (superClass.isAssignableFrom(c.getSuperclass()))
return getGenericClasses(c.getGenericSuperclass());
if(genericFieldType instanceof ParameterizedType){
ParameterizedType aType = (ParameterizedType) genericFieldType;
Type[] fieldArgTypes = aType.getActualTypeArguments();
classArray = Arrays.copyOf(fieldArgTypes, fieldArgTypes.length, Class[].class);
return new Class[0];
}
private static Class<?>[] getGenericClasses(Type genericType){
if(genericType instanceof ParameterizedType){
ParameterizedType aType = (ParameterizedType) genericType;
Type[] argTypes = aType.getActualTypeArguments();
Class<?>[] classArray = new Class<?>[argTypes.length];
for(int i=0; i<classArray.length; ++i) {
classArray[i] = (Class<?>) argTypes[i];
}
return classArray;
}
return new Class[0];
}
}

View file

@ -129,8 +129,8 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Object readType(Class<?> type, Class<?>[] genType, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException, NoSuchFieldException {
if(json == null)
protected Object readType(Class<?> type, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException, NoSuchFieldException {
if(json == null || type == null)
return null;
// Field type is a primitive?
if(type.isPrimitive() || String.class.isAssignableFrom(type)){
@ -142,25 +142,27 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
else{
Object array = Array.newInstance(type.getComponentType(), json.size());
for(int i=0; i<json.size(); i++){
Array.set(array, i, readType(type.getComponentType(), null, key, json.get(i)));
Array.set(array, i, readType(type.getComponentType(), key, json.get(i)));
}
return array;
}
}
else if(List.class.isAssignableFrom(type)){
Class<?>[] genType = ClassUtil.getGenericClasses(type, List.class);
List list = (List)type.newInstance();
for(int i=0; i<json.size(); i++){
list.add(readType(genType[0], null, key, json.get(i)));
list.add(readType((genType.length>=1? genType[0] : null), key, json.get(i)));
}
return list;
}
else if(Map.class.isAssignableFrom(type)){
Class<?>[] genType = ClassUtil.getGenericClasses(type, Map.class);
Map map = (Map)type.newInstance();
for(Iterator<String> it=json.keyIterator(); it.hasNext();){
String subKey = it.next();
map.put(
subKey,
readType(genType[1], null, subKey, json.get(subKey)));
readType((genType.length>=2? genType[1] : null), subKey, json.get(subKey)));
}
return map;
}
@ -210,7 +212,6 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
field.setAccessible(true);
field.set(obj, readType(
field.getType(),
ClassUtil.getGenericClasses(field),
field.getName(),
json.get(field.getName())));
}