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" />
|
<jarDirectory url="file://$MODULE_DIR$/libs" recursive="false" type="SOURCES" />
|
||||||
</library>
|
</library>
|
||||||
</orderEntry>
|
</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>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
44
src/zutil/ClassUtil.java
Normal file → Executable file
44
src/zutil/ClassUtil.java
Normal file → Executable file
|
|
@ -27,8 +27,11 @@ package zutil;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.lang.reflect.TypeVariable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class include some utility functions for classes
|
* 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){
|
public static Class<?>[] getGenericClasses(Field field){
|
||||||
Class[] classArray = new Class[0];
|
return getGenericClasses(field.getGenericType());
|
||||||
Type genericFieldType = 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){
|
return new Class[0];
|
||||||
ParameterizedType aType = (ParameterizedType) genericFieldType;
|
}
|
||||||
Type[] fieldArgTypes = aType.getActualTypeArguments();
|
private static Class<?>[] getGenericClasses(Type genericType){
|
||||||
classArray = Arrays.copyOf(fieldArgTypes, fieldArgTypes.length, Class[].class);
|
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 classArray;
|
return new Class[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,8 +129,8 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
protected Object readType(Class<?> type, Class<?>[] genType, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException, NoSuchFieldException {
|
protected Object readType(Class<?> type, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException, NoSuchFieldException {
|
||||||
if(json == null)
|
if(json == null || type == null)
|
||||||
return null;
|
return null;
|
||||||
// Field type is a primitive?
|
// Field type is a primitive?
|
||||||
if(type.isPrimitive() || String.class.isAssignableFrom(type)){
|
if(type.isPrimitive() || String.class.isAssignableFrom(type)){
|
||||||
|
|
@ -142,25 +142,27 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
|
||||||
else{
|
else{
|
||||||
Object array = Array.newInstance(type.getComponentType(), json.size());
|
Object array = Array.newInstance(type.getComponentType(), json.size());
|
||||||
for(int i=0; i<json.size(); i++){
|
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;
|
return array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(List.class.isAssignableFrom(type)){
|
else if(List.class.isAssignableFrom(type)){
|
||||||
|
Class<?>[] genType = ClassUtil.getGenericClasses(type, List.class);
|
||||||
List list = (List)type.newInstance();
|
List list = (List)type.newInstance();
|
||||||
for(int i=0; i<json.size(); i++){
|
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;
|
return list;
|
||||||
}
|
}
|
||||||
else if(Map.class.isAssignableFrom(type)){
|
else if(Map.class.isAssignableFrom(type)){
|
||||||
|
Class<?>[] genType = ClassUtil.getGenericClasses(type, Map.class);
|
||||||
Map map = (Map)type.newInstance();
|
Map map = (Map)type.newInstance();
|
||||||
for(Iterator<String> it=json.keyIterator(); it.hasNext();){
|
for(Iterator<String> it=json.keyIterator(); it.hasNext();){
|
||||||
String subKey = it.next();
|
String subKey = it.next();
|
||||||
map.put(
|
map.put(
|
||||||
subKey,
|
subKey,
|
||||||
readType(genType[1], null, subKey, json.get(subKey)));
|
readType((genType.length>=2? genType[1] : null), subKey, json.get(subKey)));
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +212,6 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
field.set(obj, readType(
|
field.set(obj, readType(
|
||||||
field.getType(),
|
field.getType(),
|
||||||
ClassUtil.getGenericClasses(field),
|
|
||||||
field.getName(),
|
field.getName(),
|
||||||
json.get(field.getName())));
|
json.get(field.getName())));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue