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:
@@ -0,0 +1,18 @@
|
||||
package cc.carm.lib.configuration.function;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DataConsumer<T> {
|
||||
|
||||
void accept(@NotNull T data) throws Exception;
|
||||
|
||||
default DataConsumer<T> andThen(DataConsumer<? super T> after) {
|
||||
return (T t) -> {
|
||||
accept(t);
|
||||
after.accept(t);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class ConfigurationFactory<
|
||||
SOURCE extends ConfigureSource<?, ?, SOURCE>,
|
||||
@@ -31,8 +32,7 @@ public abstract class ConfigurationFactory<
|
||||
this.adapters.register(StandardAdapters.SECTION_ADAPTER);
|
||||
}
|
||||
|
||||
public abstract SELF self();
|
||||
|
||||
protected abstract SELF self();
|
||||
|
||||
public SELF adapters(ValueAdapterRegistry adapters) {
|
||||
this.adapters = adapters;
|
||||
@@ -81,13 +81,25 @@ public abstract class ConfigurationFactory<
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF option(Consumer<ConfigurationOptionHolder> optionsConsumer) {
|
||||
optionsConsumer.accept(options);
|
||||
public SELF option(Consumer<ConfigurationOptionHolder> modifier) {
|
||||
modifier.accept(options);
|
||||
return self();
|
||||
}
|
||||
|
||||
public <O> SELF option(ConfigurationOption<O> option, O value) {
|
||||
return option(o -> o.set(option, value));
|
||||
public <O> SELF option(ConfigurationOption<O> type, O value) {
|
||||
return option(o -> o.set(type, value));
|
||||
}
|
||||
|
||||
public <O> SELF option(ConfigurationOption<O> type, Supplier<O> value) {
|
||||
return option(type, value.get());
|
||||
}
|
||||
|
||||
public <O> SELF option(ConfigurationOption<O> type, Consumer<O> modifier) {
|
||||
return option(holder -> {
|
||||
O current = holder.get(type);
|
||||
modifier.accept(current);
|
||||
holder.set(type, current);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
+18
-6
@@ -67,7 +67,17 @@ public class ConfigurationInitializer {
|
||||
this.classInitializer = this.classInitializer.andThen(classInitializer);
|
||||
}
|
||||
|
||||
public <T, A extends Annotation> void registerAnnotation(@NotNull Class<A> annotation,
|
||||
public <T, A extends Annotation> void registerClassAnnotation(@NotNull Class<A> annotation,
|
||||
@NotNull ConfigurationMetadata<T> metadata,
|
||||
@NotNull Function<A, T> extractor) {
|
||||
appendClassInitializer((holder, path, clazz) -> {
|
||||
A data = clazz.getAnnotation(annotation);
|
||||
if (data == null) return;
|
||||
holder.metadata(path).setIfAbsent(metadata, extractor.apply(data));
|
||||
});
|
||||
}
|
||||
|
||||
public <T, A extends Annotation> void registerFieldAnnotation(@NotNull Class<A> annotation,
|
||||
@NotNull ConfigurationMetadata<T> metadata,
|
||||
@NotNull Function<A, T> extractor) {
|
||||
appendFieldInitializer((holder, path, field) -> {
|
||||
@@ -75,11 +85,13 @@ public class ConfigurationInitializer {
|
||||
if (data == null) return;
|
||||
holder.metadata(path).setIfAbsent(metadata, extractor.apply(data));
|
||||
});
|
||||
appendClassInitializer((holder, path, clazz) -> {
|
||||
A data = clazz.getAnnotation(annotation);
|
||||
if (data == null) return;
|
||||
holder.metadata(path).setIfAbsent(metadata, extractor.apply(data));
|
||||
});
|
||||
}
|
||||
|
||||
public <T, A extends Annotation> void registerAnnotation(@NotNull Class<A> annotation,
|
||||
@NotNull ConfigurationMetadata<T> metadata,
|
||||
@NotNull Function<A, T> extractor) {
|
||||
registerClassAnnotation(annotation, metadata, extractor);
|
||||
registerFieldAnnotation(annotation, metadata, extractor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -54,15 +54,16 @@ public class PathGenerator {
|
||||
ConfigPath clazzPath = clazz.getAnnotation(ConfigPath.class);
|
||||
if (clazzPath != null) return link(holder, parentPath, clazzPath.root(), clazzPath.value());
|
||||
|
||||
if (clazzField == null) {
|
||||
return link(holder, parentPath, false, parentPath == null ? null : covertPath(clazz.getSimpleName())); // No field, use class name.
|
||||
}
|
||||
|
||||
if (clazzField != null) {
|
||||
ConfigPath fieldPath = clazzField.getAnnotation(ConfigPath.class);
|
||||
if (fieldPath == null) return link(holder, parentPath, false, covertPath(clazzField.getName()));
|
||||
else return getFieldPath(holder, parentPath, clazzField);
|
||||
}
|
||||
|
||||
return link(holder, parentPath, false, covertPath(clazz.getSimpleName())); // No field, use class name.
|
||||
|
||||
}
|
||||
|
||||
protected String select(String path, String defaultValue) {
|
||||
if (path == null || path.isEmpty()) return defaultValue;
|
||||
else return isBlank(path) ? null : path;
|
||||
@@ -71,7 +72,7 @@ public class PathGenerator {
|
||||
protected @Nullable String link(@NotNull ConfigurationHolder<?> holder,
|
||||
@Nullable String parent, boolean root, @Nullable String path) {
|
||||
if (path == null || path.isEmpty()) return root ? null : parent;
|
||||
return root || parent == null ? path : parent + pathSeparator(holder) + path;
|
||||
return (root || parent == null) ? path : (parent + pathSeparator(holder) + path);
|
||||
}
|
||||
|
||||
public static boolean isBlank(String path) {
|
||||
|
||||
@@ -2,6 +2,8 @@ package cc.carm.lib.configuration.source.option;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ConfigurationOption<V> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -13,6 +15,10 @@ public class ConfigurationOption<V> {
|
||||
return new ConfigurationOption<>(valueClazz, defaultValue);
|
||||
}
|
||||
|
||||
public static <T> ConfigurationOption<T> of(@NotNull Supplier<T> defaultValue) {
|
||||
return of(defaultValue.get());
|
||||
}
|
||||
|
||||
private final @NotNull Class<V> valueClazz;
|
||||
private @NotNull V defaultValue;
|
||||
|
||||
|
||||
@@ -59,6 +59,11 @@ public abstract class ConfigureSource<
|
||||
return null; // Source also represents the root section, so it has no parent
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigureSource<?, ?, ?> source() {
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return section().getValues(deep);
|
||||
|
||||
@@ -7,6 +7,32 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a configurable value with type safety and null-handling capabilities.
|
||||
* <p>
|
||||
* This abstract class provides core functionalities for managing configuration values,
|
||||
* including value retrieval with fallback defaults, null safety enforcement, and value
|
||||
* persistence controls. It serves as the foundation for type-specific configuration
|
||||
* implementations.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Functions:</h3>
|
||||
* <ul>
|
||||
* <li>Type-safe value access through {@link #get()} and {@link #optional()}</li>
|
||||
* <li>Default value fallback via {@link #getOrDefault()}</li>
|
||||
* <li>Null-safety enforcement with {@link #resolve()} and {@link #getNotNull()}</li>
|
||||
* <li>Default value initialization through {@link #setDefault()}</li>
|
||||
* <li>Value comparison with {@link #isDefault()}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Persistence Behavior:</h3>
|
||||
* Value modifications via {@link #set(Object)} or {@link #setDefault()} methods
|
||||
* <b>do NOT automatically persist</b> to configuration sources. Explicit calls to
|
||||
* {@link ConfigurationHolder#save()} are required for permanent storage.
|
||||
*
|
||||
* @see ValueManifest Base class providing metadata and default value handling
|
||||
* @see ConfigurationHolder Responsible for configuration source persistence
|
||||
*/
|
||||
public abstract class ConfigValue<T> extends ValueManifest<T> {
|
||||
|
||||
protected ConfigValue(@NotNull ValueManifest<T> manifest) {
|
||||
@@ -14,57 +40,77 @@ public abstract class ConfigValue<T> extends ValueManifest<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到该配置的设定值(即读取到的值)。
|
||||
* <br> 若初始化时未写入默认值,则可以通过 {@link #getOrDefault()} 方法在该设定值为空时获取默认值。
|
||||
* Gets the configured value (i.e., the value read from the source).
|
||||
* <br> If no default value was written during initialization, you can use
|
||||
* the {@link #getOrDefault()} method to obtain the default value when this value is empty.
|
||||
*
|
||||
* @return 设定值
|
||||
* @return Configured value
|
||||
*/
|
||||
public abstract @Nullable T get();
|
||||
|
||||
/**
|
||||
* 得到该配置的设定值,若不存在,则返回默认值。
|
||||
* Gets the configured value, or returns the default value if not present.
|
||||
*
|
||||
* @return 设定值或默认值
|
||||
* @return Configured value or default value
|
||||
*/
|
||||
public T getOrDefault() {
|
||||
return optional().orElse(defaults());
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到该配置的非空值。
|
||||
* Gets the non-null value of this configuration.
|
||||
*
|
||||
* @return 非空值
|
||||
* @throws NullPointerException 对应数据为空时抛出
|
||||
* @return Non-null value
|
||||
* @throws NullPointerException Thrown when the corresponding data is null
|
||||
*/
|
||||
public @NotNull T getNotNull() {
|
||||
public @NotNull T resolve() {
|
||||
return Objects.requireNonNull(getOrDefault(), "Value(" + type() + ") @[" + path() + "] is null.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the non-null value of this configuration.
|
||||
*
|
||||
* @return Non-null value
|
||||
* @throws NullPointerException Thrown when the corresponding data is null
|
||||
* @see #resolve()
|
||||
*/
|
||||
public @NotNull T getNotNull() {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this configuration as an {@link Optional}.
|
||||
*
|
||||
* @return {@link Optional} value
|
||||
*/
|
||||
public @NotNull Optional<@Nullable T> optional() {
|
||||
return Optional.ofNullable(get());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设定该配置的值。
|
||||
* <br> 设定后,不会自动保存配置文件;若需要保存,请调用 {@link ConfigurationHolder#save()} 方法。
|
||||
* Sets the value of this configuration.
|
||||
* <br> After setting, the configuration file will NOT be saved automatically.
|
||||
* To save, call {@link ConfigurationHolder#save()}.
|
||||
*
|
||||
* @param value 配置的值
|
||||
* @param value The value to set
|
||||
*/
|
||||
public abstract void set(@Nullable T value);
|
||||
|
||||
/**
|
||||
* 初始化该配置的默认值。
|
||||
* <br> 设定后,不会自动保存配置文件;若需要保存,请调用 {@link ConfigurationHolder#save()} 方法。
|
||||
* Initializes the default value for this configuration.
|
||||
* <br> After setting, the configuration file will NOT be saved automatically.
|
||||
* To save, call {@link ConfigurationHolder#save()}.
|
||||
*/
|
||||
public void setDefault() {
|
||||
setDefault(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将该配置的值设置为默认值。
|
||||
* <br> 设定后,不会自动保存配置文件;若需要保存,请调用 {@link ConfigurationHolder#save()} 方法。
|
||||
* Sets the configuration value to its default.
|
||||
* <br> After setting, the configuration file will NOT be saved automatically.
|
||||
* To save, call {@link ConfigurationHolder#save()}.
|
||||
*
|
||||
* @param override 是否覆盖已设定的值
|
||||
* @param override Whether to overwrite existing configured value
|
||||
*/
|
||||
public void setDefault(boolean override) {
|
||||
if (!override && config().contains(path())) return;
|
||||
@@ -72,9 +118,9 @@ public abstract class ConfigValue<T> extends ValueManifest<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断加载的配置是否与默认值相同。
|
||||
* Checks if the loaded configuration value matches the default value.
|
||||
*
|
||||
* @return 获取当前值是否为默认值。
|
||||
* @return Whether the current value is the default value
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return Objects.equals(defaults(), get());
|
||||
@@ -86,7 +132,7 @@ public abstract class ConfigValue<T> extends ValueManifest<T> {
|
||||
* it is recommended to call {@link ConfigurationHolder#save()}
|
||||
* after all modifications are completed instead of this.
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws Exception Thrown when an error occurs during saving
|
||||
*/
|
||||
public void save() throws Exception {
|
||||
holder().save();
|
||||
|
||||
@@ -111,22 +111,22 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements Lis
|
||||
|
||||
@Override
|
||||
public V get(int index) {
|
||||
return getNotNull().get(index);
|
||||
return resolve().get(index);
|
||||
}
|
||||
|
||||
public @NotNull List<V> copy() {
|
||||
return new ArrayList<>(getNotNull());
|
||||
return new ArrayList<>(resolve());
|
||||
}
|
||||
|
||||
public <T> @NotNull T handle(Function<List<V>, T> function) {
|
||||
List<V> list = getNotNull();
|
||||
List<V> list = resolve();
|
||||
T result = function.apply(list);
|
||||
set(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
public @NotNull ConfiguredList<V> modify(Consumer<List<V>> consumer) {
|
||||
List<V> list = getNotNull();
|
||||
List<V> list = resolve();
|
||||
consumer.accept(list);
|
||||
set(list);
|
||||
return this;
|
||||
@@ -139,40 +139,40 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements Lis
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return getNotNull().size();
|
||||
return resolve().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return getNotNull().isEmpty();
|
||||
return resolve().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return getNotNull().contains(o);
|
||||
return resolve().contains(o);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<V> iterator() {
|
||||
return getNotNull().iterator();
|
||||
return resolve().iterator();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object @NotNull [] toArray() {
|
||||
return getNotNull().toArray();
|
||||
return resolve().toArray();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> T @NotNull [] toArray(@NotNull T[] a) {
|
||||
return getNotNull().toArray(a);
|
||||
return resolve().toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(@NotNull Collection<?> c) {
|
||||
return new HashSet<>(getNotNull()).containsAll(c);
|
||||
return new HashSet<>(resolve()).containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -223,30 +223,30 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements Lis
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
return getNotNull().indexOf(o);
|
||||
return resolve().indexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
return getNotNull().lastIndexOf(o);
|
||||
return resolve().lastIndexOf(o);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ListIterator<V> listIterator() {
|
||||
return getNotNull().listIterator();
|
||||
return resolve().listIterator();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ListIterator<V> listIterator(int index) {
|
||||
return getNotNull().listIterator(index);
|
||||
return resolve().listIterator(index);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<V> subList(int fromIndex, int toIndex) {
|
||||
return getNotNull().subList(fromIndex, toIndex);
|
||||
return resolve().subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapter;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
||||
import cc.carm.lib.configuration.source.option.ConfigurationOptionHolder;
|
||||
import cc.carm.test.config.TestSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalTime;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class AdaptTest {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
|
||||
ValueAdapterRegistry registry = new ValueAdapterRegistry();
|
||||
registry.register(PrimitiveAdapter.ADAPTERS);
|
||||
registry.register(PrimitiveAdapter.ofEnum());
|
||||
|
||||
|
||||
registry.register(ValueType.of(Long.class), ValueType.of(Duration.class), Duration::ofMillis, Duration::toMillis);
|
||||
registry.register(
|
||||
ValueType.of(Duration.class), ValueType.of(LocalTime.class),
|
||||
duration -> LocalTime.now().plus(duration),
|
||||
data -> Duration.between(LocalTime.now(), data)
|
||||
);
|
||||
|
||||
ConfigurationHolder<TestSource> provider = new ConfigurationHolder<TestSource>(
|
||||
registry, new ConfigurationOptionHolder(),
|
||||
new ConcurrentHashMap<>(), new ConfigurationInitializer()
|
||||
) {
|
||||
final TestSource source = new TestSource(this, System.currentTimeMillis());
|
||||
|
||||
@Override
|
||||
public @NotNull TestSource config() {
|
||||
return source;
|
||||
}
|
||||
};
|
||||
|
||||
LocalTime v = registry.deserialize(provider, LocalTime.class, 600000L);
|
||||
Object d = registry.serialize(provider, v);
|
||||
|
||||
System.out.println(v);
|
||||
System.out.println(d);
|
||||
System.out.println(registry.deserialize(provider, TestEnum.class, "C"));
|
||||
System.out.println(registry.serialize(provider, TestEnum.C).getClass());
|
||||
}
|
||||
|
||||
enum TestEnum {
|
||||
A, b, C
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package cc.carm.test.config;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||
import cc.carm.lib.configuration.Configuration;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
||||
import cc.carm.lib.configuration.source.option.ConfigurationOptionHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LoaderTest {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
ConfigurationHolder<TestSource> provider = new ConfigurationHolder<TestSource>(
|
||||
new ValueAdapterRegistry(), new ConfigurationOptionHolder(),
|
||||
new ConcurrentHashMap<>(), new ConfigurationInitializer()
|
||||
) {
|
||||
final TestSource source = new TestSource(this, System.currentTimeMillis());
|
||||
|
||||
@Override
|
||||
public @NotNull TestSource config() {
|
||||
return source;
|
||||
}
|
||||
};
|
||||
|
||||
ConfigurationInitializer loader = new ConfigurationInitializer();
|
||||
loader.initialize(provider, ROOT.class);
|
||||
}
|
||||
|
||||
interface ROOT extends Configuration {
|
||||
|
||||
interface SUB extends Configuration {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ConfigPath(root = true)
|
||||
interface EXTERNAL extends Configuration {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ConfigPath("NO")
|
||||
interface YES extends Configuration {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package cc.carm.test.config;
|
||||
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestSection implements ConfigureSection {
|
||||
@Override
|
||||
public @NotNull ConfigureSource<?, ?, ?> source() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList(@NotNull String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<?> getList(@NotNull String path) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSection(@NotNull String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigureSection getSection(@NotNull String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package cc.carm.test.config;
|
||||
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TestSource extends ConfigureSource<TestSection, Map<String, String>, TestSource> {
|
||||
|
||||
|
||||
public TestSource(@NotNull ConfigurationHolder<? extends TestSource> holder, long lastUpdateMillis) {
|
||||
super(holder, lastUpdateMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TestSource self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReload() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, String> original() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestSection section() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigureSource<?, ?, ?> source() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -69,14 +69,14 @@ public class ConfigurationTest {
|
||||
provider.initialize(TEST);
|
||||
|
||||
System.out.println("> Test Inner value before:");
|
||||
System.out.println(TEST.INSTANCE.INNER_VALUE.getNotNull());
|
||||
System.out.println(TEST.INSTANCE.INNER_VALUE.resolve());
|
||||
|
||||
double after = Math.random() * 200D;
|
||||
System.out.println("> Test Inner value -> " + after);
|
||||
TEST.INSTANCE.INNER_VALUE.set(after);
|
||||
|
||||
System.out.println("> Test Inner value after:");
|
||||
System.out.println(TEST.INSTANCE.INNER_VALUE.getNotNull());
|
||||
System.out.println(TEST.INSTANCE.INNER_VALUE.resolve());
|
||||
|
||||
}
|
||||
|
||||
|
||||
+31
-4
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
+37
-27
@@ -1,34 +1,39 @@
|
||||
package cc.carm.lib.configuration.source.json;
|
||||
package cc.carm.lib.configuration.source.section;
|
||||
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class JSONSection implements ConfigureSection {
|
||||
public class MemorySection implements ConfigureSection {
|
||||
|
||||
protected final @NotNull ConfigureSource<? extends JSONSection, ?, ?> source;
|
||||
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 JSONSection parent;
|
||||
protected final @Nullable MemorySection parent;
|
||||
|
||||
public JSONSection(@NotNull ConfigureSource<? extends JSONSection, ?, ?> source,
|
||||
@NotNull Map<?, ?> data, @Nullable JSONSection 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, new JSONSection(source, (Map<?, ?>) entry.getValue(), this));
|
||||
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(new JSONSection(source, (Map<?, ?>) obj, this));
|
||||
list.add(createChild((Map<?, ?>) obj));
|
||||
} else {
|
||||
list.add(obj);
|
||||
}
|
||||
@@ -40,8 +45,16 @@ public class JSONSection implements ConfigureSection {
|
||||
}
|
||||
}
|
||||
|
||||
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 JSONSection, ?, ?> source() {
|
||||
public @NotNull ConfigureSource<? extends MemorySection, ?, ?> source() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
@@ -49,7 +62,7 @@ public class JSONSection implements ConfigureSection {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public @Nullable JSONSection parent() {
|
||||
public @Nullable MemorySection parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
@@ -64,11 +77,9 @@ public class JSONSection implements ConfigureSection {
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
if (value instanceof Map) {
|
||||
value = new JSONSection(source(), (Map<?, ?>) value, this);
|
||||
}
|
||||
if (value instanceof Map) value = createChild((Map<?, ?>) value);
|
||||
|
||||
JSONSection section = getSectionFor(path);
|
||||
MemorySection section = getSectionFor(path);
|
||||
if (section == this) {
|
||||
if (value == null) {
|
||||
this.data.remove(path);
|
||||
@@ -87,7 +98,7 @@ public class JSONSection implements ConfigureSection {
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
JSONSection section = getSectionFor(path);
|
||||
MemorySection section = getSectionFor(path);
|
||||
return section == this ? data.get(path) : section.get(getChild(path));
|
||||
}
|
||||
|
||||
@@ -104,7 +115,7 @@ public class JSONSection implements ConfigureSection {
|
||||
|
||||
@Override
|
||||
public boolean isSection(@NotNull String path) {
|
||||
return get(path) instanceof JSONSection;
|
||||
return get(path) instanceof ConfigureSection;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,18 +124,18 @@ public class JSONSection implements ConfigureSection {
|
||||
return (val instanceof ConfigureSection) ? (ConfigureSection) val : null;
|
||||
}
|
||||
|
||||
private JSONSection getSectionFor(String path) {
|
||||
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 = new JSONSection(source(), new LinkedHashMap<>(), this);
|
||||
section = createChild();
|
||||
this.data.put(root, section);
|
||||
}
|
||||
|
||||
return (JSONSection) section;
|
||||
return (MemorySection) section;
|
||||
}
|
||||
|
||||
private String getChild(String path) {
|
||||
@@ -140,16 +151,15 @@ public class JSONSection implements ConfigureSection {
|
||||
* @param section The section to map the values from
|
||||
* @param parent The parent path
|
||||
* @param deep If the mapping should be deep
|
||||
* @author md_5, sk89q
|
||||
*/
|
||||
protected void mapChildrenValues(@NotNull Map<String, Object> output, @NotNull JSONSection section,
|
||||
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 JSONSection) {
|
||||
this.mapChildrenValues(output, (JSONSection) entry.getValue(), path, true);
|
||||
if (deep && entry.getValue() instanceof MemorySection) {
|
||||
this.mapChildrenValues(output, (MemorySection) entry.getValue(), path, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
<version>3.9.1</version>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>features/commentable</module>
|
||||
<module>features/section</module>
|
||||
<module>features/file</module>
|
||||
<module>features/commentable</module>
|
||||
<module>features/versioned</module>
|
||||
|
||||
<module>providers/yaml</module>
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>easyconfiguration-feature-section</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>easyconfiguration-demo</artifactId>
|
||||
|
||||
+5
-6
@@ -28,7 +28,7 @@ public class JSONConfigFactory extends FileConfigFactory<JSONSource, Configurati
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONConfigFactory self() {
|
||||
protected JSONConfigFactory self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -37,10 +37,6 @@ public class JSONConfigFactory extends FileConfigFactory<JSONSource, Configurati
|
||||
return self();
|
||||
}
|
||||
|
||||
public JSONConfigFactory gson(@NotNull Gson gson) {
|
||||
return gson(() -> gson);
|
||||
}
|
||||
|
||||
public JSONConfigFactory gson(@NotNull Consumer<GsonBuilder> builder) {
|
||||
return gson(() -> {
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
@@ -49,6 +45,9 @@ public class JSONConfigFactory extends FileConfigFactory<JSONSource, Configurati
|
||||
});
|
||||
}
|
||||
|
||||
public JSONConfigFactory gson(@NotNull Gson gson) {
|
||||
return gson(() -> gson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigurationHolder<JSONSource> build() {
|
||||
@@ -59,7 +58,7 @@ public class JSONConfigFactory extends FileConfigFactory<JSONSource, Configurati
|
||||
String sourcePath = this.resourcePath;
|
||||
|
||||
return new ConfigurationHolder<JSONSource>(this.adapters, this.options, new ConcurrentHashMap<>(), this.initializer) {
|
||||
final JSONSource source = new JSONSource(this, 0, configFile, sourcePath, gson);
|
||||
final JSONSource source = new JSONSource(this, configFile, sourcePath, gson);
|
||||
|
||||
@Override
|
||||
public @NotNull JSONSource config() {
|
||||
|
||||
+22
-21
@@ -2,36 +2,38 @@ package cc.carm.lib.configuration.source.json;
|
||||
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.file.FileConfigSource;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import cc.carm.lib.configuration.source.section.MemorySection;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class JSONSource extends FileConfigSource<JSONSection, Map<?, ?>, JSONSource> {
|
||||
public class JSONSource extends FileConfigSource<MemorySection, Map<?, ?>, JSONSource> {
|
||||
|
||||
public static final @NotNull Gson DEFAULT_GSON = new GsonBuilder()
|
||||
.serializeNulls().disableHtmlEscaping().setPrettyPrinting()
|
||||
.registerTypeAdapter(
|
||||
JSONSection.class,
|
||||
(JsonSerializer<JSONSection>) (src, typeOfSrc, context) -> context.serialize(src.data)
|
||||
MemorySection.class,
|
||||
(JsonSerializer<MemorySection>) (src, t, c) -> c.serialize(src.data())
|
||||
).create();
|
||||
|
||||
protected final @NotNull Gson gson;
|
||||
protected @Nullable JSONSection rootSection;
|
||||
protected @Nullable MemorySection rootSection;
|
||||
|
||||
protected JSONSource(@NotNull ConfigurationHolder<? extends JSONSource> holder, long lastUpdateMillis,
|
||||
protected JSONSource(@NotNull ConfigurationHolder<? extends JSONSource> holder,
|
||||
@NotNull File file, @Nullable String resourcePath) {
|
||||
this(holder, lastUpdateMillis, file, resourcePath, DEFAULT_GSON);
|
||||
this(holder, file, resourcePath, DEFAULT_GSON);
|
||||
}
|
||||
|
||||
protected JSONSource(@NotNull ConfigurationHolder<? extends JSONSource> holder, long lastUpdateMillis,
|
||||
protected JSONSource(@NotNull ConfigurationHolder<? extends JSONSource> holder,
|
||||
@NotNull File file, @Nullable String resourcePath, @NotNull Gson gson) {
|
||||
super(holder, lastUpdateMillis, file, resourcePath);
|
||||
super(holder, 0, file, resourcePath);
|
||||
this.gson = gson;
|
||||
initialize();
|
||||
}
|
||||
@@ -50,19 +52,14 @@ public class JSONSource extends FileConfigSource<JSONSection, Map<?, ?>, JSONSou
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigureSource<?, ?, ?> source() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<?, ?> original() {
|
||||
return section().data();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull JSONSection section() {
|
||||
return Objects.requireNonNull(this.rootSection, "Section is not initialized");
|
||||
public @NotNull MemorySection section() {
|
||||
return Objects.requireNonNull(this.rootSection, "Root section is not initialized");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,11 +67,15 @@ public class JSONSource extends FileConfigSource<JSONSection, Map<?, ?>, JSONSou
|
||||
fileWriter(writer -> gson.toJson(original(), writer));
|
||||
}
|
||||
|
||||
public @NotNull String saveToString() {
|
||||
return gson.toJson(original());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReload() throws Exception {
|
||||
Map<?, ?> data = fileReader(reader -> gson.fromJson(reader, LinkedHashMap.class));
|
||||
if (data == null) data = new LinkedHashMap<>();
|
||||
this.rootSection = new JSONSection(this, data, null);
|
||||
this.rootSection = MemorySection.root(
|
||||
this, fileReader(reader -> gson.fromJson(reader, LinkedHashMap.class))
|
||||
);
|
||||
this.lastUpdateMillis = System.currentTimeMillis(); // 更新时间
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,20 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>easyconfiguration-feature-section</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>easyconfiguration-feature-commentable</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
package cc.carm.lib.configuration.source.yaml;
|
||||
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnmodifiableView;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class YAMLSection implements ConfigureSection {
|
||||
|
||||
protected final @NotNull ConfigureSource<? extends YAMLSection, ?, ?> source;
|
||||
protected final @NotNull Map<String, Object> data;
|
||||
protected final @Nullable YAMLSection parent;
|
||||
|
||||
public YAMLSection(@NotNull ConfigureSource<? extends YAMLSection, ?, ?> source,
|
||||
@NotNull Map<String, Object> data, @Nullable YAMLSection parent) {
|
||||
this.source = source;
|
||||
this.data = data;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigureSource<?, ?, ?> source() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YAMLSection parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull @UnmodifiableView Map<String, Object> getValues(boolean deep) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList(@NotNull String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<?> getList(@NotNull String path) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSection(@NotNull String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YAMLSection getSection(@NotNull String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package sample;
|
||||
|
||||
public class Sample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 1. Make a configuration provider from a file.
|
||||
ConfigurationProvider<?> provider = EasyConfiguration.from("config.yml");
|
||||
// 2. Initialize the configuration classes or instances.
|
||||
provider.initialize(SampleConfig.class);
|
||||
// 3. Enjoy using the configuration!
|
||||
SampleConfig.ENABLED.set(false);
|
||||
System.out.println("Your name is " + SampleConfig.INFO.NAME.getNotNull() + " !");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package sample;
|
||||
|
||||
import cc.carm.lib.configuration.source.Configuration;
|
||||
import cc.carm.lib.configuration.Configuration;
|
||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||
import cc.carm.lib.configuration.annotation.InlineComment;
|
||||
@@ -9,6 +9,7 @@ import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ConfigPath(root = true)
|
||||
@HeaderComment("Configurations for sample")
|
||||
public interface SampleConfig extends Configuration {
|
||||
|
||||
@@ -16,12 +17,13 @@ public interface SampleConfig extends Configuration {
|
||||
ConfiguredValue<Boolean> ENABLED = ConfiguredValue.of(true);
|
||||
|
||||
ConfiguredList<UUID> UUIDS = ConfiguredList.builderOf(UUID.class).fromString()
|
||||
.parseValue(UUID::fromString).serializeValue(UUID::toString)
|
||||
.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 {
|
||||
|
||||
@HeaderComment("Configure your name!") // Header comment
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package sample;
|
||||
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.yaml.YAMLConfigFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SampleTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
// 1. Make a configuration provider from a file.
|
||||
ConfigurationHolder<?> holder = YAMLConfigFactory.from("target/config.yml")
|
||||
.resourcePath("configs/sample.yml")
|
||||
.indent(4) // Optional: Set the indentation of the configuration file.
|
||||
.build();
|
||||
|
||||
// 2. Initialize the configuration classes or instances.
|
||||
holder.initialize(SampleConfig.class);
|
||||
// 3. Enjoy using the configuration!
|
||||
SampleConfig.ENABLED.set(false);
|
||||
System.out.println("Your name is " + SampleConfig.INFO.NAME.resolve() + " (age=" + SampleConfig.INFO.AGE.resolve() + ")!");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user