mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
feat: Implement more sections functions
This commit is contained in:
+14
@@ -5,6 +5,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class RawMapSection extends MapSection<RawMapSection> {
|
||||
|
||||
@@ -12,6 +14,18 @@ public class RawMapSection extends MapSection<RawMapSection> {
|
||||
return of((RawMapSection) null);
|
||||
}
|
||||
|
||||
public static RawMapSection of(@NotNull Consumer<Map<String, Object>> data) {
|
||||
return of(() -> {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
data.accept(map);
|
||||
return map;
|
||||
});
|
||||
}
|
||||
|
||||
public static RawMapSection of(@NotNull Supplier<Map<?, ?>> data) {
|
||||
return of(data.get(), null);
|
||||
}
|
||||
|
||||
public static RawMapSection of(@NotNull Map<?, ?> data) {
|
||||
return of(data, null);
|
||||
}
|
||||
|
||||
+1
-139
@@ -1,144 +1,6 @@
|
||||
package cc.carm.lib.configuration.source.section;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
public class ShadedSection {
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ShadedSection extends MapSection<ShadedSection> {
|
||||
|
||||
private final @Nullable Supplier<@Nullable ConfigureSection> templateSupplier;
|
||||
|
||||
public ShadedSection(@Nullable ShadedSection parent, @Nullable Supplier<ConfigureSection> templateSupplier) {
|
||||
super(parent);
|
||||
this.templateSupplier = templateSupplier;
|
||||
}
|
||||
|
||||
public ShadedSection(@NotNull Map<?, ?> data, @Nullable ShadedSection parent, @Nullable Supplier<ConfigureSection> templateSupplier) {
|
||||
super(parent);
|
||||
this.templateSupplier = templateSupplier;
|
||||
migrate(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ShadedSection self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ShadedSection createChild(@NotNull Map<?, ?> data) {
|
||||
return new ShadedSection(data, this, null);
|
||||
}
|
||||
|
||||
protected @Nullable ConfigureSection template() {
|
||||
return templateSupplier != null ? templateSupplier.get() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected <T> T template(@NotNull Function<ConfigureSection, T> function) {
|
||||
return template(null, function);
|
||||
}
|
||||
|
||||
@Contract("!null, _ -> !null")
|
||||
protected <T> T template(@Nullable T defaults, @NotNull Function<ConfigureSection, T> function) {
|
||||
return Optional.ofNullable(template()).map(function).orElse(defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
// 优先从当前section获取
|
||||
Object value = super.get(path);
|
||||
if (value != null) {
|
||||
return wrapNestedValues(path, value);
|
||||
}
|
||||
|
||||
// 当前section无数据时从模板获取
|
||||
if (templateSupplier != null) {
|
||||
Object templateValue = template((template) -> template.get(path));
|
||||
return wrapTemplateNestedValues(path, templateValue);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object wrapNestedValues(String path, Object value) {
|
||||
if (value instanceof ConfigureSection) {
|
||||
return new ShadedSection(
|
||||
((ConfigureSection) value).getValues(false),
|
||||
this, () -> template(s -> s.getSection(path))
|
||||
);
|
||||
}
|
||||
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<Object> processTemplateList(String path, List<?> list) {
|
||||
List<Object> processed = new ArrayList<>();
|
||||
for (Object item : list) {
|
||||
if (item instanceof ConfigureSection) {
|
||||
processed.add(new ShadedSection(
|
||||
((ConfigureSection) item).getValues(false), this,
|
||||
(ConfigureSection) item
|
||||
));
|
||||
} else {
|
||||
processed.add(item);
|
||||
}
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
// 获取模板值并深度比较
|
||||
Object templateValue = templateSupplier != null ? templateSupplier.get(path) : null;
|
||||
Object processedValue = preprocessValue(path, value);
|
||||
|
||||
if (isDeepEqual(processedValue, templateValue)) {
|
||||
return; // 与模板一致则跳过
|
||||
}
|
||||
|
||||
super.set(path, processedValue);
|
||||
}
|
||||
|
||||
private Object preprocessValue(String path, Object value) {
|
||||
if (value instanceof Map) {
|
||||
return new ShadedSection(
|
||||
(Map<?, ?>) value, this,
|
||||
() -> template(s -> s.getSection(path))
|
||||
);
|
||||
} else if (value instanceof List) {
|
||||
return processList(path, (List<?>) value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private boolean isDeepEqual(Object a, Object b) {
|
||||
if (a == b) return true;
|
||||
if (a == null || b == null) return false;
|
||||
|
||||
if (a instanceof ConfigureSection && b instanceof ConfigureSection) {
|
||||
return ((ConfigureSection) a).getValues(true)
|
||||
.equals(((ConfigureSection) b).getValues(true));
|
||||
}
|
||||
|
||||
return Objects.equals(a, b);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package test.section;
|
||||
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.source.section.RawMapSection;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Lyzen
|
||||
* @date 21/2/2025 下午2:18
|
||||
*/
|
||||
public class ShadeTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ConfigureSection template = RawMapSection.of(data -> {
|
||||
data.put("name", "GentleMan");
|
||||
data.put("age", 12);
|
||||
data.put("gender", "male");
|
||||
Map<String, Object> address = new LinkedHashMap<>();
|
||||
address.put("Hotel", "Nanjing Road 101");
|
||||
address.put("Parent", "BeijingRoad 404");
|
||||
data.put("addresses", address);
|
||||
data.put("cards", Arrays.asList("00000", "11111", "22222"));
|
||||
});
|
||||
|
||||
ConfigureSection source = RawMapSection.of(data -> {
|
||||
data.put("age", 25);
|
||||
Map<String, Object> address = new LinkedHashMap<>();
|
||||
address.put("NewOne", "Guangdong Road 505");
|
||||
data.put("addresses", address);
|
||||
data.put("cards", Arrays.asList("33333", "55555")); // 应当直接覆盖原先的List
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user