Special handling for map and list types during reflection
This commit is contained in:
parent
665c7e920f
commit
76f9d93a8b
2 changed files with 109 additions and 17 deletions
|
@ -1,9 +1,10 @@
|
||||||
package dev.zontreck.ariaslib.json;
|
package dev.zontreck.ariaslib.json;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.*;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.util.ArrayList;
|
||||||
import java.lang.reflect.Method;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,18 +28,49 @@ public class DynamicDeserializer {
|
||||||
T object = clazz.getDeclaredConstructor ( ).newInstance ( );
|
T object = clazz.getDeclaredConstructor ( ).newInstance ( );
|
||||||
|
|
||||||
Field[] fields = clazz.getDeclaredFields ( );
|
Field[] fields = clazz.getDeclaredFields ( );
|
||||||
for (
|
for ( Field field : fields ) {
|
||||||
Field field :
|
|
||||||
fields
|
|
||||||
) {
|
|
||||||
field.setAccessible ( true );
|
field.setAccessible ( true );
|
||||||
|
|
||||||
if ( field.isAnnotationPresent ( IgnoreSerialization.class ) )
|
if ( field.isAnnotationPresent ( IgnoreSerialization.class ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if ( List.class.isAssignableFrom ( field.getType ( ) ) ) {
|
||||||
if ( ! ( field.getType ( ).isAnnotationPresent ( DynSerial.class ) ) ) {
|
Class<?> listType = getListType ( field );
|
||||||
|
List<Object> list = new ArrayList<> ( );
|
||||||
|
List<?> serializedList = ( List<?> ) map.get ( field.getName ( ) );
|
||||||
|
if ( serializedList != null ) {
|
||||||
|
for ( Object listItem : serializedList ) {
|
||||||
|
if ( listType.isAnnotationPresent ( DynSerial.class ) ) {
|
||||||
|
Object deserializedItem = deserialize ( ( Map<String, Object> ) listItem , listType );
|
||||||
|
list.add ( deserializedItem );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
list.add ( listItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
field.set ( object , list );
|
||||||
|
}
|
||||||
|
else if ( Map.class.isAssignableFrom ( field.getType ( ) ) ) {
|
||||||
|
Class<?> valueType = getMapValueType ( field );
|
||||||
|
Map<String, Object> serializedMap = ( Map<String, Object> ) map.get ( field.getName ( ) );
|
||||||
|
if ( serializedMap != null ) {
|
||||||
|
Map<String, Object> mapValue = new HashMap<> ( );
|
||||||
|
for ( Map.Entry<String, Object> entry : serializedMap.entrySet ( ) ) {
|
||||||
|
Object deserializedValue;
|
||||||
|
if ( valueType.isAnnotationPresent ( DynSerial.class ) ) {
|
||||||
|
deserializedValue = deserialize ( ( Map<String, Object> ) entry.getValue ( ) , valueType );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deserializedValue = entry.getValue ( );
|
||||||
|
}
|
||||||
|
mapValue.put ( entry.getKey ( ) , deserializedValue );
|
||||||
|
}
|
||||||
|
field.set ( object , mapValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( ! field.getType ( ).isAnnotationPresent ( DynSerial.class ) ) {
|
||||||
field.set ( object , map.get ( field.getName ( ) ) );
|
field.set ( object , map.get ( field.getName ( ) ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -46,21 +78,42 @@ public class DynamicDeserializer {
|
||||||
field.set ( object , tmp );
|
field.set ( object , tmp );
|
||||||
}
|
}
|
||||||
} catch ( Exception e ) {
|
} catch ( Exception e ) {
|
||||||
|
// Handle any exceptions during deserialization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Method[] mth = clazz.getDeclaredMethods ( );
|
Method[] methods = clazz.getDeclaredMethods ( );
|
||||||
for (
|
for ( Method method : methods ) {
|
||||||
Method mt :
|
if ( method.isAnnotationPresent ( Completed.class ) ) {
|
||||||
mth
|
method.invoke ( object , true );
|
||||||
) {
|
|
||||||
if ( mt.isAnnotationPresent ( Completed.class ) ) {
|
|
||||||
mt.invoke ( object , true );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Class<?> getListType ( Field field ) {
|
||||||
|
Type genericType = field.getGenericType ( );
|
||||||
|
if ( genericType instanceof ParameterizedType ) {
|
||||||
|
ParameterizedType paramType = ( ParameterizedType ) genericType;
|
||||||
|
Type[] actualTypeArgs = paramType.getActualTypeArguments ( );
|
||||||
|
if ( actualTypeArgs.length > 0 ) {
|
||||||
|
return ( Class<?> ) actualTypeArgs[ 0 ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?> getMapValueType ( Field field ) {
|
||||||
|
Type genericType = field.getGenericType ( );
|
||||||
|
if ( genericType instanceof ParameterizedType ) {
|
||||||
|
ParameterizedType paramType = ( ParameterizedType ) genericType;
|
||||||
|
Type[] actualTypeArgs = paramType.getActualTypeArguments ( );
|
||||||
|
if ( actualTypeArgs.length > 1 ) {
|
||||||
|
return ( Class<?> ) actualTypeArgs[ 1 ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ package dev.zontreck.ariaslib.json;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class DynamicSerializer {
|
public class DynamicSerializer {
|
||||||
|
@ -55,6 +57,11 @@ public class DynamicSerializer {
|
||||||
String fieldName = field.getName ( );
|
String fieldName = field.getName ( );
|
||||||
|
|
||||||
if ( ! ( fieldVal.getClass ( ).isAnnotationPresent ( DynSerial.class ) ) ) {
|
if ( ! ( fieldVal.getClass ( ).isAnnotationPresent ( DynSerial.class ) ) ) {
|
||||||
|
// Special handler for List and Map is needed right here.
|
||||||
|
if (fieldVal instanceof List || fieldVal instanceof Map) {
|
||||||
|
// Special handling for List and Map types
|
||||||
|
fieldVal = serializeCollectionOrMap(fieldVal);
|
||||||
|
}
|
||||||
ret.put ( fieldName , fieldVal );
|
ret.put ( fieldName , fieldVal );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -72,4 +79,36 @@ public class DynamicSerializer {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings ("unchecked")
|
||||||
|
private static Object serializeCollectionOrMap ( Object collectionOrMap ) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
if ( collectionOrMap instanceof List ) {
|
||||||
|
List<Object> list = ( List<Object> ) collectionOrMap;
|
||||||
|
List<Object> serializedList = new ArrayList<> ( );
|
||||||
|
for ( Object item : list ) {
|
||||||
|
if ( item.getClass ( ).isAnnotationPresent ( DynSerial.class ) ) {
|
||||||
|
serializedList.add ( serialize ( item ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serializedList.add ( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return serializedList;
|
||||||
|
}
|
||||||
|
else if ( collectionOrMap instanceof Map ) {
|
||||||
|
Map<String, Object> map = ( Map<String, Object> ) collectionOrMap;
|
||||||
|
Map<String, Object> serializedMap = new HashMap<> ( );
|
||||||
|
for ( Map.Entry<String, Object> entry : map.entrySet ( ) ) {
|
||||||
|
String key = entry.getKey ( );
|
||||||
|
Object value = entry.getValue ( );
|
||||||
|
if ( value.getClass ( ).isAnnotationPresent ( DynSerial.class ) ) {
|
||||||
|
value = serialize ( value );
|
||||||
|
}
|
||||||
|
serializedMap.put ( key , value );
|
||||||
|
}
|
||||||
|
return serializedMap;
|
||||||
|
}
|
||||||
|
return collectionOrMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue