1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2026-06-04 10:38:19 +08:00

feat(yaml): Finished YAML Provider

This commit is contained in:
2025-02-13 06:48:58 +08:00
parent 5b95824bb0
commit 47e2a4854c
27 changed files with 357 additions and 426 deletions
@@ -1,5 +1,6 @@
package cc.carm.lib.configuration.source.file;
import cc.carm.lib.configuration.function.DataConsumer;
import cc.carm.lib.configuration.function.DataFunction;
import cc.carm.lib.configuration.source.ConfigurationHolder;
import cc.carm.lib.configuration.source.option.FileConfigOptions;
@@ -14,7 +15,6 @@ import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Objects;
import java.util.function.Consumer;
public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINAL, SELF extends FileConfigSource<SECTION, ORIGINAL, SELF>>
extends ConfigureSource<SECTION, ORIGINAL, SELF> {
@@ -38,7 +38,6 @@ public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINA
return holder().options().get(FileConfigOptions.COPY_DEFAULTS);
}
public void initializeFile() throws IOException {
if (this.file.exists()) return;
@@ -74,13 +73,41 @@ public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINA
}
}
protected void fileOutputStream(@NotNull Consumer<OutputStream> stream) throws Exception {
protected <R> R fileReadString(@NotNull DataFunction<String, R> loader) throws Exception {
try (InputStream is = Files.newInputStream(file.toPath())) {
try (Reader r = new InputStreamReader(is, charset())) {
StringBuilder sb = new StringBuilder();
char[] buf = new char[1024];
int len;
while ((len = r.read(buf)) > 0) {
sb.append(buf, 0, len);
}
return loader.handle(sb.toString());
}
}
}
protected void fileReadString(@NotNull DataConsumer<String> loader) throws Exception {
try (InputStream is = Files.newInputStream(file.toPath())) {
try (Reader r = new InputStreamReader(is, charset())) {
StringBuilder sb = new StringBuilder();
char[] buf = new char[1024];
int len;
while ((len = r.read(buf)) > 0) {
sb.append(buf, 0, len);
}
loader.accept(sb.toString());
}
}
}
protected void fileOutputStream(@NotNull DataConsumer<OutputStream> stream) throws Exception {
try (OutputStream os = Files.newOutputStream(file.toPath())) {
stream.accept(os);
}
}
protected void fileWriter(@NotNull Consumer<Writer> writer) throws Exception {
protected void fileWriter(@NotNull DataConsumer<Writer> writer) throws Exception {
try (OutputStream os = Files.newOutputStream(file.toPath())) {
try (Writer w = new OutputStreamWriter(os, charset())) {
writer.accept(w);
+51
View File
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>easyconfiguration-parent</artifactId>
<version>3.9.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyconfiguration-feature-section</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>easyconfiguration-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,166 @@
package cc.carm.lib.configuration.source.section;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class MemorySection implements ConfigureSection {
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);
}
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) {
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());
}
}
}
protected @NotNull MemorySection createChild(@NotNull Map<?, ?> data) {
return new MemorySection(source(), data, this);
}
protected @NotNull MemorySection createChild() {
return createChild(new LinkedHashMap<>());
}
@Override
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;
}
@Override
public @NotNull Map<String, Object> getValues(boolean deep) {
if (deep) {
Map<String, Object> values = new LinkedHashMap<>();
mapChildrenValues(values, this, null, true);
return Collections.unmodifiableMap(values);
} else return Collections.unmodifiableMap(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) {
if (value == null) {
this.data.remove(path);
} else {
this.data.put(path, value);
}
} else {
section.set(getChild(path), value);
}
}
@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(getChild(path));
}
@Override
public boolean isList(@NotNull String path) {
return get(path) instanceof List<?>;
}
@Override
public @Nullable List<?> getList(@NotNull String path) {
Object val = get(path);
return (val instanceof List<?>) ? (List<?>) val : null;
}
@Override
public boolean isSection(@NotNull String path) {
return get(path) instanceof ConfigureSection;
}
@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(separator());
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 getChild(String path) {
int index = path.indexOf(separator());
return (index == -1) ? path : path.substring(index + 1);
}
/**
* Map the values of the children of the section to the output map.
*
* @param output The map to map the values to
* @param section The section to map the values from
* @param parent The parent path
* @param deep If the mapping should be deep
*/
protected void mapChildrenValues(@NotNull Map<String, Object> output, @NotNull MemorySection section,
@Nullable String parent, boolean deep) {
for (Map.Entry<String, Object> entry : section.data().entrySet()) {
String path = (parent == null ? "" : parent + separator()) + entry.getKey();
output.remove(path);
output.put(path, entry.getValue());
if (deep && entry.getValue() instanceof MemorySection) {
this.mapChildrenValues(output, (MemorySection) entry.getValue(), path, true);
}
}
}
}
@@ -19,7 +19,7 @@ public interface VersionedMetaTypes {
}
static void register(@NotNull ConfigurationInitializer initializer) {
initializer.registerAnnotation(ConfigVersion.class, VERSION, ConfigVersion::value);
initializer.registerFieldAnnotation(ConfigVersion.class, VERSION, ConfigVersion::value);
}
}