mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
feat: hocon supported
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
package cc.carm.lib.configuration;
|
||||
|
||||
import cc.carm.lib.configuration.hocon.HOCONFileConfigProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EasyConfiguration {
|
||||
|
||||
private EasyConfiguration() {
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(File file, String source) {
|
||||
HOCONFileConfigProvider provider = new HOCONFileConfigProvider(file);
|
||||
try {
|
||||
provider.initializeFile(source);
|
||||
provider.initializeConfig();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(File file) {
|
||||
return from(file, file.getName());
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(String fileName) {
|
||||
return from(fileName, fileName);
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(String fileName, String source) {
|
||||
return from(new File(fileName), source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
package cc.carm.lib.configuration.hocon;
|
||||
|
||||
import cc.carm.lib.configuration.hocon.util.HOCONUtils;
|
||||
import com.typesafe.config.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class HOCONConfigWrapper implements ConfigurationWrapper<Map<String, Object>> {
|
||||
private static final char SEPARATOR = '.';
|
||||
protected final Map<String, Object> data;
|
||||
|
||||
public HOCONConfigWrapper(ConfigObject config) {
|
||||
this.data = new LinkedHashMap<>();
|
||||
|
||||
config.forEach((key, value) -> {
|
||||
Config cfg = config.toConfig();
|
||||
ConfigValue cv = cfg.getValue(key);
|
||||
if (cv.valueType() == ConfigValueType.OBJECT) {
|
||||
HOCONConfigWrapper.this.data.put(key, new HOCONConfigWrapper((ConfigObject) cv));
|
||||
} else {
|
||||
HOCONConfigWrapper.this.data.put(key, value.unwrapped());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getSource() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<String> getKeys(boolean deep) {
|
||||
return this.getValues(deep).keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return HOCONUtils.getKeysFromObject(this, deep, "").stream().collect(
|
||||
LinkedHashMap::new,
|
||||
(map, key) -> map.put(key, get(key)),
|
||||
LinkedHashMap::putAll
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
value = new HOCONConfigWrapper(ConfigFactory.parseMap((Map<String, ?>) value).root());
|
||||
}
|
||||
|
||||
HOCONConfigWrapper section = HOCONUtils.getObjectOn(this, path, SEPARATOR);
|
||||
String simplePath = HOCONUtils.getSimplePath(path, SEPARATOR);
|
||||
|
||||
if (value == null) {
|
||||
section.data.remove(simplePath);
|
||||
} else {
|
||||
section.setDirect(simplePath, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能设置当前路径下的内容
|
||||
* 避免环回
|
||||
*
|
||||
* @param path 路径
|
||||
*/
|
||||
public void setDirect(@NotNull String path, @Nullable Object value) {
|
||||
this.data.put(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull String path) {
|
||||
return this.get(path) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
HOCONConfigWrapper section = HOCONUtils.getObjectOn(this, path, SEPARATOR);
|
||||
return section.getDirect(HOCONUtils.getSimplePath(path, SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能获取当前路径下的内容
|
||||
* 避免环回
|
||||
*
|
||||
* @param path 路径
|
||||
*/
|
||||
public Object getDirect(@NotNull String path) {
|
||||
return this.data.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList(@NotNull String path) {
|
||||
return this.get(path) instanceof List<?>;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<?> getList(@NotNull String path) {
|
||||
Object val = this.get(path);
|
||||
return (val instanceof List<?>) ? (List<?>) val : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigurationSection(@NotNull String path) {
|
||||
return this.get(path) instanceof HOCONConfigWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigurationWrapper<Map<String, Object>> getConfigurationSection(@NotNull String path) {
|
||||
Object val = get(path);
|
||||
return (val instanceof HOCONConfigWrapper) ? (HOCONConfigWrapper) val : null;
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package cc.carm.lib.configuration.hocon;
|
||||
|
||||
import cc.carm.lib.configuration.source.comment.ConfigurationComments;
|
||||
import cc.carm.lib.configuration.core.source.impl.FileConfigProvider;
|
||||
import cc.carm.lib.configuration.hocon.exception.HOCONGetValueException;
|
||||
import cc.carm.lib.configuration.hocon.util.HOCONUtils;
|
||||
import com.typesafe.config.*;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class HOCONFileConfigProvider extends FileConfigProvider<HOCONConfigWrapper> {
|
||||
protected final @NotNull ConfigurationComments comments = new ConfigurationComments();
|
||||
protected HOCONConfigWrapper configuration;
|
||||
protected ConfigInitializer<HOCONFileConfigProvider> initializer;
|
||||
|
||||
public HOCONFileConfigProvider(@NotNull File file) {
|
||||
super(file);
|
||||
this.initializer = new ConfigInitializer<>(this);
|
||||
}
|
||||
|
||||
public void initializeConfig() {
|
||||
try {
|
||||
this.configuration = new HOCONConfigWrapper(ConfigFactory.parseFile(this.file, ConfigParseOptions.defaults()
|
||||
.setSyntax(ConfigSyntax.CONF)
|
||||
.setAllowMissing(false)).root());
|
||||
} catch (ConfigException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HOCONConfigWrapper getConfiguration() {
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
Files.write(this.file.toPath(), HOCONUtils.renderWithComment(configuration, comments::getHeaderComment).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReload() throws ConfigException {
|
||||
ConfigObject conf = ConfigFactory.parseFile(this.file, ConfigParseOptions.defaults()
|
||||
.setSyntax(ConfigSyntax.CONF)
|
||||
.setAllowMissing(false)).root();
|
||||
this.configuration = new HOCONConfigWrapper(conf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigurationComments getComments() {
|
||||
return this.comments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigInitializer<HOCONFileConfigProvider> getInitializer() {
|
||||
return this.initializer;
|
||||
}
|
||||
|
||||
public String serializeValue(@NotNull String key, @NotNull Object value) {
|
||||
// 带有 key=value 的新空对象
|
||||
return ConfigFactory.empty()
|
||||
.withValue(key, ConfigValueFactory.fromAnyRef(value))
|
||||
.root().render();
|
||||
}
|
||||
|
||||
public @NotNull Set<String> getKeys() {
|
||||
return getKeys(null, true);
|
||||
}
|
||||
|
||||
@Contract("null,_->!null")
|
||||
public @Nullable Set<String> getKeys(@Nullable String sectionKey, boolean deep) {
|
||||
if (sectionKey == null) { // 当前路径
|
||||
return HOCONUtils.getKeysFromObject(this.configuration, deep, "");
|
||||
}
|
||||
|
||||
HOCONConfigWrapper section;
|
||||
try {
|
||||
// 获取目标字段所在路径
|
||||
section = (HOCONConfigWrapper) this.configuration.get(sectionKey);
|
||||
} catch (ClassCastException e) {
|
||||
// 值和类型不匹配
|
||||
throw new HOCONGetValueException(e);
|
||||
}
|
||||
if (section == null) {
|
||||
return null;
|
||||
}
|
||||
return HOCONUtils.getKeysFromObject(section, deep, "");
|
||||
}
|
||||
|
||||
public @Nullable Object getValue(@NotNull String key) {
|
||||
return this.configuration.get(key);
|
||||
}
|
||||
|
||||
public @Nullable List<String> getHeaderComments(@Nullable String key) {
|
||||
return this.comments.getHeaderComment(key);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package cc.carm.lib.configuration.hocon.exception;
|
||||
|
||||
public class HOCONGetValueException extends RuntimeException {
|
||||
public HOCONGetValueException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HOCONGetValueException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public HOCONGetValueException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public HOCONGetValueException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package cc.carm.lib.configuration.hocon.util;
|
||||
|
||||
import cc.carm.lib.configuration.hocon.HOCONConfigWrapper;
|
||||
import cc.carm.lib.configuration.hocon.exception.HOCONGetValueException;
|
||||
import com.typesafe.config.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class HOCONUtils {
|
||||
|
||||
private HOCONUtils() {
|
||||
}
|
||||
|
||||
public static String getSimplePath(String path, char separator) {
|
||||
int index = path.lastIndexOf(separator);
|
||||
return (index == -1) ? path : path.substring(index + 1);
|
||||
}
|
||||
|
||||
public static HOCONConfigWrapper getObjectOn(@NotNull HOCONConfigWrapper parent, @NotNull String path, char separator) {
|
||||
String currentPath = path;
|
||||
HOCONConfigWrapper currentObject = parent;
|
||||
int index;
|
||||
while ((index = currentPath.indexOf(separator)) != -1) {
|
||||
HOCONConfigWrapper previousObject = currentObject;
|
||||
String pathName = currentPath.substring(0, index);
|
||||
try {
|
||||
currentObject = (HOCONConfigWrapper) previousObject.getDirect(pathName);
|
||||
} catch (ClassCastException e) {
|
||||
throw new HOCONGetValueException(e);
|
||||
}
|
||||
if (currentObject == null) {
|
||||
currentObject = new HOCONConfigWrapper(ConfigFactory.empty().root());
|
||||
previousObject.setDirect(pathName, currentObject);
|
||||
}
|
||||
currentPath = currentPath.substring(index + 1);
|
||||
}
|
||||
|
||||
return currentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 Object 中获取所有键
|
||||
* 思路:在第一次执行时 prefix 应该是 ""
|
||||
* 后续找到了更深层的键,将会变为 "deep."
|
||||
* 下一次键名就是 "deep.key"
|
||||
*
|
||||
* @param parent Object
|
||||
* @param deep 是否更深层获取
|
||||
* @param prefix 当前 Object 键名前缀
|
||||
* @return Object 中的所有键
|
||||
*/
|
||||
public static Set<String> getKeysFromObject(HOCONConfigWrapper parent, boolean deep, String prefix) {
|
||||
return parent.getSource().entrySet().stream().collect(
|
||||
LinkedHashSet::new,
|
||||
(set, entry) -> {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof HOCONConfigWrapper && deep) {
|
||||
set.addAll(HOCONUtils.getKeysFromObject((HOCONConfigWrapper) value, true, prefix + entry.getKey() + "."));
|
||||
} else {
|
||||
set.add(prefix + entry.getKey());
|
||||
}
|
||||
},
|
||||
LinkedHashSet::addAll
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Object 保存为字符串
|
||||
* 并使用注释器打上注释
|
||||
*
|
||||
* @param object Object
|
||||
* @param commenter 注释器
|
||||
* @return 保存的字符串
|
||||
*/
|
||||
public static @NotNull String renderWithComment(@NotNull HOCONConfigWrapper object, @NotNull Function<String, List<String>> commenter) {
|
||||
return HOCONUtils.makeConfigWithComment(object, "", commenter).root().render(
|
||||
ConfigRenderOptions.defaults()
|
||||
.setJson(false)
|
||||
.setOriginComments(false)
|
||||
);
|
||||
}
|
||||
|
||||
public static @NotNull Config makeConfigWithComment(@NotNull HOCONConfigWrapper object, @NotNull String prefix, @NotNull Function<String, List<String>> commenter) {
|
||||
Config config = ConfigFactory.empty();
|
||||
for (Map.Entry<String, Object> entry : object.getSource().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String fullKey = prefix + key;
|
||||
Object value = entry.getValue();
|
||||
ConfigValue result;
|
||||
if (value instanceof Iterable) {
|
||||
result = ConfigValueFactory.fromIterable((Iterable<?>) value);
|
||||
} else if (value instanceof HOCONConfigWrapper) {
|
||||
result = makeConfigWithComment((HOCONConfigWrapper) value, fullKey + ".", commenter).root();
|
||||
} else {
|
||||
result = ConfigValueFactory.fromAnyRef(value);
|
||||
}
|
||||
result = result.withOrigin(
|
||||
ConfigOriginFactory.newSimple()
|
||||
.withComments(commenter.apply(fullKey))
|
||||
);
|
||||
config = config.withValue(key, result);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package cc.carm.lib.configuration.source.hocon;
|
||||
|
||||
import cc.carm.lib.configuration.commentable.Commentable;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.file.FileConfigFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class HOCONConfigFactory extends FileConfigFactory<HOCONSource, ConfigurationHolder<HOCONSource>, HOCONConfigFactory> {
|
||||
public static HOCONConfigFactory from(@NotNull String path) {
|
||||
return new HOCONConfigFactory(new File(path));
|
||||
}
|
||||
|
||||
public static HOCONConfigFactory from(@NotNull File file) {
|
||||
return new HOCONConfigFactory(file);
|
||||
}
|
||||
|
||||
public static HOCONConfigFactory from(@NotNull File parent, @NotNull String configName) {
|
||||
return new HOCONConfigFactory(new File(parent, configName));
|
||||
}
|
||||
|
||||
public HOCONConfigFactory(@NotNull File file) {
|
||||
super(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HOCONConfigFactory self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigurationHolder<HOCONSource> build() {
|
||||
File configFile = this.file;
|
||||
String sourcePath = this.resourcePath;
|
||||
|
||||
Commentable.registerMeta(this.initializer); // Register commentable meta types
|
||||
|
||||
return new ConfigurationHolder<HOCONSource>(this.adapters, this.options, this.metadata, this.initializer) {
|
||||
final @NotNull HOCONSource source = new HOCONSource(this, configFile, sourcePath);
|
||||
|
||||
@Override
|
||||
public @NotNull HOCONSource config() {
|
||||
return this.source;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package cc.carm.lib.configuration.source.hocon;
|
||||
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import com.typesafe.config.Config;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnmodifiableView;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HOCONSection implements ConfigureSection {
|
||||
|
||||
protected final @NotNull HOCONSource source;
|
||||
protected final @Nullable HOCONSection parent;
|
||||
protected final @NotNull Config data;
|
||||
|
||||
public HOCONSection(@NotNull HOCONSource source, @Nullable HOCONSection parent,
|
||||
@NotNull Config data) {
|
||||
this.source = source;
|
||||
this.parent = parent;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public @NotNull Config data() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HOCONSource source() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable HOCONSection parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull @UnmodifiableView Map<String, Object> getValues(boolean deep) {
|
||||
return data().root().unwrapped();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull String path) {
|
||||
return data().hasPath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<?> getList(@NotNull String path) {
|
||||
return data().getAnyRefList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable HOCONSection getSection(@NotNull String path) {
|
||||
return data().getConfig(path) == null ? null : new HOCONSection(source, this, data().getConfig(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
return data().getAnyRef(path);
|
||||
}
|
||||
|
||||
}
|
||||
+74
-14
@@ -1,44 +1,104 @@
|
||||
package cc.carm.lib.configuration.source.hocon;
|
||||
|
||||
import cc.carm.lib.configuration.commentable.Commentable;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import com.typesafe.config.Config;
|
||||
import cc.carm.lib.configuration.source.file.FileConfigSource;
|
||||
import cc.carm.lib.configuration.source.section.SourcedSection;
|
||||
import com.typesafe.config.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public class HOCONSource extends ConfigureSource<HOCONSection, Config, HOCONSource> {
|
||||
public class HOCONSource
|
||||
extends FileConfigSource<SourcedSection, Map<String, Object>, HOCONSource> {
|
||||
protected @Nullable SourcedSection rootSection;
|
||||
|
||||
protected HOCONSource(
|
||||
@NotNull ConfigurationHolder<? extends HOCONSource> holder,
|
||||
@NotNull File file, @Nullable String resourcePath
|
||||
) {
|
||||
super(holder, 0, file, resourcePath);
|
||||
|
||||
private HOCONSection rootSection;
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
protected HOCONSource(@NotNull ConfigurationHolder<? extends HOCONSource> holder, long lastUpdateMillis) {
|
||||
super(holder, lastUpdateMillis);
|
||||
public void initialize() {
|
||||
try {
|
||||
this.initializeFile();
|
||||
this.onReload();
|
||||
} catch (Exception e) {
|
||||
//noinspection CallToPrintStackTrace
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HOCONSource self() {
|
||||
protected @NotNull HOCONSource self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Config original() {
|
||||
return section().data();
|
||||
public @NotNull Map<String, Object> original() {
|
||||
return this.section().data();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HOCONSection section() {
|
||||
return Objects.requireNonNull(rootSection, "RootSection is not initialized");
|
||||
public @NotNull SourcedSection section() {
|
||||
return Objects.requireNonNull(this.rootSection, "Root section is not initialized.");
|
||||
}
|
||||
|
||||
public @NotNull String saveToString() {
|
||||
// identity: 创建新的空 typesafe config
|
||||
// accumulator: 将 Section 中的信息为 typesafe config 添加并返回
|
||||
// combiner: 合并两个配置文件
|
||||
Config config = this.getValues(true).entrySet().stream().reduce(
|
||||
ConfigFactory.empty(),
|
||||
(cfg, entry) -> {
|
||||
String key = entry.getKey(); // 源数据 key
|
||||
Object value = entry.getValue(); // 源数据 value
|
||||
|
||||
ConfigValue result; // 最终转换为 typesafe 的 ConfigValue 类型
|
||||
if (value == null || value instanceof Boolean || value instanceof String || value instanceof Number) {
|
||||
result = ConfigValueFactory.fromAnyRef(value); // 原始数据类型
|
||||
} else if (value instanceof Iterator) {
|
||||
result = ConfigValueFactory.fromIterable((Iterable<?>) value);
|
||||
} else if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
result = ConfigValueFactory.fromMap((Map<String, ?>) value);
|
||||
} else {
|
||||
result = ConfigValueFactory.fromAnyRef(String.valueOf(value));
|
||||
}
|
||||
List<String> headerComments = HOCONSource.this.getHeaderComments(key); // 获取其注释
|
||||
result = result.withOrigin(result.origin().withComments(headerComments)); // 赋予其注释
|
||||
return cfg.withValue(key, result); // 将其添加到根 config 中
|
||||
},
|
||||
Config::withFallback
|
||||
);
|
||||
return config.root().render(
|
||||
ConfigRenderOptions.defaults()
|
||||
.setJson(false)
|
||||
.setOriginComments(false)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws Exception {
|
||||
|
||||
this.fileWriter(w -> w.write(HOCONSource.this.saveToString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReload() throws Exception {
|
||||
|
||||
this.rootSection = this.fileReadString(this::loadFromString);
|
||||
}
|
||||
|
||||
protected @NotNull SourcedSection loadFromString(@NotNull String data) {
|
||||
ConfigObject config = ConfigFactory.parseString(data).root();
|
||||
return SourcedSection.root(this, config.unwrapped());
|
||||
}
|
||||
|
||||
public @Nullable List<String> getHeaderComments(@Nullable String key) {
|
||||
return Commentable.getHeaderComments(holder(), key);
|
||||
}
|
||||
}
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package online.flowerinsnow.test.easyconfiguration;
|
||||
|
||||
public class HOCONTest {
|
||||
// @Test
|
||||
// public void onTest() {
|
||||
// HOCONFileConfigProvider provider = EasyConfiguration.from(new File("target/hocon.conf"));
|
||||
//
|
||||
// ConfigurationTest.testDemo(provider);
|
||||
// ConfigurationTest.testInner(provider);
|
||||
//
|
||||
// try {
|
||||
// provider.save();
|
||||
// provider.reload();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package sample;
|
||||
|
||||
import cc.carm.lib.configuration.Configuration;
|
||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||
import cc.carm.lib.configuration.annotation.HeaderComments;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ConfigPath(root = true)
|
||||
@HeaderComments("Configurations for sample")
|
||||
public interface SampleConfig extends Configuration {
|
||||
ConfiguredValue<Boolean> ENABLED = ConfiguredValue.of(true);
|
||||
|
||||
@HeaderComments("Server configurations") // Header comment
|
||||
ConfiguredValue<Integer> PORT = ConfiguredValue.of(Integer.class);
|
||||
|
||||
@HeaderComments({"[ UUID >-----------------------------------", "A lot of UUIDs"})
|
||||
ConfiguredList<UUID> UUIDS = ConfiguredList.builderOf(UUID.class).fromString()
|
||||
.parse(UUID::fromString).serialize(UUID::toString)
|
||||
.defaults(
|
||||
UUID.fromString("00000000-0000-0000-0000-000000000000"),
|
||||
UUID.fromString("00000000-0000-0000-0000-000000000001")
|
||||
).build();
|
||||
|
||||
@ConfigPath("info") // Custom path
|
||||
interface INFO extends Configuration {
|
||||
|
||||
@HeaderComments("Configure your name!") // Header comment
|
||||
ConfiguredValue<String> NAME = ConfiguredValue.of("Joker");
|
||||
|
||||
@ConfigPath("how-old-are-you") // Custom path
|
||||
ConfiguredValue<Integer> AGE = ConfiguredValue.of(24);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package sample;
|
||||
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.hocon.HOCONConfigFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SampleTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
// 1. Make a configuration provider from a file.
|
||||
ConfigurationHolder<?> holder = HOCONConfigFactory.from("target/config.conf")
|
||||
.resourcePath("configs/sample.conf")
|
||||
.build();
|
||||
|
||||
// 2. Initialize the configuration classes or instances.
|
||||
holder.initialize(SampleConfig.class);
|
||||
// 3. Enjoy using the configuration!
|
||||
System.out.println("Enabled? -> " + SampleConfig.ENABLED.resolve());
|
||||
SampleConfig.ENABLED.set(false);
|
||||
System.out.println("And now? -> " + SampleConfig.ENABLED.resolve());
|
||||
// p.s. Changes not save so enable value will still be true in the next run.
|
||||
|
||||
System.out.println("Your name is " + SampleConfig.INFO.NAME.resolve() + " (age=" + SampleConfig.INFO.AGE.resolve() + ")!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
version = 1.0
|
||||
test-save = false
|
||||
Reference in New Issue
Block a user