From 3e221740bcebdda4a6076e19c6adc5ebac5b612a Mon Sep 17 00:00:00 2001 From: carm Date: Sat, 22 Feb 2025 09:55:28 +0800 Subject: [PATCH] feat(section): Implement shaded sections --- .../source/section/ShadedSection.java | 48 +++++++++++-------- .../src/test/java/test/section/ShadeTest.java | 18 +++---- 2 files changed, 38 insertions(+), 28 deletions(-) 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 1e21cf3..bd16ab3 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 @@ -5,36 +5,48 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import java.util.*; -import java.util.function.Supplier; public class ShadedSection implements ConfigureSection { + public static ShadedSection create(@NotNull ConfigureSection template, @Nullable ConfigureSection source) { + return new ShadedSection(null, template, source); + } + + protected final @Nullable ShadedSection parent; protected @NotNull ConfigureSection template; protected @Nullable ConfigureSection source; - public ShadedSection(@NotNull ConfigureSection template, @Nullable ConfigureSection source) { + public ShadedSection(@Nullable ShadedSection parent, + @NotNull ConfigureSection template, @Nullable ConfigureSection source) { + this.parent = parent; this.template = template; this.source = source; } @Override public @Nullable ConfigureSection parent() { - return null; + return this.parent; } @Override public @NotNull @UnmodifiableView Map getValues(boolean deep) { - if (source == null) { - return template.getValues(deep); - } - + if (source == null) return template.getValues(deep); // 本函数为,当 getValues 时,递归合并 source 和 template return merge(template, source).getValues(deep); } + @Override + public @NotNull @UnmodifiableView Set getKeys(boolean deep) { + Set keys = new HashSet<>(template.getKeys(deep)); + if (source != null) { + keys.addAll(source.getKeys(deep)); + } + return Collections.unmodifiableSet(keys); + } + private ConfigureSection merge(ConfigureSection templateSection, ConfigureSection valueSection) { MemorySection merged = MemorySection.of(); - List existingKey = new ArrayList<>(); + Set existingKey = new HashSet<>(); for (Map.Entry entry : valueSection.getValues(false).entrySet()) { String key = entry.getKey(); @@ -42,7 +54,7 @@ public class ShadedSection implements ConfigureSection { if (value instanceof ConfigureSection) { ConfigureSection subSectionFromValue = (ConfigureSection) value; ConfigureSection subSectionFromTemplate = (ConfigureSection) templateSection.get(key); - if(subSectionFromTemplate == null) { + if (subSectionFromTemplate == null) { merged.set(key, value); } else { merged.set(key, merge(subSectionFromTemplate, subSectionFromValue)); @@ -54,9 +66,7 @@ public class ShadedSection implements ConfigureSection { } for (Map.Entry entry : templateSection.getValues(false).entrySet()) { - if (existingKey.contains(entry.getKey())) { - continue; - } + if (existingKey.contains(entry.getKey())) continue; merged.set(entry.getKey(), entry.getValue()); } @@ -68,20 +78,20 @@ public class ShadedSection implements ConfigureSection { if (value instanceof ConfigureSection) { ConfigureSection targetSection = (ConfigureSection) value; for (Map.Entry entry : targetSection.getValues(true).entrySet()) { - set(path+pathSeparator()+entry.getKey(), entry.getValue()); + set(path + pathSeparator() + entry.getKey(), entry.getValue()); } return; - } else if (Objects.equals(get(path), value)){ + } else if (Objects.equals(get(path), value)) { remove(path); return; } - Optional.ofNullable(source).ifPresent(source -> source.set(path, value)); + Optional.ofNullable(source).ifPresent(s -> s.set(path, value)); } @Override public void remove(@NotNull String path) { - Optional.ofNullable(source).ifPresent(source -> source.remove(path)); + Optional.ofNullable(source).ifPresent(s -> s.remove(path)); } @Override @@ -104,7 +114,7 @@ public class ShadedSection implements ConfigureSection { if (templateSection == null) { return value; } else { - return new ShadedSection(templateSection, (ConfigureSection) value); + return new ShadedSection(this, templateSection, (ConfigureSection) value); } } return value; @@ -113,13 +123,13 @@ public class ShadedSection implements ConfigureSection { public @Nullable Object getFromTemplate(@NotNull String path) { Object value = template.get(path); if (value instanceof ConfigureSection) { - return new ShadedSection((ConfigureSection) value, null); + return new ShadedSection(this, (ConfigureSection) value, null); } else { return value; } } - public ConfigureSection getSource() { + public @Nullable ConfigureSection getSource() { return source; } } \ No newline at end of file diff --git a/features/section/src/test/java/test/section/ShadeTest.java b/features/section/src/test/java/test/section/ShadeTest.java index acfe9b9..39f6a58 100644 --- a/features/section/src/test/java/test/section/ShadeTest.java +++ b/features/section/src/test/java/test/section/ShadeTest.java @@ -41,36 +41,36 @@ public class ShadeTest { data.put("cards", Arrays.asList("33333", "55555")); // 应当直接覆盖原先的List }); - ShadedSection root = new ShadedSection(template, source); - System.out.println("age: "+root.get("age")); + ShadedSection root = new ShadedSection(null, template, source); + System.out.println("age: " + root.get("age")); System.out.println("addresses: "); for (Map.Entry entry : root.getSection("addresses").getValues(false).entrySet()) { - System.out.println(" "+entry.getKey()+": "+entry.getValue()); + System.out.println(" " + entry.getKey() + ": " + entry.getValue()); if (entry.getValue() instanceof ConfigureSection) { - for(Map.Entry inner : ((ConfigureSection) entry.getValue()).getValues(false).entrySet()) { - System.out.println(" "+inner.getKey()+": "+inner.getValue()); + for (Map.Entry inner : ((ConfigureSection) entry.getValue()).getValues(false).entrySet()) { + System.out.println(" " + inner.getKey() + ": " + inner.getValue()); } } } - System.out.println("cards: "+root.getList("cards")); + System.out.println("cards: " + root.getList("cards")); System.out.println("\n----------------------\n"); System.out.println("Deep Search Test"); System.out.println("addresses: "); for (Map.Entry entry : root.getSection("addresses").getValues(true).entrySet()) { - System.out.println(" "+entry.getKey()+": "+entry.getValue()); + System.out.println(" " + entry.getKey() + ": " + entry.getValue()); } System.out.println("\n----------------------\n"); - root.set("addresses", MemorySection.of(map->{ + root.set("addresses", MemorySection.of(map -> { map.put("Hotel", "Nanjing Road 101"); map.put("Store", "Beijing Road banned"); })); for (Map.Entry entry : source.getValues(true).entrySet()) { - System.out.println(" "+entry.getKey()+": "+entry.getValue()); + System.out.println(" " + entry.getKey() + ": " + entry.getValue()); } }