Special handling for map and list types during reflection

This commit is contained in:
Aria 2023-06-16 02:45:57 -07:00
parent 665c7e920f
commit 76f9d93a8b
2 changed files with 109 additions and 17 deletions

View file

@ -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;
}
}

View file

@ -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;
}
}