This commit is contained in:
YuTian 2024-07-17 15:35:47 +08:00
parent 993ab1e11f
commit c578f25ac6
6 changed files with 228 additions and 0 deletions

View File

@ -16,8 +16,10 @@ public class AuLib extends JavaPlugin {
Lang.registerLangFile(this);
Lang.reload(this);
}
private void registerListeners() {
new GuiHandlerListener(this);
}

View File

@ -0,0 +1,9 @@
package com.io.yutian.aulib.exception;
public class SerializeException extends RuntimeException {
public SerializeException(Class clazz, Throwable cause) {
super(clazz.toString());
}
}

View File

@ -0,0 +1,11 @@
package com.io.yutian.aulib.serialize;
import org.json.JSONObject;
public interface ISerializable<T> {
JSONObject serialize();
T deserialize(JSONObject jsonObject);
}

View File

@ -0,0 +1,186 @@
package com.io.yutian.aulib.serialize;
import com.io.yutian.aulib.exception.SerializeException;
import com.io.yutian.aulib.util.ReflectionUtil;
import org.json.JSONArray;
import org.json.JSONObject;
import sun.misc.Unsafe;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
public class SerializeHelper {
private static Map<Class<?>, Serializer> serializers = new HashMap<>();
public static <T, V> void registerSerializer(Class<T> clazz, Serializer<T, V> serializer) {
serializers.put(clazz, serializer);
}
public static <T> JSONObject serialize(T obj) throws SerializeException {
try {
JSONObject jsonObject = new JSONObject();
Class clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
if (field.isAnnotationPresent(SerializeIgnore.class)) {
continue;
}
Object value = field.get(obj);
Object serializeValue = serializeValue(value);
jsonObject.put(field.getName(), serializeValue);
}
return jsonObject;
} catch (Exception e) {
throw new SerializeException(obj.getClass(), e);
}
}
public static <T> T deserialize(Class<T> clazz, JSONObject jsonObject) throws SerializeException {
try {
Unsafe unsafe = ReflectionUtil.getUnsafe();
T instance = (T) unsafe.allocateInstance(clazz);
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
if (field.isAnnotationPresent(SerializeIgnore.class)) {
continue;
}
String name = field.getName();
if (name.equalsIgnoreCase("this$0")) {
continue;
}
if (!jsonObject.has(name)) {
continue;
}
Object value = jsonObject.get(name);
if (value == null) {
continue;
}
Object deserializeValue = deserializeValue(field, field.getType(), value);
field.set(instance, deserializeValue);
}
return instance;
} catch (Exception e) {
throw new SerializeException(clazz, e);
}
}
private static Object deserializeValue(Field field, Class clazz0, Object value) throws SerializeException {
Class clazz = clazz0;
if (WRAPPER_TO_PRIMITIVE.containsKey(clazz)) {
clazz = WRAPPER_TO_PRIMITIVE.get(clazz);
}
if (serializers.containsKey(clazz)) {
Serializer serializer = serializers.get(clazz);
return serializer.deserialize(value);
}
if (ISerializable.class.isAssignableFrom(clazz)) {
ISerializable iSerializable = (ISerializable) value;
JSONObject jsonObject = (JSONObject) value;
return iSerializable.deserialize(jsonObject);
} else if (clazz.isPrimitive() || clazz.equals(String.class)) {
return value;
} else if (clazz.isEnum()) {
return Enum.valueOf((Class<Enum>) clazz, (String) value);
} else if (clazz.isArray()) {
JSONArray jsonArray = (JSONArray) value;
int length = jsonArray.length();
Object object = Array.newInstance(clazz.getComponentType(), length);
for (int i = 0; i < length; i++) {
Array.set(object, i, deserializeValue(field, clazz.getComponentType(), jsonArray.get(i)));
}
return object;
} else if (List.class.isAssignableFrom(clazz)) {
List list = new ArrayList();
JSONArray jsonArray = (JSONArray) value;
Type genericType = field.getGenericType();
Class<?> elementType = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
for (int i = 0; i < jsonArray.length(); i++) {
list.add(deserializeValue(field, elementType, jsonArray.get(i)));
}
return list;
} else if (Map.class.isAssignableFrom(clazz)) {
Map map = new HashMap();
Type genericType = field.getGenericType();
Class<?> valueType = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[1];
JSONObject jsonObject = (JSONObject) value;
for (String key : jsonObject.keySet()) {
map.put(key, deserializeValue(field, valueType, jsonObject.get(key)));
}
return map;
}
return null;
}
private static Object serializeValue(Object value) throws SerializeException {
Class clazz = value.getClass();
if (WRAPPER_TO_PRIMITIVE.containsKey(clazz)) {
clazz = WRAPPER_TO_PRIMITIVE.get(clazz);
}
if (serializers.containsKey(clazz)) {
Serializer serializer = serializers.get(clazz);
return serializer.serialize(value);
}
if (ISerializable.class.isAssignableFrom(clazz)) {
ISerializable iSerializable = (ISerializable) value;
return iSerializable.serialize();
} else if (clazz.isPrimitive() || clazz.equals(String.class)) {
return value;
} else if (clazz.isEnum()) {
return ((Enum) value).name();
} else if (clazz.isArray()) {
Class elementType = clazz.getComponentType();
JSONArray jsonArray = new JSONArray();
int length = Array.getLength(value);
for (int i = 0; i < length; i++) {
Object element = Array.get(value, i);
jsonArray.put(serializeValue(element));
}
return jsonArray;
} else if (List.class.isAssignableFrom(clazz)) {
List list = (List) value;
JSONArray jsonArray = new JSONArray();
for (Object element : list) {
jsonArray.put(serializeValue(element));
}
return jsonArray;
} else if (Map.class.isAssignableFrom(clazz)) {
Map map = (Map) value;
JSONObject jsonObject = new JSONObject();
for (Object key : map.keySet()) {
jsonObject.put(key.toString(), serializeValue(map.get(key)));
}
return jsonObject;
}
return null;
}
public static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE = new HashMap<>();
static {
WRAPPER_TO_PRIMITIVE.put(Boolean.class, boolean.class);
WRAPPER_TO_PRIMITIVE.put(Byte.class, byte.class);
WRAPPER_TO_PRIMITIVE.put(Short.class, short.class);
WRAPPER_TO_PRIMITIVE.put(Character.class, char.class);
WRAPPER_TO_PRIMITIVE.put(Integer.class, int.class);
WRAPPER_TO_PRIMITIVE.put(Long.class, long.class);
WRAPPER_TO_PRIMITIVE.put(Float.class, float.class);
WRAPPER_TO_PRIMITIVE.put(Double.class, double.class);
registerSerializer(UUID.class, new Serializer<>() {
@Override
public Object serialize(UUID value) {
return value.toString();
}
@Override
public UUID deserialize(Object value) {
return UUID.fromString((String) value);
}
});
}
}

View File

@ -0,0 +1,11 @@
package com.io.yutian.aulib.serialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SerializeIgnore {
}

View File

@ -0,0 +1,9 @@
package com.io.yutian.aulib.serialize;
public interface Serializer<K, V> {
V serialize(K value);
K deserialize(V value);
}