From 1d51ddf7a4a6713b6242a0ccc20f2d59507b0e38 Mon Sep 17 00:00:00 2001 From: 502647092 Date: Mon, 3 Oct 2016 01:12:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 502647092 --- .../yumc/YumCore/config/AbstractConfig.java | 8 +-- .../config/yaml/BukkitConstructor.java | 71 +++++++++++++++++++ .../config/yaml/BukkitRepresenter.java | 20 ++++++ 3 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 src/main/java/pw/yumc/YumCore/config/yaml/BukkitConstructor.java create mode 100644 src/main/java/pw/yumc/YumCore/config/yaml/BukkitRepresenter.java diff --git a/src/main/java/pw/yumc/YumCore/config/AbstractConfig.java b/src/main/java/pw/yumc/YumCore/config/AbstractConfig.java index c8bc0a6..74b6009 100644 --- a/src/main/java/pw/yumc/YumCore/config/AbstractConfig.java +++ b/src/main/java/pw/yumc/YumCore/config/AbstractConfig.java @@ -16,8 +16,6 @@ import java.util.Map; import org.apache.commons.lang.Validate; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.file.YamlConstructor; -import org.bukkit.configuration.file.YamlRepresenter; import org.bukkit.plugin.Plugin; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -28,6 +26,8 @@ import com.google.common.io.Files; import pw.yumc.YumCore.bukkit.Log; import pw.yumc.YumCore.bukkit.P; +import pw.yumc.YumCore.config.yaml.BukkitConstructor; +import pw.yumc.YumCore.config.yaml.BukkitRepresenter; /** * 抽象配置文件 @@ -48,8 +48,8 @@ public abstract class AbstractConfig extends YamlConfiguration { protected static Plugin plugin = P.instance; protected final DumperOptions yamlOptions = new DumperOptions(); - protected final Representer yamlRepresenter = new YamlRepresenter(); - protected final Yaml yamlz = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions); + protected final Representer yamlRepresenter = new BukkitRepresenter(); + protected final Yaml yamlz = new Yaml(new BukkitConstructor(), yamlRepresenter, yamlOptions); /** * 配置文件内容MAP diff --git a/src/main/java/pw/yumc/YumCore/config/yaml/BukkitConstructor.java b/src/main/java/pw/yumc/YumCore/config/yaml/BukkitConstructor.java new file mode 100644 index 0000000..58c2202 --- /dev/null +++ b/src/main/java/pw/yumc/YumCore/config/yaml/BukkitConstructor.java @@ -0,0 +1,71 @@ +package pw.yumc.YumCore.config.yaml; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConstructor; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.yaml.snakeyaml.error.YAMLException; +import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.nodes.Tag; + +import pw.yumc.YumCore.bukkit.L; + +public class BukkitConstructor extends YamlConstructor { + Map constructor = new HashMap<>(); + + public BukkitConstructor() { + this.yamlConstructors.put(Tag.MAP, new ConstructCustomObject()); + this.loadConstructor(); + } + + private void loadConstructor() { + constructor.put(Location.class.getName(), L.deserialize); + } + + private class ConstructCustomObject extends ConstructYamlMap { + @Override + public Object construct(final Node node) { + if (node.isTwoStepsConstruction()) { + throw new YAMLException("Unexpected referential mapping structure. Node: " + node); + } + + final Map raw = (Map) super.construct(node); + + if (raw.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) { + final Map typed = new LinkedHashMap<>(raw.size()); + for (final Map.Entry entry : raw.entrySet()) { + typed.put(entry.getKey().toString(), entry.getValue()); + } + + // 自定义解析部分 + final String key = raw.get(ConfigurationSerialization.SERIALIZED_TYPE_KEY).toString(); + if (constructor.containsKey(key)) { + try { + return constructor.get(key).invoke(null, raw); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + throw new YAMLException("Could not deserialize object", ex); + } + } + + // Bukkit自动解析 + try { + return ConfigurationSerialization.deserializeObject(typed); + } catch (final IllegalArgumentException ex) { + throw new YAMLException("Could not deserialize object", ex); + } + } + + return raw; + } + + @Override + public void construct2ndStep(final Node node, final Object object) { + throw new YAMLException("Unexpected referential mapping structure. Node: " + node); + } + } +} diff --git a/src/main/java/pw/yumc/YumCore/config/yaml/BukkitRepresenter.java b/src/main/java/pw/yumc/YumCore/config/yaml/BukkitRepresenter.java new file mode 100644 index 0000000..d44a2cf --- /dev/null +++ b/src/main/java/pw/yumc/YumCore/config/yaml/BukkitRepresenter.java @@ -0,0 +1,20 @@ +package pw.yumc.YumCore.config.yaml; + +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlRepresenter; +import org.yaml.snakeyaml.nodes.Node; + +import pw.yumc.YumCore.bukkit.L; + +public class BukkitRepresenter extends YamlRepresenter { + public BukkitRepresenter() { + this.multiRepresenters.put(Location.class, new RepresentLocation()); + } + + public class RepresentLocation extends RepresentMap { + @Override + public Node representData(final Object data) { + return super.representData(L.serialize((Location) data)); + } + } +}