mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
feat(section): support ShadedSection
This commit is contained in:
+85
-29
@@ -4,66 +4,122 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.UnmodifiableView;
|
import org.jetbrains.annotations.UnmodifiableView;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.function.Supplier;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ShadedSection implements ConfigureSection {
|
public class ShadedSection implements ConfigureSection {
|
||||||
|
|
||||||
protected final @NotNull ConfigureSection section;
|
protected @NotNull ConfigureSection template;
|
||||||
protected final @NotNull ConfigureSection template;
|
protected @Nullable ConfigureSection source;
|
||||||
|
|
||||||
public ShadedSection(@NotNull ConfigureSection section, @Nullable ConfigureSection template) {
|
public ShadedSection(@NotNull ConfigureSection template, @Nullable ConfigureSection source) {
|
||||||
this.section = section;
|
|
||||||
this.template = template;
|
this.template = template;
|
||||||
|
this.source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable ShadedSection parent() {
|
public @Nullable ConfigureSection parent() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull @UnmodifiableView Map<String, Object> getValues(boolean deep) {
|
public @NotNull @UnmodifiableView Map<String, Object> getValues(boolean deep) {
|
||||||
if (deep) {
|
if (source == null) {
|
||||||
Map<String, Object> values = new LinkedHashMap<>(template.getValues(true));
|
return template.getValues(deep);
|
||||||
values.putAll(section.getValues(true));
|
|
||||||
return values;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 本函数为,当 getValues 时,递归合并 source 和 template
|
||||||
|
return merge(template, source).getValues(deep);
|
||||||
|
}
|
||||||
|
|
||||||
return Collections.emptyMap();
|
private ConfigureSection merge(ConfigureSection templateSection, ConfigureSection valueSection) {
|
||||||
|
MemorySection merged = MemorySection.of();
|
||||||
|
List<String> existingKey = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : valueSection.getValues(false).entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (value instanceof ConfigureSection) {
|
||||||
|
ConfigureSection subSectionFromValue = (ConfigureSection) value;
|
||||||
|
ConfigureSection subSectionFromTemplate = (ConfigureSection) templateSection.get(key);
|
||||||
|
if(subSectionFromTemplate == null) {
|
||||||
|
merged.set(key, value);
|
||||||
|
} else {
|
||||||
|
merged.set(key, merge(subSectionFromTemplate, subSectionFromValue));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
merged.set(key, value);
|
||||||
|
}
|
||||||
|
existingKey.add(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : templateSection.getValues(false).entrySet()) {
|
||||||
|
if (existingKey.contains(entry.getKey())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
merged.set(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(@NotNull String path, @Nullable Object value) {
|
public void set(@NotNull String path, @Nullable Object value) {
|
||||||
|
|
||||||
if (value instanceof ConfigureSection) {
|
if (value instanceof ConfigureSection) {
|
||||||
|
ConfigureSection targetSection = (ConfigureSection) value;
|
||||||
|
for (Map.Entry<String, Object> entry : targetSection.getValues(true).entrySet()) {
|
||||||
|
set(path+pathSeparator()+entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (Objects.equals(get(path), value)){
|
||||||
|
remove(path);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
Optional.ofNullable(source).ifPresent(source -> source.set(path, value));
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Object get(@NotNull String path) {
|
|
||||||
|
|
||||||
if (section.contains(path)) {
|
|
||||||
|
|
||||||
|
|
||||||
return section.get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(@NotNull String path) {
|
public void remove(@NotNull String path) {
|
||||||
section.remove(path);
|
Optional.ofNullable(source).ifPresent(source -> source.remove(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ConfigureSection createSection(@NotNull Map<?, ?> data) {
|
public @NotNull ConfigureSection createSection(@NotNull Map<?, ?> data) {
|
||||||
return null;
|
throw new UnsupportedOperationException("not supported yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Object get(@NotNull String path) {
|
||||||
|
if (source == null) {
|
||||||
|
return getFromTemplate(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object value = source.get(path);
|
||||||
|
if (value == null) {
|
||||||
|
return getFromTemplate(path);
|
||||||
|
}
|
||||||
|
if (value instanceof ConfigureSection) {
|
||||||
|
ConfigureSection templateSection = (ConfigureSection) template.get(path);
|
||||||
|
if (templateSection == null) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return new ShadedSection(templateSection, (ConfigureSection) value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Object getFromTemplate(@NotNull String path) {
|
||||||
|
Object value = template.get(path);
|
||||||
|
if (value instanceof ConfigureSection) {
|
||||||
|
return new ShadedSection((ConfigureSection) value, null);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigureSection getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package test.section;
|
|||||||
|
|
||||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
import cc.carm.lib.configuration.source.section.MemorySection;
|
import cc.carm.lib.configuration.source.section.MemorySection;
|
||||||
|
import cc.carm.lib.configuration.source.section.ShadedSection;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -22,7 +23,10 @@ public class ShadeTest {
|
|||||||
data.put("gender", "male");
|
data.put("gender", "male");
|
||||||
Map<String, Object> address = new LinkedHashMap<>();
|
Map<String, Object> address = new LinkedHashMap<>();
|
||||||
address.put("Hotel", "Nanjing Road 101");
|
address.put("Hotel", "Nanjing Road 101");
|
||||||
address.put("Parent", "BeijingRoad 404");
|
address.put("Store", "Beijing Road 404");
|
||||||
|
Map<String, Object> mapInside = new LinkedHashMap<>();
|
||||||
|
mapInside.put("InsideKeyExample", "InsideValueExample");
|
||||||
|
address.put("Inside", mapInside);
|
||||||
data.put("addresses", address);
|
data.put("addresses", address);
|
||||||
data.put("cards", Arrays.asList("00000", "11111", "22222"));
|
data.put("cards", Arrays.asList("00000", "11111", "22222"));
|
||||||
});
|
});
|
||||||
@@ -31,13 +35,43 @@ public class ShadeTest {
|
|||||||
Map<String, Object> address = new LinkedHashMap<>();
|
Map<String, Object> address = new LinkedHashMap<>();
|
||||||
address.put("NewOne", "Guangdong Road 505");
|
address.put("NewOne", "Guangdong Road 505");
|
||||||
data.put("addresses", address);
|
data.put("addresses", address);
|
||||||
|
Map<String, Object> mapInside = new LinkedHashMap<>();
|
||||||
|
mapInside.put("AnotherInsideKey", "AnotherInsideValue");
|
||||||
|
address.put("Inside", mapInside);
|
||||||
data.put("cards", Arrays.asList("33333", "55555")); // 应当直接覆盖原先的List
|
data.put("cards", Arrays.asList("33333", "55555")); // 应当直接覆盖原先的List
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ShadedSection root = new ShadedSection(template, source);
|
||||||
|
System.out.println("age: "+root.get("age"));
|
||||||
|
System.out.println("addresses: ");
|
||||||
|
for (Map.Entry<String, Object> entry : root.getSection("addresses").getValues(false).entrySet()) {
|
||||||
|
System.out.println(" "+entry.getKey()+": "+entry.getValue());
|
||||||
|
if (entry.getValue() instanceof ConfigureSection) {
|
||||||
|
for(Map.Entry<String, Object> inner : ((ConfigureSection) entry.getValue()).getValues(false).entrySet()) {
|
||||||
|
System.out.println(" "+inner.getKey()+": "+inner.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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<String, Object> entry : root.getSection("addresses").getValues(true).entrySet()) {
|
||||||
|
System.out.println(" "+entry.getKey()+": "+entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\n----------------------\n");
|
||||||
|
|
||||||
|
root.set("addresses", MemorySection.of(map->{
|
||||||
|
map.put("Hotel", "Nanjing Road 101");
|
||||||
|
map.put("Store", "Beijing Road banned");
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : source.getValues(true).entrySet()) {
|
||||||
|
System.out.println(" "+entry.getKey()+": "+entry.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user