mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4523190cb0 | |||
| 2a49e2ee6b | |||
| 77b223b2cb | |||
| 8e7ac263e7 | |||
| 80f03ec501 | |||
| 1c002ae535 | |||
| a4659c5c9f |
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
|
||||
@@ -7,6 +7,7 @@ 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;
|
||||
@@ -17,8 +18,8 @@ import java.util.stream.Stream;
|
||||
* @author Carm
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public interface ConfigureSection {
|
||||
|
||||
public interface ConfigureSection extends Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the parent section of this section.
|
||||
* <p>
|
||||
@@ -47,6 +48,17 @@ public interface ConfigureSection {
|
||||
return getValues(deep).keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set containing all primary keys in this section.
|
||||
*
|
||||
* @return Set of keys contained within this Section.
|
||||
*/
|
||||
@NotNull
|
||||
@UnmodifiableView
|
||||
default Set<String> keys() {
|
||||
return getKeys(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set containing all values in this section.
|
||||
* <p>
|
||||
@@ -63,6 +75,36 @@ public interface ConfigureSection {
|
||||
@UnmodifiableView
|
||||
Map<String, Object> getValues(boolean deep);
|
||||
|
||||
/**
|
||||
* Gets a set containing all key-values in this section.
|
||||
*
|
||||
* @return Map of data values contained within this Section.
|
||||
* @see #getValues(boolean)
|
||||
*/
|
||||
@NotNull
|
||||
@UnmodifiableView
|
||||
default Map<String, Object> values() {
|
||||
return getValues(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a stream of all values in this section.
|
||||
*
|
||||
* @return Stream of all values in this section.
|
||||
*/
|
||||
default Stream<Map.Entry<String, Object>> stream() {
|
||||
return values().entrySet().stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over all keys in this section.
|
||||
*
|
||||
* @param action The action to apply to each key.
|
||||
*/
|
||||
default void forEach(@NotNull BiConsumer<String, Object> action) {
|
||||
values().forEach(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value at the given path.
|
||||
* <p>
|
||||
@@ -318,7 +360,7 @@ public interface ConfigureSection {
|
||||
* Predicate the value of given path is a {@link Integer}.
|
||||
*
|
||||
* @param path The path to check.
|
||||
* @return True if the value is present and is a int, false otherwise.
|
||||
* @return True if the value is present and is an int, false otherwise.
|
||||
*/
|
||||
default boolean isInt(@NotNull String path) {
|
||||
return isType(path, Integer.class);
|
||||
@@ -328,7 +370,7 @@ public interface ConfigureSection {
|
||||
* Get the value as a {@link Integer} from the specified path.
|
||||
*
|
||||
* @param path The path to get the int.
|
||||
* @return The int if the path exists and is a int, otherwise 0.
|
||||
* @return The int if the path exists and is an int, otherwise 0.
|
||||
*/
|
||||
default @Nullable Integer getInt(@NotNull String path) {
|
||||
return getInt(path, 0);
|
||||
@@ -339,7 +381,7 @@ public interface ConfigureSection {
|
||||
*
|
||||
* @param path The path to get the int.
|
||||
* @param def The default value to return if the path does not exist.
|
||||
* @return The int if the path exists and is a int, otherwise the default value.
|
||||
* @return The int if the path exists and is an int, otherwise the default value.
|
||||
*/
|
||||
@Contract("_, !null -> !null")
|
||||
default @Nullable Integer getInt(@NotNull String path, @Nullable Integer def) {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
package cc.carm.lib.configuration.source.section;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class MapSection<R extends MapSection<R>> implements ConfigureSection {
|
||||
|
||||
protected final @NotNull Map<String, Object> data;
|
||||
protected final @Nullable R parent;
|
||||
|
||||
protected MapSection(@Nullable R parent) {
|
||||
this.parent = parent;
|
||||
this.data = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public void migrate(Map<?, ?> data) {
|
||||
for (Map.Entry<?, ?> entry : data.entrySet()) {
|
||||
String key = (entry.getKey() == null) ? "null" : entry.getKey().toString();
|
||||
if (entry.getValue() instanceof Map) {
|
||||
this.data.put(key, createChild((Map<?, ?>) entry.getValue()));
|
||||
} else if (entry.getValue() instanceof List) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (Object obj : (List<?>) entry.getValue()) {
|
||||
if (obj instanceof Map) {
|
||||
list.add(createChild((Map<?, ?>) obj));
|
||||
} else {
|
||||
list.add(obj);
|
||||
}
|
||||
}
|
||||
this.data.put(key, list);
|
||||
} else {
|
||||
this.data.put(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract @NotNull R self();
|
||||
|
||||
protected abstract @NotNull R createChild(@NotNull Map<?, ?> data);
|
||||
|
||||
protected @NotNull R createChild() {
|
||||
return createChild(new LinkedHashMap<>());
|
||||
}
|
||||
|
||||
public @NotNull Map<String, Object> data() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public @Nullable R parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path separator for the section.
|
||||
*
|
||||
* @return The path separator
|
||||
*/
|
||||
public char pathSeparator() {
|
||||
return '.';
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return Collections.unmodifiableMap(deep ? mappingValues(this, null, true) : data());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
if (value instanceof Map) value = createChild((Map<?, ?>) value);
|
||||
|
||||
R section = getSectionFor(path);
|
||||
if (section == this) {
|
||||
// Even this value is null, we still need to put it in the map
|
||||
// to ensure that the path is marked as existing.
|
||||
this.data.put(path, value);
|
||||
} else {
|
||||
section.set(childPath(path), value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(@NotNull String path) {
|
||||
R section = getSectionFor(path);
|
||||
if (section != this) {
|
||||
section.remove(childPath(path));
|
||||
} else {
|
||||
this.data.remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
return (val instanceof ConfigureSection) ? (ConfigureSection) val : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private R getSectionFor(String path) {
|
||||
int index = path.indexOf(pathSeparator());
|
||||
if (index == -1) return self();
|
||||
|
||||
String root = path.substring(0, index);
|
||||
return (R) data().computeIfAbsent(root, k -> createChild());
|
||||
}
|
||||
|
||||
private String childPath(String path) {
|
||||
int index = path.indexOf(pathSeparator());
|
||||
return (index == -1) ? path : path.substring(index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the values of the children of the section to the output map.
|
||||
*
|
||||
* @param section The section to map the values from
|
||||
* @param parent The parent path
|
||||
* @param deep If the mapping should be deep
|
||||
*/
|
||||
protected Map<String, Object> mappingValues(@NotNull MapSection<?> section, @Nullable String parent, boolean deep) {
|
||||
Map<String, Object> output = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, Object> entry : section.data().entrySet()) {
|
||||
String path = (parent == null ? "" : parent + pathSeparator()) + entry.getKey();
|
||||
output.remove(path);
|
||||
output.put(path, entry.getValue());
|
||||
if (deep && entry.getValue() instanceof MapSection<?>) {
|
||||
output.putAll(mappingValues((MapSection<?>) entry.getValue(), path, true));
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
+24
-139
@@ -3,161 +3,46 @@ package cc.carm.lib.configuration.source.section;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MemorySection implements ConfigureSection {
|
||||
public class MemorySection extends MapSection<MemorySection> {
|
||||
|
||||
public static @NotNull MemorySection root(@NotNull ConfigureSource<? extends MemorySection, ?, ?> source) {
|
||||
return new MemorySection(source, new LinkedHashMap<>(), null);
|
||||
}
|
||||
|
||||
public static @NotNull MemorySection root(@NotNull ConfigureSource<? extends MemorySection, ?, ?> source,
|
||||
@Nullable Map<?, ?> data) {
|
||||
return new MemorySection(source, data == null ? new LinkedHashMap<>() : data, null);
|
||||
@Nullable Map<?, ?> raw) {
|
||||
return new MemorySection(source, raw == null ? new LinkedHashMap<>() : raw, null);
|
||||
}
|
||||
|
||||
protected final @NotNull ConfigureSource<? extends MemorySection, ?, ?> source;
|
||||
protected final @NotNull Map<String, Object> data;
|
||||
protected final @Nullable MemorySection parent;
|
||||
|
||||
public MemorySection(@NotNull ConfigureSource<? extends MemorySection, ?, ?> source,
|
||||
@NotNull Map<?, ?> data, @Nullable MemorySection parent) {
|
||||
protected MemorySection(@NotNull ConfigureSource<? extends MemorySection, ?, ?> source,
|
||||
@NotNull Map<?, ?> raw, @Nullable MemorySection parent) {
|
||||
super(parent);
|
||||
this.source = source;
|
||||
this.parent = parent;
|
||||
this.data = new LinkedHashMap<>();
|
||||
for (Map.Entry<?, ?> entry : data.entrySet()) {
|
||||
String key = (entry.getKey() == null) ? "null" : entry.getKey().toString();
|
||||
if (entry.getValue() instanceof Map) {
|
||||
this.data.put(key, createChild((Map<?, ?>) entry.getValue()));
|
||||
} else if (entry.getValue() instanceof List) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (Object obj : (List<?>) entry.getValue()) {
|
||||
if (obj instanceof Map) {
|
||||
list.add(createChild((Map<?, ?>) obj));
|
||||
} else {
|
||||
list.add(obj);
|
||||
}
|
||||
}
|
||||
this.data.put(key, list);
|
||||
} else {
|
||||
this.data.put(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
migrate(raw);
|
||||
}
|
||||
|
||||
public @NotNull ConfigureSource<? extends MemorySection, ?, ?> source() {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char pathSeparator() {
|
||||
return source().pathSeparator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull MemorySection self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull MemorySection createChild(@NotNull Map<?, ?> data) {
|
||||
return new MemorySection(source(), data, this);
|
||||
}
|
||||
|
||||
protected @NotNull MemorySection createChild() {
|
||||
return createChild(new LinkedHashMap<>());
|
||||
}
|
||||
|
||||
public @NotNull ConfigureSource<? extends MemorySection, ?, ?> source() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public @NotNull Map<String, Object> data() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public @Nullable MemorySection parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public char pathSeparator() {
|
||||
return source.pathSeparator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return Collections.unmodifiableMap(deep ? mapChildrenValues(this, null, true) : data());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
if (value instanceof Map) value = createChild((Map<?, ?>) value);
|
||||
|
||||
MemorySection section = getSectionFor(path);
|
||||
if (section == this) {
|
||||
// Even this value is null, we still need to put it in the map
|
||||
// to ensure that the path is marked as existing.
|
||||
this.data.put(path, value);
|
||||
} else {
|
||||
section.set(childPath(path), value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(@NotNull String path) {
|
||||
MemorySection section = getSectionFor(path);
|
||||
if (section != this) {
|
||||
section.remove(childPath(path));
|
||||
} else {
|
||||
this.data.remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull String path) {
|
||||
return get(path) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
MemorySection 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);
|
||||
return (val instanceof ConfigureSection) ? (ConfigureSection) val : null;
|
||||
}
|
||||
|
||||
private MemorySection getSectionFor(String path) {
|
||||
int index = path.indexOf(pathSeparator());
|
||||
if (index == -1) return this;
|
||||
|
||||
String root = path.substring(0, index);
|
||||
Object section = this.data.get(root);
|
||||
if (section == null) {
|
||||
section = createChild();
|
||||
this.data.put(root, section);
|
||||
}
|
||||
|
||||
return (MemorySection) section;
|
||||
}
|
||||
|
||||
private String childPath(String path) {
|
||||
int index = path.indexOf(pathSeparator());
|
||||
return (index == -1) ? path : path.substring(index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the values of the children of the section to the output map.
|
||||
*
|
||||
* @param section The section to map the values from
|
||||
* @param parent The parent path
|
||||
* @param deep If the mapping should be deep
|
||||
*/
|
||||
protected Map<String, Object> mapChildrenValues(@NotNull MemorySection section,
|
||||
@Nullable String parent, boolean deep) {
|
||||
Map<String, Object> output = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, Object> entry : section.data().entrySet()) {
|
||||
String path = (parent == null ? "" : parent + pathSeparator()) + entry.getKey();
|
||||
output.remove(path);
|
||||
output.put(path, entry.getValue());
|
||||
if (deep && entry.getValue() instanceof MemorySection) {
|
||||
output.putAll(mapChildrenValues((MemorySection) entry.getValue(), path, true));
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>features/section</module>
|
||||
@@ -34,7 +34,7 @@
|
||||
</modules>
|
||||
|
||||
<name>EasyConfiguration</name>
|
||||
<description>轻松(做)配置,简单便捷的通用配置文件加载、读取与更新工具,可自定义配置格式。</description>
|
||||
<description>A simple, easy-to-use and universal solution for managing configuration files.</description>
|
||||
<url>https://github.com/CarmJos/EasyConfiguration</url>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -61,75 +61,4 @@ repositories {
|
||||
dependencies {
|
||||
api "cc.carm.lib:easyconfiguration-yaml:[LATEST RELEASE]"
|
||||
}
|
||||
```
|
||||
|
||||
## Example file format
|
||||
```yaml
|
||||
version: 1.0.0
|
||||
|
||||
test-save: false
|
||||
|
||||
test-number: 6161926779561752576
|
||||
|
||||
test-enum: DAYS
|
||||
|
||||
# Section类型数据测试
|
||||
user: # Section数据也支持InlineComment注释
|
||||
name: '35882'
|
||||
info:
|
||||
uuid: 554b79f1-7c39-4960-82d1-5514c9734417
|
||||
|
||||
uuid-value: 9a86663e-2fc7-4851-a423-c7e5d8e94a47 # This is an inline comment
|
||||
|
||||
sub:
|
||||
that:
|
||||
operators: []
|
||||
|
||||
# [ID - UUID]对照表
|
||||
|
||||
# 用于测试Map类型的解析与序列化保存
|
||||
users:
|
||||
'1': 1c055bdd-c9d1-4931-8270-3d162247f38a
|
||||
'2': 934e2b05-2417-424e-80fd-fe58c6725837
|
||||
'3': 442949a2-8345-4210-a87b-593d7168980e
|
||||
'4': 5c015453-4b5b-42e3-ad87-b9498f2dfeab
|
||||
'5': 8f9640e7-0fbd-4f73-b737-f0b707215e71
|
||||
|
||||
# Inner Test
|
||||
inner:
|
||||
inner-value: 51.223503560658166
|
||||
|
||||
class-value: 1.0
|
||||
|
||||
test:
|
||||
# Section类型数据测试
|
||||
user: # Section数据也支持InlineComment注释
|
||||
name: Carm
|
||||
info:
|
||||
uuid: 3d1ef2a0-a38b-44f3-b15f-8e3b22cb8cc6
|
||||
|
||||
# 以下内容用于测试序列化
|
||||
model-test:
|
||||
some-model:
|
||||
==: SomeModel
|
||||
num: 855
|
||||
name: 4f6b7
|
||||
any-model:
|
||||
==: AnyModel
|
||||
name: 63d05
|
||||
state: false
|
||||
models:
|
||||
- name: 481f3
|
||||
state: true
|
||||
- name: fcf3e
|
||||
state: false
|
||||
- name: '14e50'
|
||||
state: false
|
||||
model-map:
|
||||
a:
|
||||
name: 1fb9b
|
||||
state: false
|
||||
b:
|
||||
name: 5486f
|
||||
state: false
|
||||
```
|
||||
```
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.5</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
|
||||
Reference in New Issue
Block a user