From 6f28abebb91ff0b9b222eb2164d3677bfa2242e9 Mon Sep 17 00:00:00 2001 From: carm Date: Tue, 25 Feb 2025 00:04:24 +0800 Subject: [PATCH] feat(section): Add #path and #fullPath for sections --- core/pom.xml | 2 +- .../source/section/ConfigureSection.java | 114 +++++++++++++++++- .../source/section/ConfigureSource.java | 9 +- demo/pom.xml | 2 +- .../demo/tests/model/UserRecord.java | 1 + features/commentable/pom.xml | 2 +- features/file/pom.xml | 2 +- features/section/pom.xml | 2 +- .../source/section/AbstractMapSection.java | 35 ++++-- .../source/section/ImmutableSection.java | 9 +- .../source/section/MemorySection.java | 22 ++-- .../source/section/ShadedSection.java | 9 +- .../source/section/SourcedSection.java | 12 +- features/text/pom.xml | 2 +- features/versioned/pom.xml | 2 +- pom.xml | 8 +- providers/gson/pom.xml | 2 +- providers/yaml/pom.xml | 9 +- .../configuration/source/yaml/YAMLSource.java | 2 +- .../src/test/java/yaml/test/YamlTests.java | 1 - 20 files changed, 181 insertions(+), 66 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 537b053..62c38e2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.6 + 4.0.7 4.0.0 diff --git a/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSection.java b/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSection.java index b232232..a12ded5 100644 --- a/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSection.java +++ b/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSection.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.UnmodifiableView; import java.util.*; import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; @@ -30,6 +31,24 @@ public interface ConfigureSection { @Contract(pure = true) @Nullable ConfigureSection parent(); + /** + * Get the current section's path from {@link #parent()} of this section. + * + * @return The current path of this section, if {@link #isRoot()}, return empty string. + */ + @NotNull String path(); + + /** + * Get the full path of this section. + * + * @return The full path of this section, if {@link #isRoot()}, return empty string. + */ + default @NotNull String fullPath() { + if (parent() == null) return ""; + return (parent().isRoot() ? "" : parent().fullPath() + pathSeparator()) + path(); + } + + /** * Get the path separator for the section. * @@ -44,6 +63,7 @@ public interface ConfigureSection { * * @return True if this section is a root section, false otherwise. */ + @Contract(pure = true) default boolean isRoot() { return parent() == null; } @@ -57,6 +77,15 @@ public interface ConfigureSection { return getValues(false).isEmpty(); } + /** + * Gets the number of keys in this section. + * + * @return Number of keys in this section. + */ + default int size(boolean deep) { + return getKeys(deep).size(); + } + /** * Gets a set containing all keys in this section. *

@@ -238,11 +267,39 @@ public interface ConfigureSection { /** * Creates a new {@link ConfigureSection} with specified values. *

The {@link #parent()} of the new section will be this section. + *

This section will not be saved until {@link #set(String, Object)} is called. + *

If you want to create and use a section and set it to this section, use {@link #computeSection(String)}. * * @param data The data to be used to create section. * @return Newly created section */ - @NotNull ConfigureSection createSection(@NotNull Map data); + @NotNull ConfigureSection createSection(@NotNull String path, @NotNull Map data); + + /** + * Creates a new {@link ConfigureSection} with specified values. + *

The {@link #parent()} of the new section will be this section. + * + * @param data The data to be used to create section. + * @return Newly created section + */ + default @NotNull ConfigureSection createSection(@NotNull String path, @NotNull Consumer> data) { + return createSection(path, () -> { + Map map = new LinkedHashMap<>(); + data.accept(map); + return map; + }); + } + + /** + * Creates a new {@link ConfigureSection} with specified values. + *

The {@link #parent()} of the new section will be this section. + * + * @param data The data to be used to create section. + * @return Newly created section + */ + default @NotNull ConfigureSection createSection(@NotNull String path, @NotNull Supplier> data) { + return createSection(path, data.get()); + } /** * Creates a new empty {@link ConfigureSection}. @@ -250,8 +307,8 @@ public interface ConfigureSection { * * @return Newly created section */ - default @NotNull ConfigureSection createSection() { - return createSection(new LinkedHashMap<>()); + default @NotNull ConfigureSection createSection(@NotNull String path) { + return createSection(path, new LinkedHashMap<>()); } /** @@ -262,17 +319,64 @@ public interface ConfigureSection { * * @param path The path to get the section from. * @return The section at the path, or a new section if it does not exist. - * @see #createSection() + * @see #createSection(String, Map) */ default @NotNull ConfigureSection computeSection(@NotNull String path) { + return computeSection(path, new LinkedHashMap<>()); + } + + /** + * Get or create a section at the given path. + *

+ * Any value previously set at this path will be replaced if it is not a section + * or will be returned if it is an exists {@link ConfigureSection}. + * + * @param path The path to get the section from. + * @return The section at the path, or a new section if it does not exist. + * @see #createSection(String, Map) + */ + default @NotNull ConfigureSection computeSection(@NotNull String path, @NotNull Map data) { ConfigureSection current = getSection(path); if (current == null) { - current = createSection(); + current = createSection(path, data); set(path, current); } return current; } + /** + * Get or create a section at the given path. + *

+ * Any value previously set at this path will be replaced if it is not a section + * or will be returned if it is an exists {@link ConfigureSection}. + * + * @param path The path to get the section from. + * @return The section at the path, or a new section if it does not exist. + * @see #createSection(String, Map) + */ + default @NotNull ConfigureSection computeSection(@NotNull String path, @NotNull Consumer> data) { + return computeSection(path, () -> { + Map map = new LinkedHashMap<>(); + data.accept(map); + return map; + }); + } + + /** + * Get or create a section at the given path. + *

+ * Any value previously set at this path will be replaced if it is not a section + * or will be returned if it is an exists {@link ConfigureSection}. + * + * @param path The path to get the section from. + * @return The section at the path, or a new section if it does not exist. + * @see #createSection(String, Map) + */ + default @NotNull ConfigureSection computeSection(@NotNull String path, @NotNull Supplier> data) { + return computeSection(path, data.get()); + } + + /** * Get the origin value of the path. * diff --git a/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSource.java b/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSource.java index 9260d07..202249d 100644 --- a/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSource.java +++ b/core/src/main/java/cc/carm/lib/configuration/source/section/ConfigureSource.java @@ -92,6 +92,11 @@ public abstract class ConfigureSource< return null; } + @Override + public @NotNull String path() { + return ""; + } + @Override public @NotNull Map getValues(boolean deep) { return section().getValues(deep); @@ -103,8 +108,8 @@ public abstract class ConfigureSource< } @Override - public @NotNull ConfigureSection createSection(@NotNull Map data) { - return section().createSection(data); + public @NotNull ConfigureSection createSection(@NotNull String path, @NotNull Map data) { + return section().createSection(path, data); } @Override diff --git a/demo/pom.xml b/demo/pom.xml index 637e43a..bc89f7d 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -5,7 +5,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.6 + 4.0.7 4.0.0 diff --git a/demo/src/main/java/cc/carm/lib/configuration/demo/tests/model/UserRecord.java b/demo/src/main/java/cc/carm/lib/configuration/demo/tests/model/UserRecord.java index f14240a..b8b0273 100644 --- a/demo/src/main/java/cc/carm/lib/configuration/demo/tests/model/UserRecord.java +++ b/demo/src/main/java/cc/carm/lib/configuration/demo/tests/model/UserRecord.java @@ -36,6 +36,7 @@ public class UserRecord extends AbstractRecord { } public static UserRecord deserialize(ConfigureSection section) { + System.out.println("> Deserializing -> " + section.fullPath()); String name = section.getString("name"); if (name == null) throw new NullPointerException("name is null"); String uuidString = section.getString("info.uuid"); diff --git a/features/commentable/pom.xml b/features/commentable/pom.xml index 502a014..83bdddc 100644 --- a/features/commentable/pom.xml +++ b/features/commentable/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.6 + 4.0.7 ../../pom.xml diff --git a/features/file/pom.xml b/features/file/pom.xml index b88c2a1..e899f77 100644 --- a/features/file/pom.xml +++ b/features/file/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.6 + 4.0.7 ../../pom.xml diff --git a/features/section/pom.xml b/features/section/pom.xml index 07187b9..79f4e45 100644 --- a/features/section/pom.xml +++ b/features/section/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.6 + 4.0.7 ../../pom.xml diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java index e52b929..63a9083 100644 --- a/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java +++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java @@ -10,9 +10,11 @@ public abstract class AbstractMapSection> implem protected final @NotNull Map data; protected final @Nullable R parent; + protected final @NotNull String path; - protected AbstractMapSection(@Nullable R parent) { + protected AbstractMapSection(@Nullable R parent, @NotNull String path) { this.parent = parent; + this.path = path; this.data = new LinkedHashMap<>(); } @@ -20,15 +22,17 @@ public abstract class AbstractMapSection> implem for (Map.Entry entry : data.entrySet()) { String key = (entry.getKey() == null) ? "" : entry.getKey().toString(); if (entry.getValue() instanceof Map) { - this.data.put(key, createSection((Map) entry.getValue())); + this.data.put(key, createSection(key, (Map) entry.getValue())); } else if (entry.getValue() instanceof List) { List list = new ArrayList<>(); + int index = 0; for (Object obj : (List) entry.getValue()) { if (obj instanceof Map) { - list.add(createSection((Map) obj)); + list.add(createSection(key + "[" + index + "]", (Map) obj)); } else { list.add(obj); } + index++; } this.data.put(key, list); } else { @@ -40,11 +44,11 @@ public abstract class AbstractMapSection> implem public abstract @NotNull R self(); @Override - public abstract @NotNull R createSection(@NotNull Map data); + public abstract @NotNull R createSection(@NotNull String path, @NotNull Map data); @Override - public @NotNull R createSection() { - return createSection(new LinkedHashMap<>()); + public @NotNull String path() { + return this.path; } @Override @@ -63,7 +67,12 @@ public abstract class AbstractMapSection> implem @Override public boolean isEmpty() { - return data.isEmpty(); + return this.data.isEmpty(); + } + + @Override + public int size(boolean deep) { + return deep ? getKeys(true).size() : this.data.size(); } @UnmodifiableView @@ -86,12 +95,12 @@ public abstract class AbstractMapSection> implem @Override public @NotNull Map getValues(boolean deep) { - return Collections.unmodifiableMap(deep ? mappingValues(this, null, true) : data()); + return Collections.unmodifiableMap(deep ? mappingValues(this, null, true, String.valueOf(pathSeparator())) : data()); } @Override public void set(@NotNull String path, @Nullable Object value) { - if (value instanceof Map) value = createSection((Map) value); + if (value instanceof Map) value = createSection(path, (Map) value); R section = getSectionFor(path); if (section == this) { @@ -125,7 +134,7 @@ public abstract class AbstractMapSection> implem if (index == -1) return self(); String root = path.substring(0, index); - return (R) data().computeIfAbsent(root, k -> createSection()); + return (R) computeSection(root); } /** @@ -135,14 +144,14 @@ public abstract class AbstractMapSection> implem * @param parent The parent path * @param deep If the mapping should be deep */ - protected Map mappingValues(@NotNull AbstractMapSection section, @Nullable String parent, boolean deep) { + protected static Map mappingValues(@NotNull AbstractMapSection section, @Nullable String parent, boolean deep, String pathSeparator) { Map output = new LinkedHashMap<>(); for (Map.Entry entry : section.data().entrySet()) { - String path = (parent == null ? "" : parent + pathSeparator()) + entry.getKey(); + String path = (parent == null ? "" : parent + pathSeparator) + entry.getKey(); output.remove(path); output.put(path, entry.getValue()); if (deep && entry.getValue() instanceof AbstractMapSection) { - output.putAll(mappingValues((AbstractMapSection) entry.getValue(), path, true)); + output.putAll(mappingValues((AbstractMapSection) entry.getValue(), path, true, pathSeparator)); } } return output; diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/ImmutableSection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/ImmutableSection.java index 10274c5..2d87dfd 100644 --- a/features/section/src/main/java/cc/carm/lib/configuration/source/section/ImmutableSection.java +++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/ImmutableSection.java @@ -32,6 +32,11 @@ public class ImmutableSection implements ConfigureSection { return this.parent; } + @Override + public @NotNull String path() { + return section().path(); + } + private @NotNull ConfigureSection section() { return section; } @@ -52,8 +57,8 @@ public class ImmutableSection implements ConfigureSection { } @Override - public @NotNull ConfigureSection createSection(@NotNull Map data) { - return new ImmutableSection(this, section().createSection(data)); + public @NotNull ImmutableSection createSection(@NotNull String path, @NotNull Map data) { + return new ImmutableSection(this, section().createSection(path, data)); } @Override 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 1dfddfe..c5b495f 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 @@ -11,7 +11,7 @@ import java.util.function.Supplier; public class MemorySection extends AbstractMapSection { public static MemorySection of() { - return of((MemorySection) null); + return of(new LinkedHashMap<>()); } public static MemorySection of(@NotNull Consumer> data) { @@ -23,23 +23,23 @@ public class MemorySection extends AbstractMapSection { } public static MemorySection of(@NotNull Supplier> data) { - return of(data.get(), null); + return of(data.get()); } public static MemorySection of(@NotNull Map data) { - return of(data, null); + return of(data, null, ""); } - public static MemorySection of(@Nullable MemorySection parent) { - return of(new LinkedHashMap<>(), parent); + public static MemorySection of(@Nullable MemorySection parent, @NotNull String path) { + return of(new LinkedHashMap<>(), parent, path); } - public static MemorySection of(@NotNull Map data, @Nullable MemorySection parent) { - return new MemorySection(data, parent); + public static MemorySection of(@NotNull Map data, @Nullable MemorySection parent, @NotNull String path) { + return new MemorySection(data, parent, path); } - public MemorySection(@NotNull Map raw, @Nullable MemorySection parent) { - super(parent); + public MemorySection(@NotNull Map raw, @Nullable MemorySection parent, @NotNull String path) { + super(parent, path); migrate(raw); } @@ -49,8 +49,8 @@ public class MemorySection extends AbstractMapSection { } @Override - public @NotNull MemorySection createSection(@NotNull Map data) { - return new MemorySection(data, this); + public @NotNull MemorySection createSection(@NotNull String path, @NotNull Map data) { + return new MemorySection(data, this, path); } } diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/ShadedSection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/ShadedSection.java index fc5d3aa..6141483 100644 --- a/features/section/src/main/java/cc/carm/lib/configuration/source/section/ShadedSection.java +++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/ShadedSection.java @@ -28,6 +28,11 @@ public class ShadedSection implements ConfigureSection { return this.parent; } + @Override + public @NotNull String path() { + return this.template.path(); + } + @Override public @NotNull @UnmodifiableView Map getValues(boolean deep) { if (source == null) return template.getValues(deep); @@ -95,11 +100,11 @@ public class ShadedSection implements ConfigureSection { } @Override - public @NotNull ConfigureSection createSection(@NotNull Map data) { + public @NotNull ConfigureSection createSection(@NotNull String path, @NotNull Map data) { if (source == null) { return new ShadedSection(this, template, MemorySection.of(data)); } else { - ConfigureSection section = source.createSection(data); + ConfigureSection section = source.computeSection(path, data); return new ShadedSection(this, template, section); } } diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/SourcedSection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/SourcedSection.java index 205fd92..9a91ec2 100644 --- a/features/section/src/main/java/cc/carm/lib/configuration/source/section/SourcedSection.java +++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/SourcedSection.java @@ -9,19 +9,19 @@ import java.util.Map; public class SourcedSection extends AbstractMapSection { public static @NotNull SourcedSection root(@NotNull ConfigureSource source) { - return new SourcedSection(source, new LinkedHashMap<>(), null); + return new SourcedSection(source, new LinkedHashMap<>(), null, ""); } public static @NotNull SourcedSection root(@NotNull ConfigureSource source, @Nullable Map raw) { - return new SourcedSection(source, raw == null ? new LinkedHashMap<>() : raw, null); + return new SourcedSection(source, raw == null ? new LinkedHashMap<>() : raw, null, ""); } protected final @NotNull ConfigureSource source; public SourcedSection(@NotNull ConfigureSource source, - @NotNull Map raw, @Nullable SourcedSection parent) { - super(parent); + @NotNull Map raw, @Nullable SourcedSection parent, @NotNull String path) { + super(parent, path); this.source = source; migrate(raw); } @@ -41,8 +41,8 @@ public class SourcedSection extends AbstractMapSection { } @Override - public @NotNull SourcedSection createSection(@NotNull Map data) { - return new SourcedSection(source(), data, this); + public @NotNull SourcedSection createSection(@NotNull String path, @NotNull Map data) { + return new SourcedSection(source(), data, this, path); } } diff --git a/features/text/pom.xml b/features/text/pom.xml index a92727e..15e94ad 100644 --- a/features/text/pom.xml +++ b/features/text/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.6 + 4.0.7 ../../pom.xml diff --git a/features/versioned/pom.xml b/features/versioned/pom.xml index 7d162b7..4a6c9a3 100644 --- a/features/versioned/pom.xml +++ b/features/versioned/pom.xml @@ -6,7 +6,7 @@ cc.carm.lib easyconfiguration-parent - 4.0.6 + 4.0.7 ../../pom.xml diff --git a/pom.xml b/pom.xml index 0995007..4077842 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ cc.carm.lib easyconfiguration-parent pom - 4.0.6 + 4.0.7 core features/section @@ -89,12 +89,6 @@ https://repo1.maven.org/maven2/ - - github - GitHub Packages - https://maven.pkg.github.com/CarmJos/* - - diff --git a/providers/gson/pom.xml b/providers/gson/pom.xml index 5c42ad0..e2bf4c9 100644 --- a/providers/gson/pom.xml +++ b/providers/gson/pom.xml @@ -5,7 +5,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.6 + 4.0.7 ../../pom.xml 4.0.0 diff --git a/providers/yaml/pom.xml b/providers/yaml/pom.xml index a464508..d1e2bd1 100644 --- a/providers/yaml/pom.xml +++ b/providers/yaml/pom.xml @@ -6,7 +6,7 @@ easyconfiguration-parent cc.carm.lib - 4.0.6 + 4.0.7 ../../pom.xml @@ -29,13 +29,6 @@ compile - - cc.carm.lib - yamlcommentwriter - 1.2.0 - compile - - ${project.parent.groupId} easyconfiguration-feature-file 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 1480f2a..b8ec084 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 @@ -56,7 +56,7 @@ public class YAMLSource @Override protected @NotNull YAMLSource self() { - return null; + return this; } @Override diff --git a/providers/yaml/src/test/java/yaml/test/YamlTests.java b/providers/yaml/src/test/java/yaml/test/YamlTests.java index b140e5b..82bb848 100644 --- a/providers/yaml/src/test/java/yaml/test/YamlTests.java +++ b/providers/yaml/src/test/java/yaml/test/YamlTests.java @@ -9,7 +9,6 @@ import org.junit.Test; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; public class YamlTests {