更新一下配置类
This commit is contained in:
parent
f40039f9ce
commit
20fcb3dfa0
@ -1,33 +1,20 @@
|
|||||||
package com.ilummc.tlib.inject;
|
package com.ilummc.tlib.inject;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import com.ilummc.tlib.TLib;
|
||||||
|
import com.ilummc.tlib.annotations.Config;
|
||||||
|
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import com.ilummc.tlib.TLib;
|
|
||||||
import com.ilummc.tlib.annotations.Config;
|
|
||||||
import com.ilummc.tlib.bean.Property;
|
|
||||||
|
|
||||||
public class TConfigInjector {
|
public class TConfigInjector {
|
||||||
|
|
||||||
@ -83,9 +70,10 @@ public class TConfigInjector {
|
|||||||
try {
|
try {
|
||||||
Config config = clazz.getAnnotation(Config.class);
|
Config config = clazz.getAnnotation(Config.class);
|
||||||
Validate.notNull(config);
|
Validate.notNull(config);
|
||||||
return new GsonBuilder().disableHtmlEscaping().excludeFieldsWithModifiers(config.excludeModifiers())
|
return ConfigUtils.confToObj(
|
||||||
.create().fromJson(new Gson().toJson(new Yaml()
|
ConfigUtils.mapToConf(
|
||||||
.dump(Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz);
|
ConfigUtils.yamlToMap(
|
||||||
|
Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解或文件不存在");
|
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解或文件不存在");
|
||||||
return null;
|
return null;
|
||||||
@ -103,7 +91,7 @@ public class TConfigInjector {
|
|||||||
try {
|
try {
|
||||||
Config config = object.getClass().getAnnotation(Config.class);
|
Config config = object.getClass().getAnnotation(Config.class);
|
||||||
Validate.notNull(config);
|
Validate.notNull(config);
|
||||||
return new Serializer(new LinkedHashMap<>(), object, config.excludeModifiers()).get();
|
return ConfigUtils.objToConf(object).getValues(false);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败:没有 @Config 注解");
|
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败:没有 @Config 注解");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -128,64 +116,4 @@ public class TConfigInjector {
|
|||||||
Files.write(arr, target);
|
Files.write(arr, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final List<Class<?>> primitiveType = Lists.newArrayList(Integer.class,
|
|
||||||
Double.class, Float.class, Boolean.class, Short.class, Byte.class, Character.class, Long.class, String.class);
|
|
||||||
|
|
||||||
private static class Serializer {
|
|
||||||
|
|
||||||
private HashMap<String, Object> map;
|
|
||||||
private Object o;
|
|
||||||
private int modifiers;
|
|
||||||
|
|
||||||
private Serializer(HashMap<String, Object> map, Object o, int modifiers) {
|
|
||||||
this.map = map;
|
|
||||||
this.o = o;
|
|
||||||
this.modifiers = modifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HashMap<String, Object> get() {
|
|
||||||
for (Field field : o.getClass().getDeclaredFields()) {
|
|
||||||
if ((field.getModifiers() & modifiers) == 0 && !field.isSynthetic())
|
|
||||||
try {
|
|
||||||
SerializedName node = field.getAnnotation(SerializedName.class);
|
|
||||||
if (!field.isAccessible()) field.setAccessible(true);
|
|
||||||
Object obj = field.get(o);
|
|
||||||
map.put(node == null ? field.getName() : node.value(), serialize(obj));
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
||||||
private Object serialize(Object o) {
|
|
||||||
try {
|
|
||||||
if (o.getClass().isPrimitive() || primitiveType.contains(o.getClass())) {
|
|
||||||
return o;
|
|
||||||
} else if (o.getClass().isArray()) {
|
|
||||||
return ImmutableList.copyOf(((Object[]) o));
|
|
||||||
} else if (o instanceof Collection) {
|
|
||||||
return ((Collection) o).stream().map(this::serialize).collect(Collectors.toList());
|
|
||||||
} else if (o instanceof Map) {
|
|
||||||
Map map = new LinkedHashMap<>();
|
|
||||||
((Map) o).forEach((o1, o2) -> map.put(o1, serialize(o2)));
|
|
||||||
return map;
|
|
||||||
} else if (o instanceof ConfigurationSerializable) {
|
|
||||||
Map map = new LinkedHashMap<>();
|
|
||||||
map.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY,
|
|
||||||
ConfigurationSerialization.getAlias((Class<? extends ConfigurationSerializable>) o.getClass()));
|
|
||||||
map.putAll(((ConfigurationSerializable) o).serialize());
|
|
||||||
return map;
|
|
||||||
} else if (o instanceof Property) {
|
|
||||||
return serialize(((Property) o).get());
|
|
||||||
} else {
|
|
||||||
return new Serializer(new HashMap<>(), o, modifiers).get();
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,18 @@
|
|||||||
package com.ilummc.tlib.util;
|
package com.ilummc.tlib.util;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
|
||||||
|
|
||||||
import org.objectweb.asm.ClassReader;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
|
|
||||||
import com.ilummc.tlib.TLib;
|
import com.ilummc.tlib.TLib;
|
||||||
import com.ilummc.tlib.util.asm.AsmAnalyser;
|
import com.ilummc.tlib.util.asm.AsmAnalyser;
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
import sun.reflect.Reflection;
|
import sun.reflect.Reflection;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
public class Ref {
|
public class Ref {
|
||||||
|
|
||||||
@ -71,6 +64,19 @@ public class Ref {
|
|||||||
return Optional.ofNullable(CallerClass.impl.getCallerClass(depth + 1));
|
return Optional.ofNullable(CallerClass.impl.getCallerClass(depth + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getSerializedName(Field field) {
|
||||||
|
return field.isAnnotationPresent(SerializedName.class) ? field.getAnnotation(SerializedName.class).value() : field.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Field> getFieldBySerializedName(Class<?> clazz, String name) {
|
||||||
|
for (Field field : Ref.getDeclaredFields(clazz, 0, false)) {
|
||||||
|
if (field.isAnnotationPresent(SerializedName.class))
|
||||||
|
if (field.getAnnotation(SerializedName.class).value().equals(name)) return Optional.of(field);
|
||||||
|
else if (field.getName().equals(name)) return Optional.of(field);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
private static abstract class CallerClass {
|
private static abstract class CallerClass {
|
||||||
|
|
||||||
private static CallerClass impl;
|
private static CallerClass impl;
|
||||||
@ -88,7 +94,7 @@ public class Ref {
|
|||||||
|
|
||||||
private static class ReflectionImpl extends CallerClass {
|
private static class ReflectionImpl extends CallerClass {
|
||||||
|
|
||||||
@SuppressWarnings({ "deprecation", "restriction" })
|
@SuppressWarnings({"deprecation", "restriction"})
|
||||||
@Override
|
@Override
|
||||||
Class<?> getCallerClass(int i) {
|
Class<?> getCallerClass(int i) {
|
||||||
return Reflection.getCallerClass(i);
|
return Reflection.getCallerClass(i);
|
||||||
|
@ -1,20 +1,134 @@
|
|||||||
package me.skymc.taboolib.fileutils;
|
package me.skymc.taboolib.fileutils;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.ilummc.tlib.TLib;
|
||||||
|
import com.ilummc.tlib.util.Ref;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.MemoryConfiguration;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import java.lang.reflect.Modifier;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import java.util.LinkedHashMap;
|
||||||
import org.bukkit.plugin.Plugin;
|
import java.util.Map;
|
||||||
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.ilummc.tlib.TLib;
|
|
||||||
|
|
||||||
public class ConfigUtils {
|
public class ConfigUtils {
|
||||||
|
|
||||||
|
private static final Yaml YAML;
|
||||||
|
|
||||||
|
static {
|
||||||
|
DumperOptions options = new DumperOptions();
|
||||||
|
options.setAllowUnicode(false);
|
||||||
|
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||||
|
YAML = new Yaml(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Map<String, Object> yamlToMap(String yamlText) {
|
||||||
|
return YAML.loadAs(yamlText, LinkedHashMap.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MemoryConfiguration objToConf(Object object) {
|
||||||
|
return mapToConf(objToMap(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MemoryConfiguration objToConf(Object object, int excludedModifiers) {
|
||||||
|
return mapToConf(objToMap(object, excludedModifiers));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Object confToObj(MemoryConfiguration configuration, Class<T> clazz) {
|
||||||
|
try {
|
||||||
|
return mapToObj(configuration.getValues(false), clazz.newInstance());
|
||||||
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Object confToObj(MemoryConfiguration configuration, T obj) {
|
||||||
|
return mapToObj(configuration.getValues(false), obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String mapToYaml(Map<String, Object> map) {
|
||||||
|
String dump = YAML.dump(map);
|
||||||
|
if (dump.equals("{}\n")) {
|
||||||
|
dump = "";
|
||||||
|
}
|
||||||
|
return dump;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MemoryConfiguration mapToConf(Map<String, Object> map) {
|
||||||
|
MemoryConfiguration configuration = new MemoryConfiguration();
|
||||||
|
convertMapsToSections(map, configuration);
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> confToMap(MemoryConfiguration configuration) {
|
||||||
|
return configuration.getValues(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将会在该类无默认构造方法时返回 null
|
||||||
|
*/
|
||||||
|
public static <T> T mapToObj(Map<String, Object> map, Class<T> clazz) {
|
||||||
|
try {
|
||||||
|
return mapToObj(map, clazz.newInstance());
|
||||||
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T mapToObj(Map<String, Object> map, T obj) {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
map.forEach((string, value) -> Ref.getFieldBySerializedName(clazz, string).ifPresent(field -> {
|
||||||
|
if (!field.isAccessible())
|
||||||
|
field.setAccessible(true);
|
||||||
|
try {
|
||||||
|
field.set(obj, value);
|
||||||
|
} catch (IllegalAccessException ignored) {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> objToMap(Object object) {
|
||||||
|
return objToMap(object, Modifier.TRANSIENT & Modifier.STATIC & Ref.ACC_SYNTHETIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> objToMap(Object object, int excludedModifiers) {
|
||||||
|
Map<String, Object> map = Maps.newHashMap();
|
||||||
|
for (Field field : Ref.getDeclaredFields(object.getClass(), excludedModifiers, false)) {
|
||||||
|
try {
|
||||||
|
if (!field.isAccessible()) field.setAccessible(true);
|
||||||
|
map.put(Ref.getSerializedName(field), field.get(object));
|
||||||
|
} catch (IllegalAccessException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void convertMapsToSections(Map<?, ?> input, ConfigurationSection section) {
|
||||||
|
for (Object o : input.entrySet()) {
|
||||||
|
Map.Entry<?, ?> entry = (Map.Entry) o;
|
||||||
|
String key = entry.getKey().toString();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (value instanceof Map) {
|
||||||
|
convertMapsToSections((Map) value, section.createSection(key));
|
||||||
|
} else {
|
||||||
|
section.set(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static FileConfiguration decodeYAML(String args) {
|
public static FileConfiguration decodeYAML(String args) {
|
||||||
return YamlConfiguration.loadConfiguration(new StringReader(Base64Coder.decodeString(args)));
|
return YamlConfiguration.loadConfiguration(new StringReader(Base64Coder.decodeString(args)));
|
||||||
}
|
}
|
||||||
@ -25,7 +139,7 @@ public class ConfigUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 以 UTF-8 的格式释放配置文件并载入
|
* 以 UTF-8 的格式释放配置文件并载入
|
||||||
*
|
* <p>
|
||||||
* 录入时间:2018年2月10日21:28:30
|
* 录入时间:2018年2月10日21:28:30
|
||||||
* 录入版本:3.49
|
* 录入版本:3.49
|
||||||
*
|
*
|
||||||
@ -61,6 +175,7 @@ public class ConfigUtils {
|
|||||||
return yaml;
|
return yaml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static FileConfiguration load(Plugin plugin, String file) {
|
public static FileConfiguration load(Plugin plugin, String file) {
|
||||||
return load(plugin, FileUtils.file(file));
|
return load(plugin, FileUtils.file(file));
|
||||||
|
Loading…
Reference in New Issue
Block a user