From 1c002ae535cbe61f67e1c8b3a70d16325e55c120 Mon Sep 17 00:00:00 2001 From: carm Date: Thu, 20 Feb 2025 02:50:00 +0800 Subject: [PATCH] feat: Split MapSection and MemorySection --- core/pom.xml | 2 +- demo/pom.xml | 2 +- features/commentable/pom.xml | 2 +- features/file/pom.xml | 2 +- features/section/pom.xml | 2 +- .../source/section/MapSection.java | 146 ++++++++++++++++++ .../source/section/MemorySection.java | 141 ++--------------- features/text/pom.xml | 2 +- features/versioned/pom.xml | 2 +- pom.xml | 2 +- providers/gson/pom.xml | 2 +- .../configuration/source/json/JSONSource.java | 14 +- providers/yaml/pom.xml | 2 +- .../configuration/source/yaml/YAMLSource.java | 16 +- 14 files changed, 184 insertions(+), 153 deletions(-) create mode 100644 features/section/src/main/java/cc/carm/lib/configuration/source/section/MapSection.java diff --git a/core/pom.xml b/core/pom.xml index 3d0c346..611f04b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.2 + 4.0.3 4.0.0 diff --git a/demo/pom.xml b/demo/pom.xml index 6fc3c85..d6dfc7f 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -5,7 +5,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.2 + 4.0.3 4.0.0 diff --git a/features/commentable/pom.xml b/features/commentable/pom.xml index e3d6329..102b7d1 100644 --- a/features/commentable/pom.xml +++ b/features/commentable/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.2 + 4.0.3 ../../pom.xml diff --git a/features/file/pom.xml b/features/file/pom.xml index 3045891..4186f36 100644 --- a/features/file/pom.xml +++ b/features/file/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.2 + 4.0.3 ../../pom.xml diff --git a/features/section/pom.xml b/features/section/pom.xml index 1f41fab..dc878fc 100644 --- a/features/section/pom.xml +++ b/features/section/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.2 + 4.0.3 ../../pom.xml diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/MapSection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/MapSection.java new file mode 100644 index 0000000..8774d7d --- /dev/null +++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/MapSection.java @@ -0,0 +1,146 @@ +package cc.carm.lib.configuration.source.section; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public abstract class MapSection> implements ConfigureSection { + + protected final @NotNull Map data; + protected final @Nullable R parent; + + protected MapSection(@NotNull Map data, @Nullable R parent) { + this.parent = parent; + this.data = new LinkedHashMap<>(); + for (Map.Entry entry : data.entrySet()) { + String key = (entry.getKey() == null) ? "null" : entry.getKey().toString(); + if (entry.getValue() instanceof Map) { + this.data.put(key, createChild((Map) entry.getValue())); + } else if (entry.getValue() instanceof List) { + List list = new ArrayList<>(); + for (Object obj : (List) entry.getValue()) { + if (obj instanceof Map) { + list.add(createChild((Map) obj)); + } else { + list.add(obj); + } + } + this.data.put(key, list); + } else { + this.data.put(key, entry.getValue()); + } + } + } + + public abstract @NotNull R self(); + + protected abstract @NotNull R createChild(@NotNull Map data); + + protected @NotNull R createChild() { + return createChild(new LinkedHashMap<>()); + } + + public @NotNull Map data() { + return this.data; + } + + public @Nullable R parent() { + return this.parent; + } + + /** + * Get the path separator for the section. + * + * @return The path separator + */ + public char pathSeparator() { + return '.'; + } + + @Override + public @NotNull Map getValues(boolean deep) { + return Collections.unmodifiableMap(deep ? mappingValues(this, null, true) : data()); + } + + @Override + public void set(@NotNull String path, @Nullable Object value) { + if (value instanceof Map) value = createChild((Map) value); + + R section = getSectionFor(path); + if (section == this) { + // Even this value is null, we still need to put it in the map + // to ensure that the path is marked as existing. + this.data.put(path, value); + } else { + section.set(childPath(path), value); + } + } + + @Override + public void remove(@NotNull String path) { + R section = getSectionFor(path); + if (section != this) { + section.remove(childPath(path)); + } else { + this.data.remove(path); + } + } + + @Override + public boolean contains(@NotNull String path) { + return get(path) != null; + } + + @Override + public @Nullable Object get(@NotNull String path) { + R section = getSectionFor(path); + return section == this ? data.get(path) : section.get(childPath(path)); + } + + @Override + public @Nullable List getList(@NotNull String path) { + Object val = get(path); + return (val instanceof List) ? (List) val : null; + } + + @Override + public @Nullable ConfigureSection getSection(@NotNull String path) { + Object val = get(path); + return (val instanceof ConfigureSection) ? (ConfigureSection) val : null; + } + + @SuppressWarnings("unchecked") + private R getSectionFor(String path) { + int index = path.indexOf(pathSeparator()); + if (index == -1) return self(); + + String root = path.substring(0, index); + return (R) data().computeIfAbsent(root, k -> createChild()); + } + + private String childPath(String path) { + int index = path.indexOf(pathSeparator()); + return (index == -1) ? path : path.substring(index + 1); + } + + /** + * Map the values of the children of the section to the output map. + * + * @param section The section to map the values from + * @param parent The parent path + * @param deep If the mapping should be deep + */ + protected Map mappingValues(@NotNull MapSection section, @Nullable String parent, boolean deep) { + Map output = new LinkedHashMap<>(); + for (Map.Entry entry : section.data().entrySet()) { + String path = (parent == null ? "" : parent + pathSeparator()) + entry.getKey(); + output.remove(path); + output.put(path, entry.getValue()); + if (deep && entry.getValue() instanceof MapSection) { + output.putAll(mappingValues((MapSection) entry.getValue(), path, true)); + } + } + return output; + } +} diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/MemorySection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/MemorySection.java index b29fb4f..55c33f7 100644 --- a/features/section/src/main/java/cc/carm/lib/configuration/source/section/MemorySection.java +++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/MemorySection.java @@ -3,9 +3,11 @@ package cc.carm.lib.configuration.source.section; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.LinkedHashMap; +import java.util.Map; + +public class MemorySection extends MapSection { -public class MemorySection implements ConfigureSection { public static @NotNull MemorySection root(@NotNull ConfigureSource source) { return new MemorySection(source, new LinkedHashMap<>(), null); @@ -17,147 +19,30 @@ public class MemorySection implements ConfigureSection { } protected final @NotNull ConfigureSource source; - protected final @NotNull Map data; - protected final @Nullable MemorySection parent; - public MemorySection(@NotNull ConfigureSource source, - @NotNull Map data, @Nullable MemorySection parent) { + protected MemorySection(@NotNull ConfigureSource source, + @NotNull Map data, @Nullable MemorySection parent) { + super(data, parent); this.source = source; - this.parent = parent; - this.data = new LinkedHashMap<>(); - for (Map.Entry entry : data.entrySet()) { - String key = (entry.getKey() == null) ? "null" : entry.getKey().toString(); - if (entry.getValue() instanceof Map) { - this.data.put(key, createChild((Map) entry.getValue())); - } else if (entry.getValue() instanceof List) { - List list = new ArrayList<>(); - for (Object obj : (List) entry.getValue()) { - if (obj instanceof Map) { - list.add(createChild((Map) obj)); - } else { - list.add(obj); - } - } - this.data.put(key, list); - } else { - this.data.put(key, entry.getValue()); - } - } - } - - protected @NotNull MemorySection createChild(@NotNull Map data) { - return new MemorySection(source(), data, this); - } - - protected @NotNull MemorySection createChild() { - return createChild(new LinkedHashMap<>()); } public @NotNull ConfigureSource source() { - return this.source; - } - - public @NotNull Map data() { - return this.data; - } - - public @Nullable MemorySection parent() { - return this.parent; + return source; } + @Override public char pathSeparator() { return source.pathSeparator(); } @Override - public @NotNull Map getValues(boolean deep) { - return Collections.unmodifiableMap(deep ? mapChildrenValues(this, null, true) : data()); + public @NotNull MemorySection self() { + return this; } @Override - public void set(@NotNull String path, @Nullable Object value) { - if (value instanceof Map) value = createChild((Map) value); - - MemorySection section = getSectionFor(path); - if (section == this) { - // Even this value is null, we still need to put it in the map - // to ensure that the path is marked as existing. - this.data.put(path, value); - } else { - section.set(childPath(path), value); - } + protected @NotNull MemorySection createChild(@NotNull Map data) { + return new MemorySection(source, data, this); } - @Override - public void remove(@NotNull String path) { - MemorySection section = getSectionFor(path); - if (section != this) { - section.remove(childPath(path)); - } else { - this.data.remove(path); - } - } - - @Override - public boolean contains(@NotNull String path) { - return get(path) != null; - } - - @Override - public @Nullable Object get(@NotNull String path) { - MemorySection section = getSectionFor(path); - return section == this ? data.get(path) : section.get(childPath(path)); - } - - @Override - public @Nullable List getList(@NotNull String path) { - Object val = get(path); - return (val instanceof List) ? (List) val : null; - } - - @Override - public @Nullable ConfigureSection getSection(@NotNull String path) { - Object val = get(path); - return (val instanceof ConfigureSection) ? (ConfigureSection) val : null; - } - - private MemorySection getSectionFor(String path) { - int index = path.indexOf(pathSeparator()); - if (index == -1) return this; - - String root = path.substring(0, index); - Object section = this.data.get(root); - if (section == null) { - section = createChild(); - this.data.put(root, section); - } - - return (MemorySection) section; - } - - private String childPath(String path) { - int index = path.indexOf(pathSeparator()); - return (index == -1) ? path : path.substring(index + 1); - } - - /** - * Map the values of the children of the section to the output map. - * - * @param section The section to map the values from - * @param parent The parent path - * @param deep If the mapping should be deep - */ - protected Map mapChildrenValues(@NotNull MemorySection section, - @Nullable String parent, boolean deep) { - Map output = new LinkedHashMap<>(); - for (Map.Entry entry : section.data().entrySet()) { - String path = (parent == null ? "" : parent + pathSeparator()) + entry.getKey(); - output.remove(path); - output.put(path, entry.getValue()); - if (deep && entry.getValue() instanceof MemorySection) { - output.putAll(mapChildrenValues((MemorySection) entry.getValue(), path, true)); - } - } - return output; - } } diff --git a/features/text/pom.xml b/features/text/pom.xml index f5d5e0e..9a310ea 100644 --- a/features/text/pom.xml +++ b/features/text/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.2 + 4.0.3 ../../pom.xml diff --git a/features/versioned/pom.xml b/features/versioned/pom.xml index e9337d5..531c607 100644 --- a/features/versioned/pom.xml +++ b/features/versioned/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.2 + 4.0.3 ../../pom.xml diff --git a/pom.xml b/pom.xml index c8c0082..90888c5 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ cc.carm.lib easyconfiguration-parent pom - 4.0.2 + 4.0.3 core features/section diff --git a/providers/gson/pom.xml b/providers/gson/pom.xml index 6dea304..24f17e1 100644 --- a/providers/gson/pom.xml +++ b/providers/gson/pom.xml @@ -5,7 +5,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.2 + 4.0.3 ../../pom.xml 4.0.0 diff --git a/providers/gson/src/main/java/cc/carm/lib/configuration/source/json/JSONSource.java b/providers/gson/src/main/java/cc/carm/lib/configuration/source/json/JSONSource.java index 22e8f50..0a0448d 100644 --- a/providers/gson/src/main/java/cc/carm/lib/configuration/source/json/JSONSource.java +++ b/providers/gson/src/main/java/cc/carm/lib/configuration/source/json/JSONSource.java @@ -2,7 +2,7 @@ package cc.carm.lib.configuration.source.json; import cc.carm.lib.configuration.source.ConfigurationHolder; import cc.carm.lib.configuration.source.file.FileConfigSource; -import cc.carm.lib.configuration.source.section.MemorySection; +import cc.carm.lib.configuration.source.section.MapSection; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSerializer; @@ -14,17 +14,17 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; -public class JSONSource extends FileConfigSource, JSONSource> { +public class JSONSource extends FileConfigSource, JSONSource> { public static final @NotNull Gson DEFAULT_GSON = new GsonBuilder() .serializeNulls().disableHtmlEscaping().setPrettyPrinting() .registerTypeAdapter( - MemorySection.class, - (JsonSerializer) (src, t, c) -> c.serialize(src.data()) + MapSection.class, + (JsonSerializer) (src, t, c) -> c.serialize(src.data()) ).create(); protected final @NotNull Gson gson; - protected @Nullable MemorySection rootSection; + protected @Nullable MapSection rootSection; protected JSONSource(@NotNull ConfigurationHolder holder, @NotNull File file, @Nullable String resourcePath) { @@ -58,7 +58,7 @@ public class JSONSource extends FileConfigSource data = fileReader(reader -> gson.fromJson(reader, LinkedHashMap.class)); - this.rootSection = MemorySection.root(this, data); + this.rootSection = MapSection.root(this, data); this.lastUpdateMillis = System.currentTimeMillis(); // 更新时间 } diff --git a/providers/yaml/pom.xml b/providers/yaml/pom.xml index 6d3fd58..a6dd4ad 100644 --- a/providers/yaml/pom.xml +++ b/providers/yaml/pom.xml @@ -6,7 +6,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.2 + 4.0.3 ../../pom.xml diff --git a/providers/yaml/src/main/java/cc/carm/lib/configuration/source/yaml/YAMLSource.java b/providers/yaml/src/main/java/cc/carm/lib/configuration/source/yaml/YAMLSource.java index 6e10a6b..4ce82bf 100644 --- a/providers/yaml/src/main/java/cc/carm/lib/configuration/source/yaml/YAMLSource.java +++ b/providers/yaml/src/main/java/cc/carm/lib/configuration/source/yaml/YAMLSource.java @@ -5,7 +5,7 @@ import cc.carm.lib.configuration.commentable.CommentableOptions; import cc.carm.lib.configuration.source.ConfigurationHolder; import cc.carm.lib.configuration.source.file.FileConfigSource; import cc.carm.lib.configuration.source.section.ConfigureSection; -import cc.carm.lib.configuration.source.section.MemorySection; +import cc.carm.lib.configuration.source.section.MapSection; import cc.carm.lib.yamlcommentupdater.CommentedSection; import cc.carm.lib.yamlcommentupdater.CommentedYAMLWriter; import org.jetbrains.annotations.NotNull; @@ -26,14 +26,14 @@ import java.nio.charset.StandardCharsets; import java.util.*; public class YAMLSource - extends FileConfigSource, YAMLSource> + extends FileConfigSource, YAMLSource> implements CommentedSection { protected final @NotNull YamlConstructor yamlConstructor; protected final @NotNull YamlRepresenter yamlRepresenter; protected final @NotNull Yaml yaml; - protected @Nullable MemorySection rootSection; + protected @Nullable MapSection rootSection; protected YAMLSource(@NotNull ConfigurationHolder holder, @NotNull File file, @Nullable String resourcePath) { @@ -65,7 +65,7 @@ public class YAMLSource } @Override - public @NotNull MemorySection section() { + public @NotNull MapSection section() { return Objects.requireNonNull(this.rootSection, "Root section is not initialized."); } @@ -130,18 +130,18 @@ public class YAMLSource return this.saveToString(section()); } - public @NotNull MemorySection loadFromString(@NotNull String data) throws Exception { + public @NotNull MapSection loadFromString(@NotNull String data) throws Exception { MappingNode mappingNode; try (Reader reader = new UnicodeReader(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)))) { Node rawNode = this.yaml.compose(reader); mappingNode = (MappingNode) rawNode; } - if (mappingNode == null) return MemorySection.root(this); + if (mappingNode == null) return MapSection.root(this); Map map = new LinkedHashMap<>(); this.constructMap(mappingNode, map); - return MemorySection.root(this, map); + return MapSection.root(this, map); } private void constructMap(@NotNull MappingNode mappingNode, @NotNull Map section) { @@ -170,7 +170,7 @@ public class YAMLSource public String serializeValue(@NotNull String key, @NotNull Object value) { Map map = new LinkedHashMap<>(); map.put(key, value); - return saveToString(MemorySection.root(this, map)); + return saveToString(MapSection.root(this, map)); } @Override