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;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -27,18 +28,49 @@ public class DynamicDeserializer {
|
|||
T object = clazz.getDeclaredConstructor ( ).newInstance ( );
|
||||
|
||||
Field[] fields = clazz.getDeclaredFields ( );
|
||||
for (
|
||||
Field field :
|
||||
fields
|
||||
) {
|
||||
for ( Field field : fields ) {
|
||||
field.setAccessible ( true );
|
||||
|
||||
if ( field.isAnnotationPresent ( IgnoreSerialization.class ) )
|
||||
continue;
|
||||
|
||||
try {
|
||||
|
||||
if ( ! ( field.getType ( ).isAnnotationPresent ( DynSerial.class ) ) ) {
|
||||
if ( List.class.isAssignableFrom ( field.getType ( ) ) ) {
|
||||
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 ( ) ) );
|
||||
}
|
||||
else {
|
||||
|
@ -46,21 +78,42 @@ public class DynamicDeserializer {
|
|||
field.set ( object , tmp );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
|
||||
// Handle any exceptions during deserialization
|
||||
}
|
||||
}
|
||||
|
||||
Method[] mth = clazz.getDeclaredMethods ( );
|
||||
for (
|
||||
Method mt :
|
||||
mth
|
||||
) {
|
||||
if ( mt.isAnnotationPresent ( Completed.class ) ) {
|
||||
mt.invoke ( object , true );
|
||||
Method[] methods = clazz.getDeclaredMethods ( );
|
||||
for ( Method method : methods ) {
|
||||
if ( method.isAnnotationPresent ( Completed.class ) ) {
|
||||
method.invoke ( object , true );
|
||||
}
|
||||
}
|
||||
|
||||
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.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DynamicSerializer {
|
||||
|
@ -55,6 +57,11 @@ public class DynamicSerializer {
|
|||
String fieldName = field.getName ( );
|
||||
|
||||
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 );
|
||||
}
|
||||
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…
Reference in a new issue