Add 序列化注解 @TSerializeCollection、@TSerializeMap、@TSerializeCustom
This commit is contained in:
parent
5f0c5a6426
commit
9ceb5b1b45
@ -8,6 +8,8 @@ import java.lang.annotation.Target;
|
|||||||
/**
|
/**
|
||||||
* @Author sky
|
* @Author sky
|
||||||
* @Since 2018-10-05 12:11
|
* @Since 2018-10-05 12:11
|
||||||
|
*
|
||||||
|
* 用于标注不需要进行序列化的内容
|
||||||
*/
|
*/
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package me.skymc.taboolib.common.serialize;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sky
|
||||||
|
* @Since 2018-10-05 12:11
|
||||||
|
*
|
||||||
|
* 用于标识 Collection 类型的字段
|
||||||
|
*/
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface TSerializeCollection {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package me.skymc.taboolib.common.serialize;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sky
|
||||||
|
* @Since 2018-10-05 12:11
|
||||||
|
*
|
||||||
|
* 用于标识 TSerializable 类型的字段
|
||||||
|
*/
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface TSerializeCustom {
|
||||||
|
|
||||||
|
}
|
@ -1,20 +1,18 @@
|
|||||||
package me.skymc.taboolib.common.serialize.container;
|
package me.skymc.taboolib.common.serialize;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author sky
|
* @Author sky
|
||||||
* @Since 2018-10-05 12:11
|
* @Since 2018-10-05 12:11
|
||||||
|
*
|
||||||
|
* 用于标识 Map 类型的字段
|
||||||
*/
|
*/
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface TSerializeMap {
|
public @interface TSerializeMap {
|
||||||
|
|
||||||
Class<? extends Map> type() default HashMap.class;
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package me.skymc.taboolib.common.serialize;
|
package me.skymc.taboolib.common.serialize;
|
||||||
|
|
||||||
import ch.njol.skript.classes.ConfigurationSerializer;
|
import ch.njol.skript.classes.ConfigurationSerializer;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
|
import me.skymc.taboolib.common.util.SimpleReflection;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||||
@ -19,27 +21,65 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public class TSerializer {
|
public class TSerializer {
|
||||||
|
|
||||||
|
private static Map<String, TSerializerElement> generated = Maps.newHashMap();
|
||||||
|
|
||||||
public static <T extends ConfigurationSerializable> T read(String value, Class<T> type) {
|
public static <T extends ConfigurationSerializable> T read(String value, Class<T> type) {
|
||||||
return ConfigurationSerializer.deserializeCS(value, type);
|
return ConfigurationSerializer.deserializeCS(value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TSerializable read(TSerializable serializable, String serializedString) {
|
public static TSerializable read(TSerializable serializable, String serializedString) {
|
||||||
|
SimpleReflection.checkAndSave(serializable.getClass());
|
||||||
try {
|
try {
|
||||||
JsonObject jsonObject = (JsonObject) new JsonParser().parse(serializedString);
|
JsonObject jsonObject = (JsonObject) new JsonParser().parse(serializedString);
|
||||||
if (jsonObject.has("serializeObject")) {
|
if (jsonObject.has("serializeObject")) {
|
||||||
JsonObject serializeObject = jsonObject.getAsJsonObject("serializeObject");
|
JsonObject serializeObject = jsonObject.getAsJsonObject("serializeObject");
|
||||||
for (Map.Entry<String, JsonElement> jsonElementEntry : serializeObject.entrySet()) {
|
for (Map.Entry<String, JsonElement> jsonElementEntry : serializeObject.entrySet()) {
|
||||||
try {
|
try {
|
||||||
Field declaredField = serializable.getClass().getDeclaredField(jsonElementEntry.getKey());
|
Field declaredField = SimpleReflection.getField(serializable.getClass(), jsonElementEntry.getKey());
|
||||||
declaredField.setAccessible(true);
|
|
||||||
if (declaredField.isAnnotationPresent(DoNotSerialize.class)) {
|
if (declaredField.isAnnotationPresent(DoNotSerialize.class)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Optional<TSerializerElementGeneral> serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(declaredField.getType())).findFirst();
|
// Serializable
|
||||||
if (serializer.isPresent()) {
|
if (declaredField.isAnnotationPresent(TSerializeCustom.class) && TSerializable.class.isAssignableFrom(declaredField.getType())) {
|
||||||
declaredField.set(serializable, serializer.get().getSerializer().read(jsonElementEntry.getValue().getAsString()));
|
declaredField.set(serializable, generateElement((Class<? extends TSerializable>) declaredField.getType()).read(jsonElementEntry.getValue().getAsString()));
|
||||||
} else {
|
}
|
||||||
|
// List
|
||||||
|
else if (declaredField.isAnnotationPresent(TSerializeCollection.class) && Collection.class.isAssignableFrom(declaredField.getType())) {
|
||||||
|
Class listType = SimpleReflection.getListType(declaredField);
|
||||||
|
if (listType == null) {
|
||||||
serializable.read(jsonElementEntry.getKey(), jsonElementEntry.getValue().getAsString());
|
serializable.read(jsonElementEntry.getKey(), jsonElementEntry.getValue().getAsString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TSerializerElementGeneral serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(listType)).findFirst().orElse(null);
|
||||||
|
if (serializer == null) {
|
||||||
|
serializable.read(jsonElementEntry.getKey(), jsonElementEntry.getValue().getAsString());
|
||||||
|
} else {
|
||||||
|
readCollection((Collection) declaredField.get(serializable), jsonElementEntry.getValue().getAsString(), checkCustom(listType, serializer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Map
|
||||||
|
else if (declaredField.isAnnotationPresent(TSerializeMap.class) && Map.class.isAssignableFrom(declaredField.getType())) {
|
||||||
|
Class[] mapType = SimpleReflection.getMapType(declaredField);
|
||||||
|
if (mapType == null) {
|
||||||
|
serializable.read(jsonElementEntry.getKey(), jsonElementEntry.getValue().getAsString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TSerializerElementGeneral serializerK = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(mapType[0])).findFirst().orElse(null);
|
||||||
|
TSerializerElementGeneral serializerV = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(mapType[1])).findFirst().orElse(null);
|
||||||
|
if (serializerK == null || serializerV == null) {
|
||||||
|
serializable.read(jsonElementEntry.getKey(), jsonElementEntry.getValue().getAsString());
|
||||||
|
} else {
|
||||||
|
readMap((Map) declaredField.get(serializable), jsonElementEntry.getValue().getAsString(), checkCustom(mapType[0], serializerK), checkCustom(mapType[1], serializerV));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 未声明类型
|
||||||
|
else {
|
||||||
|
TSerializerElementGeneral serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(declaredField.getType())).findFirst().orElse(null);
|
||||||
|
if (serializer == null) {
|
||||||
|
serializable.read(jsonElementEntry.getKey(), jsonElementEntry.getValue().getAsString());
|
||||||
|
} else {
|
||||||
|
declaredField.set(serializable, serializer.getSerializer().read(jsonElementEntry.getValue().getAsString()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
@ -57,21 +97,57 @@ public class TSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String write(TSerializable serializable) {
|
public static String write(TSerializable serializable) {
|
||||||
|
SimpleReflection.checkAndSave(serializable.getClass());
|
||||||
JsonObject jsonObject = new JsonObject();
|
JsonObject jsonObject = new JsonObject();
|
||||||
JsonObject serializeObject = new JsonObject();
|
JsonObject serializeObject = new JsonObject();
|
||||||
for (Field declaredField : serializable.getClass().getDeclaredFields()) {
|
for (Field declaredField : SimpleReflection.getFields(serializable.getClass()).values()) {
|
||||||
try {
|
try {
|
||||||
if (!declaredField.isAnnotationPresent(DoNotSerialize.class) && !Modifier.isStatic(declaredField.getModifiers())) {
|
if (!declaredField.isAnnotationPresent(DoNotSerialize.class) && !Modifier.isStatic(declaredField.getModifiers())) {
|
||||||
declaredField.setAccessible(true);
|
Object fieldObject = declaredField.get(serializable);
|
||||||
Object o = declaredField.get(serializable);
|
if (fieldObject == null) {
|
||||||
if (o == null) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Optional<TSerializerElementGeneral> serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(declaredField.getType())).findFirst();
|
// Serializable
|
||||||
if (serializer.isPresent()) {
|
if (declaredField.isAnnotationPresent(TSerializeCustom.class) && TSerializable.class.isAssignableFrom(declaredField.getType())) {
|
||||||
serializeObject.addProperty(declaredField.getName(), serializer.get().getSerializer().write(o));
|
serializeObject.addProperty(declaredField.getName(), generateElement((Class<? extends TSerializable>) declaredField.getType()).write(fieldObject));
|
||||||
|
}
|
||||||
|
// List
|
||||||
|
else if (declaredField.isAnnotationPresent(TSerializeCollection.class) && Collection.class.isAssignableFrom(declaredField.getType())) {
|
||||||
|
Class listType = SimpleReflection.getListType(declaredField);
|
||||||
|
if (listType == null) {
|
||||||
|
Optional.ofNullable(serializable.write(declaredField.getName(), fieldObject)).ifPresent(value -> serializeObject.addProperty(declaredField.getName(), value));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TSerializerElementGeneral serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(listType)).findFirst().orElse(null);
|
||||||
|
if (serializer == null) {
|
||||||
|
Optional.ofNullable(serializable.write(declaredField.getName(), fieldObject)).ifPresent(value -> serializeObject.addProperty(declaredField.getName(), value));
|
||||||
} else {
|
} else {
|
||||||
Optional.ofNullable(serializable.write(declaredField.getName(), o)).ifPresent(value -> serializeObject.addProperty(declaredField.getName(), value));
|
serializeObject.addProperty(declaredField.getName(), writeCollection((Collection) fieldObject, checkCustom(listType, serializer)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Map
|
||||||
|
else if (declaredField.isAnnotationPresent(TSerializeMap.class) && Map.class.isAssignableFrom(declaredField.getType())) {
|
||||||
|
Class[] mapType = SimpleReflection.getMapType(declaredField);
|
||||||
|
if (mapType == null) {
|
||||||
|
Optional.ofNullable(serializable.write(declaredField.getName(), fieldObject)).ifPresent(value -> serializeObject.addProperty(declaredField.getName(), value));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TSerializerElementGeneral serializerK = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(mapType[0])).findFirst().orElse(null);
|
||||||
|
TSerializerElementGeneral serializerV = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(mapType[1])).findFirst().orElse(null);
|
||||||
|
if (serializerK == null || serializerV == null) {
|
||||||
|
Optional.ofNullable(serializable.write(declaredField.getName(), fieldObject)).ifPresent(value -> serializeObject.addProperty(declaredField.getName(), value));
|
||||||
|
} else {
|
||||||
|
serializeObject.addProperty(declaredField.getName(), writeMap((Map) fieldObject, checkCustom(mapType[0], serializerK), checkCustom(mapType[1], serializerV)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 未声明类型
|
||||||
|
else {
|
||||||
|
TSerializerElementGeneral serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(declaredField.getType())).findFirst().orElse(null);
|
||||||
|
if (serializer == null) {
|
||||||
|
Optional.ofNullable(serializable.write(declaredField.getName(), fieldObject)).ifPresent(value -> serializeObject.addProperty(declaredField.getName(), value));
|
||||||
|
} else {
|
||||||
|
serializeObject.addProperty(declaredField.getName(), serializer.getSerializer().write(fieldObject));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@ -168,4 +244,33 @@ public class TSerializer {
|
|||||||
Object o = y.get("value");
|
Object o = y.get("value");
|
||||||
return !c.isInstance(o) ? null : (T) o;
|
return !c.isInstance(o) ? null : (T) o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TSerializerElement generateElement(Class<? extends TSerializable> serializable) {
|
||||||
|
return generated.computeIfAbsent(serializable.getName(), n -> new TSerializerElement() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object read(String value) {
|
||||||
|
try {
|
||||||
|
return serializable.newInstance().read(value);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String write(Object value) {
|
||||||
|
return ((TSerializable) value).write();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Class objectClass) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TSerializerElement checkCustom(Class type, TSerializerElementGeneral serializer) {
|
||||||
|
return serializer == TSerializerElementGeneral.CUSTOM ? generateElement(type) : serializer.getSerializer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,4 @@ public interface TSerializerElement<T> {
|
|||||||
String write(T value);
|
String write(T value);
|
||||||
|
|
||||||
boolean matches(Class objectClass);
|
boolean matches(Class objectClass);
|
||||||
|
|
||||||
}
|
}
|
@ -182,7 +182,7 @@ public enum TSerializerElementGeneral {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Class objectClass) {
|
public boolean matches(Class objectClass) {
|
||||||
return ItemStack.class.equals(objectClass);
|
return ItemStack.class.isAssignableFrom(objectClass);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -200,7 +200,25 @@ public enum TSerializerElementGeneral {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Class objectClass) {
|
public boolean matches(Class objectClass) {
|
||||||
return Location.class.equals(objectClass);
|
return Location.class.isAssignableFrom(objectClass);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
CUSTOM(new TSerializerElement() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object read(String value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String write(Object value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Class objectClass) {
|
||||||
|
return TSerializable.class.isAssignableFrom(objectClass);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@ package me.skymc.taboolib.common.serialize;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import me.skymc.taboolib.string.ArrayUtils;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -15,17 +16,19 @@ public class TSerializerExample {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// 创建对象
|
// 创建对象
|
||||||
SimpleData date = new SimpleData();
|
SimpleData data = new SimpleData();
|
||||||
// 修改参数
|
// 修改参数
|
||||||
date.number = 100;
|
data.number = 9999;
|
||||||
|
data.list.addAll(ArrayUtils.asList(111D, 222D));
|
||||||
|
data.map.putAll(ImmutableMap.of("a", "b", "c", "d"));
|
||||||
// 序列化
|
// 序列化
|
||||||
String value = date.writeBase64();
|
String value = data.write();
|
||||||
// 打印
|
// 打印
|
||||||
System.out.println(value);
|
System.out.println(value);
|
||||||
// 创建新的对象
|
// 创建新的对象
|
||||||
SimpleData dataCopy = new SimpleData();
|
SimpleData dataCopy = new SimpleData();
|
||||||
// 反序列化
|
// 反序列化
|
||||||
dataCopy.readBase64(value);
|
dataCopy.read(value);
|
||||||
// 打印
|
// 打印
|
||||||
System.out.println(dataCopy);
|
System.out.println(dataCopy);
|
||||||
}
|
}
|
||||||
@ -44,14 +47,13 @@ public class TSerializerExample {
|
|||||||
private int number = 100;
|
private int number = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 特殊类型需要进行手动序列化
|
* 包含基本类型的容器需要通过标注来完成序列化
|
||||||
* 标注 @TSerializeCollection 或 @TSerializeMap 来进行自动序列化(未完成)
|
|
||||||
*/
|
*/
|
||||||
// @TSerializeCollection
|
@TSerializeCollection
|
||||||
private List<Double> list = Lists.newArrayList(1.0, 2.0, 3.0);
|
private List<Double> list = Lists.newArrayList();
|
||||||
|
|
||||||
// @TSerializeMap
|
@TSerializeMap
|
||||||
private Map<String, String> map = ImmutableMap.of("abc", "def");
|
private Map<String, String> map = Maps.newHashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跳过序列化
|
* 跳过序列化
|
||||||
@ -59,32 +61,13 @@ public class TSerializerExample {
|
|||||||
@DoNotSerialize
|
@DoNotSerialize
|
||||||
private String ignoreSerialize = "aaa";
|
private String ignoreSerialize = "aaa";
|
||||||
|
|
||||||
/**
|
|
||||||
* 基本类型不会执行以下两个方法
|
|
||||||
* 由 TSerializer 自动进行序列化和反序列化步骤
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void read(String fieldName, String value) {
|
|
||||||
if (fieldName.equals("list")) {
|
|
||||||
// List 类型可以直接通过 TSerializer 提供的预设方法进行反序列化
|
|
||||||
TSerializer.readCollection(list, value, TSerializerElementGeneral.DOUBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String write(String fieldName, Object value) {
|
|
||||||
if (fieldName.equals("list")) {
|
|
||||||
return TSerializer.writeCollection((Collection) value, TSerializerElementGeneral.DOUBLE);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SimpleData{" +
|
return "SimpleData{" +
|
||||||
"text='" + text + '\'' +
|
"text='" + text + '\'' +
|
||||||
", number=" + number +
|
", number=" + number +
|
||||||
", list=" + list +
|
", list=" + list +
|
||||||
|
", map=" + map +
|
||||||
", ignoreSerialize='" + ignoreSerialize + '\'' +
|
", ignoreSerialize='" + ignoreSerialize + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package me.skymc.taboolib.common.serialize.container;
|
|
||||||
|
|
||||||
import me.skymc.taboolib.common.serialize.TSerializerElement;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author sky
|
|
||||||
* @Since 2018-10-05 12:11
|
|
||||||
*/
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface TSerializeCollection {
|
|
||||||
|
|
||||||
Class<? extends Collection> type() default ArrayList.class;
|
|
||||||
|
|
||||||
Class<? extends TSerializerElement> element() default TSerializerElement.class;
|
|
||||||
|
|
||||||
}
|
|
@ -3,6 +3,8 @@ package me.skymc.taboolib.common.util;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -14,6 +16,24 @@ public class SimpleReflection {
|
|||||||
|
|
||||||
private static Map<String, Map<String, Field>> fieldCached = Maps.newHashMap();
|
private static Map<String, Map<String, Field>> fieldCached = Maps.newHashMap();
|
||||||
|
|
||||||
|
public static boolean isExists(Class<?> nmsClass) {
|
||||||
|
return fieldCached.containsKey(nmsClass.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Field> getFields(Class<?> nmsClass) {
|
||||||
|
return fieldCached.getOrDefault(nmsClass.getName(), Maps.newHashMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Field getField(Class<?> nmsClass, String fieldName) {
|
||||||
|
return fieldCached.getOrDefault(nmsClass.getName(), Maps.newHashMap()).get(fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void checkAndSave(Class<?> nmsClass) {
|
||||||
|
if (!isExists(nmsClass)) {
|
||||||
|
saveField(nmsClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void saveField(Class<?> nmsClass) {
|
public static void saveField(Class<?> nmsClass) {
|
||||||
try {
|
try {
|
||||||
Arrays.stream(nmsClass.getDeclaredFields()).forEach(declaredField -> saveField(nmsClass, declaredField.getName()));
|
Arrays.stream(nmsClass.getDeclaredFields()).forEach(declaredField -> saveField(nmsClass, declaredField.getName()));
|
||||||
@ -82,4 +102,32 @@ public class SimpleReflection {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Class getListType(Field field) {
|
||||||
|
Type genericType = field.getGenericType();
|
||||||
|
try {
|
||||||
|
if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
|
||||||
|
for (Type actualTypeArgument : ((ParameterizedType) genericType).getActualTypeArguments()) {
|
||||||
|
return Class.forName(actualTypeArgument.getTypeName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class[] getMapType(Field field) {
|
||||||
|
Class[] mapType = new Class[2];
|
||||||
|
try {
|
||||||
|
Type genericType = field.getGenericType();
|
||||||
|
if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
|
||||||
|
for (Type actualTypeArgument : ((ParameterizedType) genericType).getActualTypeArguments()) {
|
||||||
|
mapType[mapType[0] == null ? 0 : 1] = Class.forName(actualTypeArgument.getTypeName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
return mapType[1] == null ? null : mapType ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,12 @@ public class ClickEvent {
|
|||||||
|
|
||||||
private ClickType clickType;
|
private ClickType clickType;
|
||||||
private Event event;
|
private Event event;
|
||||||
|
private char slot;
|
||||||
|
|
||||||
public ClickEvent(ClickType clickType, Event event) {
|
public ClickEvent(ClickType clickType, Event event, char slot) {
|
||||||
this.clickType = clickType;
|
this.clickType = clickType;
|
||||||
this.event = event;
|
this.event = event;
|
||||||
|
this.slot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryClickEvent castClick() {
|
public InventoryClickEvent castClick() {
|
||||||
@ -28,6 +30,10 @@ public class ClickEvent {
|
|||||||
return (InventoryDragEvent) event;
|
return (InventoryDragEvent) event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public char getSlot() {
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
public ClickType getClickType() {
|
public ClickType getClickType() {
|
||||||
return clickType;
|
return clickType;
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,14 @@ class ClickListener implements Listener {
|
|||||||
if (((MenuHolder) e.getInventory().getHolder()).getBuilder().isLockHand() && (e.getRawSlot() - e.getInventory().getSize() - 27 == e.getWhoClicked().getInventory().getHeldItemSlot() || (e.getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY && e.getHotbarButton() == e.getWhoClicked().getInventory().getHeldItemSlot()))) {
|
if (((MenuHolder) e.getInventory().getHolder()).getBuilder().isLockHand() && (e.getRawSlot() - e.getInventory().getSize() - 27 == e.getWhoClicked().getInventory().getHeldItemSlot() || (e.getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY && e.getHotbarButton() == e.getWhoClicked().getInventory().getHeldItemSlot()))) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
Optional.ofNullable(((MenuHolder) e.getInventory().getHolder()).getBuilder().getClickTask()).ifPresent(t -> t.run(new ClickEvent(ClickType.CLICK, e)));
|
Optional.ofNullable(((MenuHolder) e.getInventory().getHolder()).getBuilder().getClickTask()).ifPresent(t -> t.run(new ClickEvent(ClickType.CLICK, e, ((MenuHolder) e.getInventory().getHolder()).getBuilder().getSlot(e.getRawSlot()))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onDrag(InventoryDragEvent e) {
|
public void onDrag(InventoryDragEvent e) {
|
||||||
if (e.getInventory().getHolder() instanceof MenuHolder) {
|
if (e.getInventory().getHolder() instanceof MenuHolder) {
|
||||||
Optional.ofNullable(((MenuHolder) e.getInventory().getHolder()).getBuilder().getClickTask()).ifPresent(t -> t.run(new ClickEvent(ClickType.DRAG, e)));
|
Optional.ofNullable(((MenuHolder) e.getInventory().getHolder()).getBuilder().getClickTask()).ifPresent(t -> t.run(new ClickEvent(ClickType.DRAG, e, ' ')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,18 @@ public class MenuBuilder {
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public char getSlot(int slot) {
|
||||||
|
for (int i = 0; i < items.length && i < rows; i++) {
|
||||||
|
char[] line = items[i];
|
||||||
|
for (int j = 0; j < line.length && j < 9; j++) {
|
||||||
|
if (i * 9 + j == slot) {
|
||||||
|
return line[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
|
||||||
// *********************************
|
// *********************************
|
||||||
//
|
//
|
||||||
// Getter and Setter
|
// Getter and Setter
|
||||||
|
Loading…
Reference in New Issue
Block a user