mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 10:38:19 +08:00
feat(section): Implement more sections
This commit is contained in:
@@ -235,6 +235,44 @@ public interface ConfigureSection {
|
|||||||
return (val instanceof ConfigureSection) ? (ConfigureSection) val : null;
|
return (val instanceof ConfigureSection) ? (ConfigureSection) val : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link ConfigureSection} with specified values.
|
||||||
|
* <p> 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
|
||||||
|
*/
|
||||||
|
@NotNull ConfigureSection createSection(@NotNull Map<?, ?> data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty {@link ConfigureSection}.
|
||||||
|
* <p> The {@link #parent()} of the new section will be this section.
|
||||||
|
*
|
||||||
|
* @return Newly created section
|
||||||
|
*/
|
||||||
|
default @NotNull ConfigureSection createSection() {
|
||||||
|
return createSection(new LinkedHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create a section at the given path.
|
||||||
|
* <p>
|
||||||
|
* 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()
|
||||||
|
*/
|
||||||
|
default @NotNull ConfigureSection computeSection(@NotNull String path) {
|
||||||
|
ConfigureSection current = getSection(path);
|
||||||
|
if (current == null) {
|
||||||
|
current = createSection();
|
||||||
|
set(path, current);
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the origin value of the path.
|
* Get the origin value of the path.
|
||||||
*
|
*
|
||||||
|
|||||||
+17
-15
@@ -6,26 +6,26 @@ import org.jetbrains.annotations.UnmodifiableView;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public abstract class MapSection<R extends MapSection<R>> implements ConfigureSection {
|
public abstract class AbstractMapSection<R extends AbstractMapSection<R>> implements ConfigureSection {
|
||||||
|
|
||||||
protected final @NotNull Map<String, Object> data;
|
protected final @NotNull Map<String, Object> data;
|
||||||
protected final @Nullable R parent;
|
protected final @Nullable R parent;
|
||||||
|
|
||||||
protected MapSection(@Nullable R parent) {
|
protected AbstractMapSection(@Nullable R parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.data = new LinkedHashMap<>();
|
this.data = new LinkedHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void migrate(Map<?, ?> data) {
|
public void migrate(Map<?, ?> data) {
|
||||||
for (Map.Entry<?, ?> entry : data.entrySet()) {
|
for (Map.Entry<?, ?> entry : data.entrySet()) {
|
||||||
String key = (entry.getKey() == null) ? "null" : entry.getKey().toString();
|
String key = (entry.getKey() == null) ? "" : entry.getKey().toString();
|
||||||
if (entry.getValue() instanceof Map) {
|
if (entry.getValue() instanceof Map) {
|
||||||
this.data.put(key, createChild((Map<?, ?>) entry.getValue()));
|
this.data.put(key, createSection((Map<?, ?>) entry.getValue()));
|
||||||
} else if (entry.getValue() instanceof List) {
|
} else if (entry.getValue() instanceof List) {
|
||||||
List<Object> list = new ArrayList<>();
|
List<Object> list = new ArrayList<>();
|
||||||
for (Object obj : (List<?>) entry.getValue()) {
|
for (Object obj : (List<?>) entry.getValue()) {
|
||||||
if (obj instanceof Map) {
|
if (obj instanceof Map) {
|
||||||
list.add(createChild((Map<?, ?>) obj));
|
list.add(createSection((Map<?, ?>) obj));
|
||||||
} else {
|
} else {
|
||||||
list.add(obj);
|
list.add(obj);
|
||||||
}
|
}
|
||||||
@@ -39,10 +39,12 @@ public abstract class MapSection<R extends MapSection<R>> implements ConfigureSe
|
|||||||
|
|
||||||
public abstract @NotNull R self();
|
public abstract @NotNull R self();
|
||||||
|
|
||||||
protected abstract @NotNull R createChild(@NotNull Map<?, ?> data);
|
@Override
|
||||||
|
public abstract @NotNull R createSection(@NotNull Map<?, ?> data);
|
||||||
|
|
||||||
protected @NotNull R createChild() {
|
@Override
|
||||||
return createChild(new LinkedHashMap<>());
|
public @NotNull R createSection() {
|
||||||
|
return createSection(new LinkedHashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -68,8 +70,8 @@ public abstract class MapSection<R extends MapSection<R>> implements ConfigureSe
|
|||||||
public @NotNull Map<String, Object> rawMap() {
|
public @NotNull Map<String, Object> rawMap() {
|
||||||
Map<String, Object> output = new LinkedHashMap<>();
|
Map<String, Object> output = new LinkedHashMap<>();
|
||||||
for (Map.Entry<String, Object> entry : this.data.entrySet()) {
|
for (Map.Entry<String, Object> entry : this.data.entrySet()) {
|
||||||
if (entry.getValue() instanceof MapSection<?>) {
|
if (entry.getValue() instanceof AbstractMapSection<?>) {
|
||||||
output.put(entry.getKey(), ((MapSection<?>) entry.getValue()).rawMap());
|
output.put(entry.getKey(), ((AbstractMapSection<?>) entry.getValue()).rawMap());
|
||||||
} else {
|
} else {
|
||||||
output.put(entry.getKey(), entry.getValue());
|
output.put(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
@@ -89,7 +91,7 @@ public abstract class MapSection<R extends MapSection<R>> implements ConfigureSe
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(@NotNull String path, @Nullable Object value) {
|
public void set(@NotNull String path, @Nullable Object value) {
|
||||||
if (value instanceof Map) value = createChild((Map<?, ?>) value);
|
if (value instanceof Map) value = createSection((Map<?, ?>) value);
|
||||||
|
|
||||||
R section = getSectionFor(path);
|
R section = getSectionFor(path);
|
||||||
if (section == this) {
|
if (section == this) {
|
||||||
@@ -123,7 +125,7 @@ public abstract class MapSection<R extends MapSection<R>> implements ConfigureSe
|
|||||||
if (index == -1) return self();
|
if (index == -1) return self();
|
||||||
|
|
||||||
String root = path.substring(0, index);
|
String root = path.substring(0, index);
|
||||||
return (R) data().computeIfAbsent(root, k -> createChild());
|
return (R) data().computeIfAbsent(root, k -> createSection());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,14 +135,14 @@ public abstract class MapSection<R extends MapSection<R>> implements ConfigureSe
|
|||||||
* @param parent The parent path
|
* @param parent The parent path
|
||||||
* @param deep If the mapping should be deep
|
* @param deep If the mapping should be deep
|
||||||
*/
|
*/
|
||||||
protected Map<String, Object> mappingValues(@NotNull MapSection<?> section, @Nullable String parent, boolean deep) {
|
protected Map<String, Object> mappingValues(@NotNull AbstractMapSection<?> section, @Nullable String parent, boolean deep) {
|
||||||
Map<String, Object> output = new LinkedHashMap<>();
|
Map<String, Object> output = new LinkedHashMap<>();
|
||||||
for (Map.Entry<String, Object> entry : section.data().entrySet()) {
|
for (Map.Entry<String, Object> entry : section.data().entrySet()) {
|
||||||
String path = (parent == null ? "" : parent + pathSeparator()) + entry.getKey();
|
String path = (parent == null ? "" : parent + pathSeparator()) + entry.getKey();
|
||||||
output.remove(path);
|
output.remove(path);
|
||||||
output.put(path, entry.getValue());
|
output.put(path, entry.getValue());
|
||||||
if (deep && entry.getValue() instanceof MapSection<?>) {
|
if (deep && entry.getValue() instanceof AbstractMapSection<?>) {
|
||||||
output.putAll(mappingValues((MapSection<?>) entry.getValue(), path, true));
|
output.putAll(mappingValues((AbstractMapSection<?>) entry.getValue(), path, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
+372
@@ -0,0 +1,372 @@
|
|||||||
|
package cc.carm.lib.configuration.source.section;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.function.DataFunction;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.UnmodifiableView;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ImmutableSection implements ConfigureSection {
|
||||||
|
|
||||||
|
public static ImmutableSection of(@NotNull ConfigureSection section) {
|
||||||
|
if (section instanceof ImmutableSection) {
|
||||||
|
return (ImmutableSection) section;
|
||||||
|
} else return new ImmutableSection(null, section);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final @Nullable ImmutableSection parent;
|
||||||
|
protected final @NotNull ConfigureSection section;
|
||||||
|
|
||||||
|
private ImmutableSection(@Nullable ImmutableSection parent, @NotNull ConfigureSection section) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.section = section;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ImmutableSection parent() {
|
||||||
|
return this.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull ConfigureSection section() {
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @UnmodifiableView Map<String, Object> getValues(boolean deep) {
|
||||||
|
return section().getValues(deep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(@NotNull String path, @Nullable Object value) {
|
||||||
|
throw new IllegalStateException("This section is not modifiable!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(@NotNull String path) {
|
||||||
|
throw new IllegalStateException("This section is not modifiable!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfigureSection createSection(@NotNull Map<?, ?> data) {
|
||||||
|
return new ImmutableSection(this, section().createSection(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Object get(@NotNull String path) {
|
||||||
|
Object value = section().get(path);
|
||||||
|
if (value instanceof ConfigureSection && !(value instanceof ImmutableSection)) {
|
||||||
|
return new ImmutableSection(this, (ConfigureSection) value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ConfigureSection getSection(@NotNull String path) {
|
||||||
|
ConfigureSection get = section().getSection(path);
|
||||||
|
if (get != null && !(get instanceof ImmutableSection)) {
|
||||||
|
return new ImmutableSection(this, get);
|
||||||
|
}
|
||||||
|
return get;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char pathSeparator() {
|
||||||
|
return section().pathSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRoot() {
|
||||||
|
return section().isRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return section().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @UnmodifiableView Set<String> getKeys(boolean deep) {
|
||||||
|
return section().getKeys(deep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @UnmodifiableView Set<String> keys() {
|
||||||
|
return section().keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @UnmodifiableView Map<String, Object> values() {
|
||||||
|
return section().values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<Map.Entry<String, Object>> stream() {
|
||||||
|
return section().stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEach(@NotNull BiConsumer<String, Object> action) {
|
||||||
|
section().forEach(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(@NotNull String path) {
|
||||||
|
return section().contains(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsValue(@NotNull String path) {
|
||||||
|
return section().containsValue(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> boolean isType(@NotNull String path, @NotNull Class<T> typeClass) {
|
||||||
|
return section().isType(path, typeClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isList(@NotNull String path) {
|
||||||
|
return section().isList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<?> getList(@NotNull String path) {
|
||||||
|
return section().getList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSection(@NotNull String path) {
|
||||||
|
return section().isSection(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> @Nullable T get(@NotNull String path, @NotNull Class<T> type) {
|
||||||
|
return section().get(path, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> @Nullable T get(@NotNull String path, @NotNull DataFunction<@Nullable Object, T> parser) {
|
||||||
|
return section().get(path, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> @Nullable T get(@NotNull String path, @Nullable T defaults, @NotNull Class<T> clazz) {
|
||||||
|
return section().get(path, defaults, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> @Nullable T get(@NotNull String path, @Nullable T defaultValue, @NotNull DataFunction<Object, T> parser) {
|
||||||
|
return section().get(path, defaultValue, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBoolean(@NotNull String path) {
|
||||||
|
return section().isBoolean(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(@NotNull String path) {
|
||||||
|
return section().getBoolean(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Boolean getBoolean(@NotNull String path, @Nullable Boolean def) {
|
||||||
|
return section().getBoolean(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Boolean isByte(@NotNull String path) {
|
||||||
|
return section().isByte(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Byte getByte(@NotNull String path) {
|
||||||
|
return section().getByte(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Byte getByte(@NotNull String path, @Nullable Byte def) {
|
||||||
|
return section().getByte(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShort(@NotNull String path) {
|
||||||
|
return section().isShort(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Short getShort(@NotNull String path) {
|
||||||
|
return section().getShort(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Short getShort(@NotNull String path, @Nullable Short def) {
|
||||||
|
return section().getShort(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInt(@NotNull String path) {
|
||||||
|
return section().isInt(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Integer getInt(@NotNull String path) {
|
||||||
|
return section().getInt(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Integer getInt(@NotNull String path, @Nullable Integer def) {
|
||||||
|
return section().getInt(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLong(@NotNull String path) {
|
||||||
|
return section().isLong(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Long getLong(@NotNull String path) {
|
||||||
|
return section().getLong(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Long getLong(@NotNull String path, @Nullable Long def) {
|
||||||
|
return section().getLong(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFloat(@NotNull String path) {
|
||||||
|
return section().isFloat(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Float getFloat(@NotNull String path) {
|
||||||
|
return section().getFloat(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Float getFloat(@NotNull String path, @Nullable Float def) {
|
||||||
|
return section().getFloat(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDouble(@NotNull String path) {
|
||||||
|
return section().isDouble(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Double getDouble(@NotNull String path) {
|
||||||
|
return section().getDouble(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Double getDouble(@NotNull String path, @Nullable Double def) {
|
||||||
|
return section().getDouble(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChar(@NotNull String path) {
|
||||||
|
return section().isChar(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Character getChar(@NotNull String path) {
|
||||||
|
return section().getChar(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Character getChar(@NotNull String path, @Nullable Character def) {
|
||||||
|
return section().getChar(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isString(@NotNull String path) {
|
||||||
|
return section().isString(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getString(@NotNull String path) {
|
||||||
|
return section().getString(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getString(@NotNull String path, @Nullable String def) {
|
||||||
|
return section().getString(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <V> List<V> getList(@NotNull String path, @NotNull DataFunction<Object, V> parser) {
|
||||||
|
return section().getList(path, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<String> getStringList(@NotNull String path) {
|
||||||
|
return section().getStringList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Integer> getIntegerList(@NotNull String path) {
|
||||||
|
return section().getIntegerList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Long> getLongList(@NotNull String path) {
|
||||||
|
return section().getLongList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Double> getDoubleList(@NotNull String path) {
|
||||||
|
return section().getDoubleList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Float> getFloatList(@NotNull String path) {
|
||||||
|
return section().getFloatList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Byte> getByteList(@NotNull String path) {
|
||||||
|
return section().getByteList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Character> getCharList(@NotNull String path) {
|
||||||
|
return section().getCharList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T, C extends Collection<T>> @NotNull C getCollection(@NotNull String path, @NotNull Supplier<C> constructor, @NotNull DataFunction<Object, T> parser) {
|
||||||
|
return section().getCollection(path, constructor, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Stream<?> stream(@NotNull String path) {
|
||||||
|
return section().stream(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> Stream<T> stream(@NotNull String path, @NotNull Function<Object, T> parser) {
|
||||||
|
return section().stream(path, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String childPath(String path) {
|
||||||
|
return section().childPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return section.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return Objects.equals(section, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+29
-21
@@ -5,44 +5,52 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class MemorySection extends MapSection<MemorySection> {
|
public class MemorySection extends AbstractMapSection<MemorySection> {
|
||||||
|
|
||||||
public static @NotNull MemorySection root(@NotNull ConfigureSource<? extends MemorySection, ?, ?> source) {
|
public static MemorySection of() {
|
||||||
return new MemorySection(source, new LinkedHashMap<>(), null);
|
return of((MemorySection) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull MemorySection root(@NotNull ConfigureSource<? extends MemorySection, ?, ?> source,
|
public static MemorySection of(@NotNull Consumer<Map<String, Object>> data) {
|
||||||
@Nullable Map<?, ?> raw) {
|
return of(() -> {
|
||||||
return new MemorySection(source, raw == null ? new LinkedHashMap<>() : raw, null);
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
data.accept(map);
|
||||||
|
return map;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final @NotNull ConfigureSource<? extends MemorySection, ?, ?> source;
|
public static MemorySection of(@NotNull Supplier<Map<?, ?>> data) {
|
||||||
|
return of(data.get(), null);
|
||||||
|
}
|
||||||
|
|
||||||
protected MemorySection(@NotNull ConfigureSource<? extends MemorySection, ?, ?> source,
|
public static MemorySection of(@NotNull Map<?, ?> data) {
|
||||||
@NotNull Map<?, ?> raw, @Nullable MemorySection parent) {
|
return of(data, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MemorySection of(@Nullable MemorySection parent) {
|
||||||
|
return of(new LinkedHashMap<>(), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MemorySection of(@NotNull Map<?, ?> data, @Nullable MemorySection parent) {
|
||||||
|
return new MemorySection(data, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemorySection(@NotNull Map<?, ?> raw, @Nullable MemorySection parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
this.source = source;
|
|
||||||
migrate(raw);
|
migrate(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull ConfigureSource<? extends MemorySection, ?, ?> source() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char pathSeparator() {
|
|
||||||
return source().pathSeparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull MemorySection self() {
|
public @NotNull MemorySection self() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @NotNull MemorySection createChild(@NotNull Map<?, ?> data) {
|
public @NotNull MemorySection createSection(@NotNull Map<?, ?> data) {
|
||||||
return new MemorySection(source(), data, this);
|
return new MemorySection(data, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-56
@@ -1,56 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.source.section;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
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> {
|
|
||||||
|
|
||||||
public static RawMapSection of() {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RawMapSection of(@Nullable RawMapSection parent) {
|
|
||||||
return of(new LinkedHashMap<>(), parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RawMapSection of(@NotNull Map<?, ?> data, @Nullable RawMapSection parent) {
|
|
||||||
return new RawMapSection(data, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+16
-8
@@ -5,30 +5,33 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.annotations.UnmodifiableView;
|
import org.jetbrains.annotations.UnmodifiableView;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ShadedSection implements ConfigureSection {
|
public class ShadedSection implements ConfigureSection {
|
||||||
|
|
||||||
|
|
||||||
protected final @Nullable ShadedSection parent;
|
|
||||||
protected final @NotNull ConfigureSection section;
|
protected final @NotNull ConfigureSection section;
|
||||||
protected final @Nullable ConfigureSection template;
|
protected final @NotNull ConfigureSection template;
|
||||||
|
|
||||||
public ShadedSection(@NotNull ShadedSection parent,
|
public ShadedSection(@NotNull ConfigureSection section, @Nullable ConfigureSection template) {
|
||||||
@NotNull ConfigureSection section, @Nullable ConfigureSection template) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.section = section;
|
this.section = section;
|
||||||
this.template = template;
|
this.template = template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable ShadedSection parent() {
|
public @Nullable ShadedSection parent() {
|
||||||
return this.parent;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull @UnmodifiableView Map<String, Object> getValues(boolean deep) {
|
public @NotNull @UnmodifiableView Map<String, Object> getValues(boolean deep) {
|
||||||
|
if (deep) {
|
||||||
|
Map<String, Object> values = new LinkedHashMap<>(template.getValues(true));
|
||||||
|
values.putAll(section.getValues(true));
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,4 +61,9 @@ public class ShadedSection implements ConfigureSection {
|
|||||||
section.remove(path);
|
section.remove(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfigureSection createSection(@NotNull Map<?, ?> data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
package cc.carm.lib.configuration.source.section;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SourcedSection extends AbstractMapSection<SourcedSection> {
|
||||||
|
|
||||||
|
public static @NotNull SourcedSection root(@NotNull ConfigureSource<? extends SourcedSection, ?, ?> source) {
|
||||||
|
return new SourcedSection(source, new LinkedHashMap<>(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull SourcedSection root(@NotNull ConfigureSource<? extends SourcedSection, ?, ?> source,
|
||||||
|
@Nullable Map<?, ?> raw) {
|
||||||
|
return new SourcedSection(source, raw == null ? new LinkedHashMap<>() : raw, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final @NotNull ConfigureSource<? extends SourcedSection, ?, ?> source;
|
||||||
|
|
||||||
|
public SourcedSection(@NotNull ConfigureSource<? extends SourcedSection, ?, ?> source,
|
||||||
|
@NotNull Map<?, ?> raw, @Nullable SourcedSection parent) {
|
||||||
|
super(parent);
|
||||||
|
this.source = source;
|
||||||
|
migrate(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ConfigureSource<? extends SourcedSection, ?, ?> source() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char pathSeparator() {
|
||||||
|
return source().pathSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull SourcedSection self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull SourcedSection createSection(@NotNull Map<?, ?> data) {
|
||||||
|
return new SourcedSection(source(), data, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package test.section;
|
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.RawMapSection;
|
import cc.carm.lib.configuration.source.section.MemorySection;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -16,7 +16,7 @@ public class ShadeTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
ConfigureSection template = RawMapSection.of(data -> {
|
ConfigureSection template = MemorySection.of(data -> {
|
||||||
data.put("name", "GentleMan");
|
data.put("name", "GentleMan");
|
||||||
data.put("age", 12);
|
data.put("age", 12);
|
||||||
data.put("gender", "male");
|
data.put("gender", "male");
|
||||||
@@ -26,8 +26,7 @@ public class ShadeTest {
|
|||||||
data.put("addresses", address);
|
data.put("addresses", address);
|
||||||
data.put("cards", Arrays.asList("00000", "11111", "22222"));
|
data.put("cards", Arrays.asList("00000", "11111", "22222"));
|
||||||
});
|
});
|
||||||
|
ConfigureSection source = MemorySection.of(data -> {
|
||||||
ConfigureSection source = RawMapSection.of(data -> {
|
|
||||||
data.put("age", 25);
|
data.put("age", 25);
|
||||||
Map<String, Object> address = new LinkedHashMap<>();
|
Map<String, Object> address = new LinkedHashMap<>();
|
||||||
address.put("NewOne", "Guangdong Road 505");
|
address.put("NewOne", "Guangdong Road 505");
|
||||||
@@ -35,6 +34,10 @@ public class ShadeTest {
|
|||||||
data.put("cards", Arrays.asList("33333", "55555")); // 应当直接覆盖原先的List
|
data.put("cards", Arrays.asList("33333", "55555")); // 应当直接覆盖原先的List
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package cc.carm.lib.configuration.source.json;
|
|||||||
|
|
||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
import cc.carm.lib.configuration.source.file.FileConfigSource;
|
import cc.carm.lib.configuration.source.file.FileConfigSource;
|
||||||
import cc.carm.lib.configuration.source.section.MemorySection;
|
import cc.carm.lib.configuration.source.section.SourcedSection;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonSerializer;
|
import com.google.gson.JsonSerializer;
|
||||||
@@ -14,17 +14,17 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class JSONSource extends FileConfigSource<MemorySection, Map<String, Object>, JSONSource> {
|
public class JSONSource extends FileConfigSource<SourcedSection, Map<String, Object>, JSONSource> {
|
||||||
|
|
||||||
public static final @NotNull Gson DEFAULT_GSON = new GsonBuilder()
|
public static final @NotNull Gson DEFAULT_GSON = new GsonBuilder()
|
||||||
.serializeNulls().disableHtmlEscaping().setPrettyPrinting()
|
.serializeNulls().disableHtmlEscaping().setPrettyPrinting()
|
||||||
.registerTypeAdapter(
|
.registerTypeAdapter(
|
||||||
MemorySection.class,
|
SourcedSection.class,
|
||||||
(JsonSerializer<MemorySection>) (src, t, c) -> c.serialize(src.data())
|
(JsonSerializer<SourcedSection>) (src, t, c) -> c.serialize(src.data())
|
||||||
).create();
|
).create();
|
||||||
|
|
||||||
protected final @NotNull Gson gson;
|
protected final @NotNull Gson gson;
|
||||||
protected @Nullable MemorySection rootSection;
|
protected @Nullable SourcedSection rootSection;
|
||||||
|
|
||||||
protected JSONSource(@NotNull ConfigurationHolder<? extends JSONSource> holder,
|
protected JSONSource(@NotNull ConfigurationHolder<? extends JSONSource> holder,
|
||||||
@NotNull File file, @Nullable String resourcePath) {
|
@NotNull File file, @Nullable String resourcePath) {
|
||||||
@@ -58,7 +58,7 @@ public class JSONSource extends FileConfigSource<MemorySection, Map<String, Obje
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull MemorySection section() {
|
public @NotNull SourcedSection section() {
|
||||||
return Objects.requireNonNull(this.rootSection, "Root section is not initialized");
|
return Objects.requireNonNull(this.rootSection, "Root section is not initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ public class JSONSource extends FileConfigSource<MemorySection, Map<String, Obje
|
|||||||
@Override
|
@Override
|
||||||
protected void onReload() throws Exception {
|
protected void onReload() throws Exception {
|
||||||
Map<?, ?> data = fileReader(reader -> gson.fromJson(reader, LinkedHashMap.class));
|
Map<?, ?> data = fileReader(reader -> gson.fromJson(reader, LinkedHashMap.class));
|
||||||
this.rootSection = MemorySection.root(this, data);
|
this.rootSection = SourcedSection.root(this, data);
|
||||||
this.lastUpdateMillis = System.currentTimeMillis(); // 更新时间
|
this.lastUpdateMillis = System.currentTimeMillis(); // 更新时间
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import cc.carm.lib.configuration.commentable.CommentableOptions;
|
|||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
import cc.carm.lib.configuration.source.file.FileConfigSource;
|
import cc.carm.lib.configuration.source.file.FileConfigSource;
|
||||||
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.SourcedSection;
|
||||||
import cc.carm.lib.yamlcommentupdater.CommentedSection;
|
import cc.carm.lib.yamlcommentupdater.CommentedSection;
|
||||||
import cc.carm.lib.yamlcommentupdater.CommentedYAMLWriter;
|
import cc.carm.lib.yamlcommentupdater.CommentedYAMLWriter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -26,14 +26,14 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class YAMLSource
|
public class YAMLSource
|
||||||
extends FileConfigSource<MemorySection, Map<String, Object>, YAMLSource>
|
extends FileConfigSource<SourcedSection, Map<String, Object>, YAMLSource>
|
||||||
implements CommentedSection {
|
implements CommentedSection {
|
||||||
|
|
||||||
protected final @NotNull YamlConstructor yamlConstructor;
|
protected final @NotNull YamlConstructor yamlConstructor;
|
||||||
protected final @NotNull YamlRepresenter yamlRepresenter;
|
protected final @NotNull YamlRepresenter yamlRepresenter;
|
||||||
protected final @NotNull Yaml yaml;
|
protected final @NotNull Yaml yaml;
|
||||||
|
|
||||||
protected @Nullable MemorySection rootSection;
|
protected @Nullable SourcedSection rootSection;
|
||||||
|
|
||||||
protected YAMLSource(@NotNull ConfigurationHolder<? extends YAMLSource> holder,
|
protected YAMLSource(@NotNull ConfigurationHolder<? extends YAMLSource> holder,
|
||||||
@NotNull File file, @Nullable String resourcePath) {
|
@NotNull File file, @Nullable String resourcePath) {
|
||||||
@@ -65,7 +65,7 @@ public class YAMLSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull MemorySection section() {
|
public @NotNull SourcedSection section() {
|
||||||
return Objects.requireNonNull(this.rootSection, "Root section is not initialized.");
|
return Objects.requireNonNull(this.rootSection, "Root section is not initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,18 +130,18 @@ public class YAMLSource
|
|||||||
return this.saveToString(section());
|
return this.saveToString(section());
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull MemorySection loadFromString(@NotNull String data) throws Exception {
|
public @NotNull SourcedSection loadFromString(@NotNull String data) throws Exception {
|
||||||
MappingNode mappingNode;
|
MappingNode mappingNode;
|
||||||
try (Reader reader = new UnicodeReader(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)))) {
|
try (Reader reader = new UnicodeReader(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)))) {
|
||||||
Node rawNode = this.yaml.compose(reader);
|
Node rawNode = this.yaml.compose(reader);
|
||||||
mappingNode = (MappingNode) rawNode;
|
mappingNode = (MappingNode) rawNode;
|
||||||
}
|
}
|
||||||
if (mappingNode == null) return MemorySection.root(this);
|
if (mappingNode == null) return SourcedSection.root(this);
|
||||||
|
|
||||||
|
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
this.constructMap(mappingNode, map);
|
this.constructMap(mappingNode, map);
|
||||||
return MemorySection.root(this, map);
|
return SourcedSection.root(this, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void constructMap(@NotNull MappingNode mappingNode, @NotNull Map<String, Object> section) {
|
private void constructMap(@NotNull MappingNode mappingNode, @NotNull Map<String, Object> section) {
|
||||||
@@ -170,7 +170,7 @@ public class YAMLSource
|
|||||||
public String serializeValue(@NotNull String key, @NotNull Object value) {
|
public String serializeValue(@NotNull String key, @NotNull Object value) {
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put(key, value);
|
map.put(key, value);
|
||||||
return saveToString(MemorySection.root(this, map));
|
return saveToString(SourcedSection.root(this, map));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user