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 21ec7cc..52ad20a 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
@@ -19,7 +19,7 @@ import java.util.stream.Stream;
* @since 4.0.0
*/
public interface ConfigureSection extends Cloneable {
-
+
/**
* Gets the parent section of this section.
*
@@ -136,7 +136,9 @@ public interface ConfigureSection extends Cloneable {
* @param path The path to check.
* @return True if the value is present, false otherwise.
*/
- boolean contains(@NotNull String path);
+ default boolean contains(@NotNull String path) {
+ return get(path) != null;
+ }
/**
* Predicate the value of given path is specific type.
@@ -166,7 +168,10 @@ public interface ConfigureSection extends Cloneable {
* @param path The path to get the {@link List}.
* @return The list if the path exists and is a list, otherwise null.
*/
- @Nullable List> getList(@NotNull String path);
+ default @Nullable List> getList(@NotNull String path) {
+ Object val = get(path);
+ return (val instanceof List>) ? (List>) val : null;
+ }
/**
* Predicate the value of given path is a {@link ConfigureSection}.
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 a5e0363..dde17cf 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
@@ -7,7 +7,6 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.List;
import java.util.Map;
/**
@@ -104,21 +103,11 @@ public abstract class ConfigureSource<
section().set(path, value);
}
- @Override
- public boolean contains(@NotNull String path) {
- return section().contains(path);
- }
-
@Override
public void remove(@NotNull String path) {
section().remove(path);
}
- @Override
- public @Nullable List> getList(@NotNull String path) {
- return section().getList(path);
- }
-
@Override
public @Nullable ConfigureSection getSection(@NotNull String path) {
return section().getSection(path);
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
index 9a11614..347e6db 100644
--- 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
@@ -8,6 +8,14 @@ import java.util.*;
public abstract class MapSection> implements ConfigureSection {
+ public static RawMapSection of() {
+ return new RawMapSection(new LinkedHashMap<>(), null);
+ }
+
+ public static RawMapSection of(@NotNull Map, ?> data) {
+ return new RawMapSection(data, null);
+ }
+
protected final @NotNull Map data;
protected final @Nullable R parent;
@@ -50,11 +58,11 @@ public abstract class MapSection> implements ConfigureSe
}
@UnmodifiableView
- public @NotNull Map original() {
+ public @NotNull Map rawMap() {
Map output = new LinkedHashMap<>();
for (Map.Entry entry : this.data.entrySet()) {
if (entry.getValue() instanceof MapSection>) {
- output.put(entry.getKey(), ((MapSection>) entry.getValue()).original());
+ output.put(entry.getKey(), ((MapSection>) entry.getValue()).rawMap());
} else {
output.put(entry.getKey(), entry.getValue());
}
@@ -104,23 +112,12 @@ public abstract class MapSection> implements ConfigureSe
}
}
- @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);
@@ -160,4 +157,5 @@ public abstract class MapSection> implements ConfigureSe
}
return output;
}
+
}
diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/RawMapSection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/RawMapSection.java
new file mode 100644
index 0000000..f23d5e6
--- /dev/null
+++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/RawMapSection.java
@@ -0,0 +1,25 @@
+package cc.carm.lib.configuration.source.section;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Map;
+
+public class RawMapSection extends MapSection {
+
+ protected RawMapSection(@NotNull Map, ?> raw, @Nullable RawMapSection parent) {
+ super(parent);
+ migrate(raw);
+ }
+
+ @Override
+ public @NotNull RawMapSection self() {
+ return this;
+ }
+
+ @Override
+ protected @NotNull RawMapSection createChild(@NotNull Map, ?> data) {
+ return new RawMapSection(data, this);
+ }
+
+}
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
new file mode 100644
index 0000000..1bae9a4
--- /dev/null
+++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/ShadedSection.java
@@ -0,0 +1,161 @@
+package cc.carm.lib.configuration.source.section;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class ShadedSection extends MapSection {
+ private final ConfigureSection template;
+
+ // 构造方法
+ public ShadedSection(@Nullable ShadedSection parent, @Nullable ConfigureSection template) {
+ super(parent);
+ this.template = template;
+ }
+
+ public ShadedSection(@NotNull Map, ?> data, @Nullable ShadedSection parent, @Nullable ConfigureSection template) {
+ super(parent);
+ this.template = template;
+ migrate(data);
+ }
+
+ @Override
+ public @NotNull ShadedSection self() {
+ return this;
+ }
+
+ @Override
+ protected @NotNull ShadedSection createChild(@NotNull Map, ?> data) {
+ return new ShadedSection(data, this, null);
+ }
+
+ @Override
+ public @Nullable Object get(@NotNull String path) {
+ // 优先从当前section获取
+ Object value = super.get(path);
+ if (value != null) {
+ return wrapNestedValues(path, value);
+ }
+
+ // 当前section无数据时从模板获取
+ if (template != null) {
+ Object templateValue = template.get(path);
+ return wrapTemplateNestedValues(path, templateValue);
+ }
+
+ return null;
+ }
+
+ private Object wrapNestedValues(String path, Object value) {
+ if (value instanceof ConfigureSection) {
+ // 包装子Section,继承当前模板的对应子Section
+ ConfigureSection templateChild = template != null ? template.getSection(path) : null;
+ return new ShadedSection(
+ ((ConfigureSection) value).getValues(false),
+ this,
+ templateChild
+ );
+ } else if (value instanceof List) {
+ // 处理列表中的嵌套结构
+ return processList(path, (List>) value);
+ }
+ return value;
+ }
+
+ private Object wrapTemplateNestedValues(String path, Object templateValue) {
+ if (templateValue instanceof ConfigureSection) {
+ // 模板子Section作为新Section的模板
+ return new ShadedSection(
+ ((ConfigureSection) templateValue).getValues(false),
+ this,
+ ((ConfigureSection) templateValue) // 模板继承
+ );
+ } else if (templateValue instanceof List) {
+ // 处理模板列表中的嵌套结构
+ return processTemplateList(path, (List>) templateValue);
+ }
+ return templateValue;
+ }
+
+ private List