1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2026-06-05 02:58:20 +08:00

chore(yaml): 独立 YAMLCommentWriter 项目

This commit is contained in:
2023-03-20 20:11:23 +08:00
parent 727c26a2fb
commit ddd33154be
14 changed files with 62 additions and 151 deletions
@@ -1,111 +0,0 @@
package cc.carm.lib.configuration.yaml;
import cc.carm.lib.configuration.core.source.ConfigurationComments;
import org.bspfsystems.yamlconfiguration.configuration.ConfigurationSection;
import org.bspfsystems.yamlconfiguration.file.FileConfiguration;
import org.bspfsystems.yamlconfiguration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static cc.carm.lib.configuration.yaml.YAMLConfigProvider.SEPARATOR;
@SuppressWarnings("SpellCheckingInspection")
public class YAMLComments extends ConfigurationComments {
public @Nullable String buildHeaderComments(@Nullable String path, @NotNull String indents) {
List<String> comments = getHeaderComment(path);
if (comments == null || comments.size() == 0) return null;
StringJoiner joiner = new StringJoiner("\n");
for (String comment : comments) {
if (comment.length() == 0) joiner.add(" ");
else joiner.add(indents + "# " + comment);
}
return joiner + "\n";
}
/**
* 从一个文件读取配置并写入注释到某个写入器中。
* 该方法的部分源代码借鉴自 tchristofferson/ConfigUpdater 项目。
*
* @param source 源配置文件
* @param writer 配置写入器
* @throws IOException 当写入发生错误时抛出
*/
public void writeComments(@NotNull YamlConfiguration source, @NotNull BufferedWriter writer) throws IOException {
FileConfiguration temp = new YamlConfiguration(); // 该对象用于临时记录配置内容
String configHeader = buildHeaderComments(null, "");
if (configHeader != null) writer.write(configHeader);
for (String fullKey : source.getKeys(true)) {
Object currentValue = source.get(fullKey);
String indents = getIndents(fullKey);
String headerComments = buildHeaderComments(fullKey, indents);
String inlineComment = getInlineComment(fullKey);
if (headerComments != null) writer.write(headerComments);
String[] splitFullKey = fullKey.split("[" + SEPARATOR + "]");
String trailingKey = splitFullKey[splitFullKey.length - 1];
if (currentValue instanceof ConfigurationSection) {
ConfigurationSection section = (ConfigurationSection) currentValue;
writer.write(indents + trailingKey + ":");
if (inlineComment != null && inlineComment.length() > 0) {
writer.write(" # " + inlineComment);
}
if (!section.getKeys(false).isEmpty()) {
writer.write("\n");
} else {
writer.write(" {}\n");
if (indents.length() == 0) writer.write("\n");
}
continue;
}
temp.set(trailingKey, currentValue);
String yaml = temp.saveToString();
temp.set(trailingKey, null);
yaml = yaml.substring(0, yaml.length() - 1);
if (inlineComment != null && inlineComment.length() > 0) {
if (yaml.contains("\n")) {
// section为多行内容,需要 InlineComment 加在首行末尾
String[] splitLine = yaml.split("\n", 2);
yaml = splitLine[0] + " # " + inlineComment + "\n" + splitLine[1];
} else {
// 其他情况下就直接加载后面就好。
yaml += " # " + inlineComment;
}
}
writer.write(indents + yaml.replace("\n", "\n" + indents) + "\n");
if (indents.length() == 0) writer.write("\n");
}
writer.close();
}
/**
* 得到一个键的缩进。
* 该方法的源代码来自 tchristofferson/ConfigUpdater 项目。
*
* @param key 键
* @return 该键的缩进文本
*/
protected static String getIndents(String key) {
String[] splitKey = key.split("[" + YAMLConfigProvider.SEPARATOR + "]");
return IntStream.range(1, splitKey.length).mapToObj(i -> " ").collect(Collectors.joining());
}
}
@@ -3,22 +3,21 @@ package cc.carm.lib.configuration.yaml;
import cc.carm.lib.configuration.core.ConfigInitializer;
import cc.carm.lib.configuration.core.source.ConfigurationComments;
import cc.carm.lib.configuration.core.source.impl.FileConfigProvider;
import cc.carm.lib.yamlcommentupdater.CommentedYAML;
import cc.carm.lib.yamlcommentupdater.CommentedYAMLWriter;
import org.bspfsystems.yamlconfiguration.configuration.ConfigurationSection;
import org.bspfsystems.yamlconfiguration.file.FileConfiguration;
import org.bspfsystems.yamlconfiguration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedWriter;
import java.io.File;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Set;
public class YAMLConfigProvider extends FileConfigProvider<YAMLSectionWrapper> {
public class YAMLConfigProvider extends FileConfigProvider<YAMLSectionWrapper> implements CommentedYAML {
protected static final char SEPARATOR = '.';
protected final @NotNull YAMLComments comments = new YAMLComments();
protected final @NotNull ConfigurationComments comments = new ConfigurationComments();
protected YamlConfiguration configuration;
protected ConfigInitializer<YAMLConfigProvider> initializer;
@@ -42,27 +41,18 @@ public class YAMLConfigProvider extends FileConfigProvider<YAMLSectionWrapper> {
}
@Override
public @Nullable ConfigurationComments getComments() {
public @NotNull ConfigurationComments getComments() {
return this.comments;
}
@Override
@SuppressWarnings("SpellCheckingInspection")
public void save() throws Exception {
configuration.save(getFile());
// tchristofferson/ConfigUpdater start
StringWriter writer = new StringWriter();
this.comments.writeComments(configuration, new BufferedWriter(writer));
String value = writer.toString(); // config contents
Path toUpdatePath = getFile().toPath();
if (!value.equals(new String(Files.readAllBytes(toUpdatePath), StandardCharsets.UTF_8))) {
// if updated contents are not the same as current file contents, update
Files.write(toUpdatePath, value.getBytes(StandardCharsets.UTF_8));
try {
CommentedYAMLWriter.writeWithComments(this, this.file);
} catch (Exception ex) {
configuration.save(file);
throw ex;
}
// tchristofferson/ConfigUpdater end
}
@Override
@@ -70,4 +60,31 @@ public class YAMLConfigProvider extends FileConfigProvider<YAMLSectionWrapper> {
return this.initializer;
}
@Override
public String serializeValue(@NotNull String key, @NotNull Object value) {
FileConfiguration temp = new YamlConfiguration();
temp.set(key, value);
return temp.saveToString();
}
@Override
public Set<String> getKeys(@Nullable String sectionKey, boolean deep) {
if (sectionKey == null) return configuration.getKeys(deep);
ConfigurationSection section = configuration.getConfigurationSection(sectionKey);
if (section == null) return null;
return section.getKeys(deep);
}
@Override
public @Nullable Object getValue(@NotNull String key) {
return configuration.get(key);
}
@Override
public @Nullable List<String> getHeaderComments(@Nullable String key) {
return comments.getHeaderComment(key);
}
}
@@ -21,6 +21,7 @@ public class DemoConfigTest {
@Test
public void onTest() {
ConfigurationTest.testDemo(this.provider);
ConfigurationTest.testInner(this.provider);
@@ -2,12 +2,14 @@ package config.source;
import cc.carm.lib.configuration.core.ConfigurationRoot;
import cc.carm.lib.configuration.core.annotation.ConfigPath;
import cc.carm.lib.configuration.core.annotation.HeaderComment;
import cc.carm.lib.configuration.core.value.ConfigValue;
import cc.carm.lib.configuration.demo.tests.model.AbstractModel;
import cc.carm.lib.configuration.yaml.value.ConfiguredSerializable;
import config.model.AnyModel;
import config.model.SomeModel;
@HeaderComment("以下内容用于测试序列化")
@ConfigPath("model-test")
public class ModelConfiguration extends ConfigurationRoot {
-1
View File
@@ -1,2 +1 @@
# Test Header
version: 1.0