Updated JSONObjectOutputStream to support extended generics
This commit is contained in:
parent
2dae3a6f01
commit
8ca2f21c7c
3 changed files with 54 additions and 13 deletions
10
Zutil.iml
Normal file → Executable file
10
Zutil.iml
Normal file → Executable 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
42
src/zutil/ClassUtil.java
Normal file → Executable 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];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue