mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
feat(json): Implement json sources
This commit is contained in:
@@ -55,13 +55,13 @@ public class ValueAdapter<TYPE>
|
||||
@Override
|
||||
public Object serialize(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<? super TYPE> type, @NotNull TYPE value) throws Exception {
|
||||
if (serializer == null) throw new UnsupportedOperationException("Serializer is not supported");
|
||||
return serializer.serialize(provider, type, value);
|
||||
return serializer.serialize(holder, type, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TYPE parse(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<? super TYPE> type, @NotNull Object value) throws Exception {
|
||||
if (deserializer == null) throw new UnsupportedOperationException("Deserializer is not supported");
|
||||
return deserializer.parse(provider, type, value);
|
||||
return deserializer.parse(holder, type, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -101,7 +101,7 @@ public class ValueAdapterRegistry {
|
||||
|
||||
@Contract("_,_,null -> null")
|
||||
public <T> T deserialize(@NotNull ConfigurationHolder<?> holder, @NotNull Class<T> type, @Nullable Object source) throws Exception {
|
||||
return deserialize(provider, ValueType.of(type), source);
|
||||
return deserialize(holder, ValueType.of(type), source);
|
||||
}
|
||||
|
||||
@Contract("_,_,null -> null")
|
||||
@@ -110,7 +110,7 @@ public class ValueAdapterRegistry {
|
||||
if (type.isInstance(source)) return type.cast(source); // Not required to deserialize
|
||||
ValueAdapter<T> adapter = adapterOf(type);
|
||||
if (adapter == null) throw new RuntimeException("No adapter for type " + type);
|
||||
return adapter.parse(provider, type, source);
|
||||
return adapter.parse(holder, type, source);
|
||||
}
|
||||
|
||||
@Contract("_,null -> null")
|
||||
@@ -119,7 +119,7 @@ public class ValueAdapterRegistry {
|
||||
ValueType<T> type = ValueType.of(value);
|
||||
ValueAdapter<T> adapter = adapterOf(type);
|
||||
if (adapter == null) return value; // No adapters, try to return the original value
|
||||
return adapter.serialize(provider, type, value);
|
||||
return adapter.serialize(holder, type, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package cc.carm.lib.configuration.adapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -12,12 +11,45 @@ import java.util.Objects;
|
||||
*/
|
||||
public abstract class ValueType<T> {
|
||||
|
||||
public static final ValueType<String> STRING = ofPrimitiveType(String.class);
|
||||
public static final ValueType<Integer> INTEGER = ofPrimitiveType(Integer.class);
|
||||
public static final ValueType<Integer> INTEGER_TYPE = ofPrimitiveType(int.class);
|
||||
public static final ValueType<Long> LONG = ofPrimitiveType(Long.class);
|
||||
public static final ValueType<Long> LONG_TYPE = ofPrimitiveType(long.class);
|
||||
public static final ValueType<Double> DOUBLE = ofPrimitiveType(Double.class);
|
||||
public static final ValueType<Double> DOUBLE_TYPE = ofPrimitiveType(double.class);
|
||||
public static final ValueType<Float> FLOAT = ofPrimitiveType(Float.class);
|
||||
public static final ValueType<Float> FLOAT_TYPE = ofPrimitiveType(float.class);
|
||||
public static final ValueType<Boolean> BOOLEAN = ofPrimitiveType(Boolean.class);
|
||||
public static final ValueType<Boolean> BOOLEAN_TYPE = ofPrimitiveType(boolean.class);
|
||||
public static final ValueType<Byte> BYTE = ofPrimitiveType(Byte.class);
|
||||
public static final ValueType<Byte> BYTE_TYPE = ofPrimitiveType(byte.class);
|
||||
public static final ValueType<Short> SHORT = ofPrimitiveType(Short.class);
|
||||
public static final ValueType<Short> SHORT_TYPE = ofPrimitiveType(short.class);
|
||||
public static final ValueType<Character> CHAR = ofPrimitiveType(Character.class);
|
||||
public static final ValueType<Character> CHAR_TYPE = ofPrimitiveType(char.class);
|
||||
|
||||
public static final ValueType<?>[] PRIMITIVE_TYPES = {
|
||||
STRING, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, BYTE, SHORT, CHAR,
|
||||
INTEGER_TYPE, LONG_TYPE, DOUBLE_TYPE, FLOAT_TYPE, BOOLEAN_TYPE, BYTE_TYPE, SHORT_TYPE, CHAR_TYPE
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> ValueType<T> of(@NotNull T value) {
|
||||
return of((Class<T>) value.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> ValueType<T> of(final Type type) {
|
||||
if (type == null) throw new NullPointerException("Type cannot be null");
|
||||
if (type instanceof Class<?>) { // Try handle primitive types
|
||||
Class<?> clazz = (Class<?>) type;
|
||||
for (ValueType<?> valueType : PRIMITIVE_TYPES) {
|
||||
if (valueType.getRawType() == clazz) {
|
||||
return (ValueType<T>) valueType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ValueType<T>(type) {
|
||||
};
|
||||
}
|
||||
@@ -54,6 +86,11 @@ public abstract class ValueType<T> {
|
||||
return of(parameterizedType);
|
||||
}
|
||||
|
||||
private static <T> ValueType<T> ofPrimitiveType(Class<T> clazz) {
|
||||
return new ValueType<T>(clazz) {
|
||||
};
|
||||
}
|
||||
|
||||
private final Type type;
|
||||
|
||||
protected ValueType() {
|
||||
@@ -139,6 +176,9 @@ public abstract class ValueType<T> {
|
||||
if (obj instanceof ValueType) {
|
||||
return Objects.equals(type, ((ValueType<?>) obj).type);
|
||||
}
|
||||
if (obj instanceof Type) {
|
||||
return Objects.equals(type, obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -2,16 +2,16 @@ package cc.carm.lib.configuration.adapter.strandard;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
|
||||
public interface StandardAdapters {
|
||||
|
||||
ValueAdapter<ConfigurationSection> SECTION_ADAPTER = new ValueAdapter<>(
|
||||
ValueType.of(ConfigurationSection.class),
|
||||
ValueAdapter<ConfigureSection> SECTION_ADAPTER = new ValueAdapter<>(
|
||||
ValueType.of(ConfigureSection.class),
|
||||
(provider, type, value) -> value,
|
||||
(provider, type, value) -> {
|
||||
if (value instanceof ConfigurationSection) {
|
||||
return (ConfigurationSection) value;
|
||||
if (value instanceof ConfigureSection) {
|
||||
return (ConfigureSection) value;
|
||||
} else throw new IllegalArgumentException("Value is not a ConfigurationSection");
|
||||
}
|
||||
);
|
||||
|
||||
+13
-13
@@ -5,7 +5,7 @@ import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||
import cc.carm.lib.configuration.function.DataFunction;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.value.ConfigValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -21,39 +21,39 @@ public abstract class AbstractSectionBuilder<
|
||||
|
||||
protected final @NotNull ValueType<PARAM> paramType;
|
||||
|
||||
protected @NotNull ValueHandler<ConfigurationSection, PARAM> parser;
|
||||
protected @NotNull ValueHandler<PARAM, ? extends Map<Object, Object>> serializer;
|
||||
protected @NotNull ValueHandler<ConfigureSection, PARAM> parser;
|
||||
protected @NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer;
|
||||
|
||||
public AbstractSectionBuilder(@NotNull ValueType<TYPE> type, @NotNull ValueType<PARAM> paramType,
|
||||
@NotNull ValueHandler<ConfigurationSection, PARAM> parser,
|
||||
@NotNull ValueHandler<PARAM, ? extends Map<Object, Object>> serializer) {
|
||||
@NotNull ValueHandler<ConfigureSection, PARAM> parser,
|
||||
@NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer) {
|
||||
super(type);
|
||||
this.paramType = paramType;
|
||||
this.parser = parser;
|
||||
this.serializer = serializer;
|
||||
}
|
||||
|
||||
public @NotNull SELF parse(DataFunction<ConfigurationSection, PARAM> valueParser) {
|
||||
public @NotNull SELF parse(DataFunction<ConfigureSection, PARAM> valueParser) {
|
||||
return parse((p, section) -> valueParser.handle(section));
|
||||
}
|
||||
|
||||
public @NotNull SELF parse(ValueHandler<ConfigurationSection, PARAM> valueParser) {
|
||||
public @NotNull SELF parse(ValueHandler<ConfigureSection, PARAM> valueParser) {
|
||||
this.parser = valueParser;
|
||||
return self();
|
||||
}
|
||||
|
||||
public @NotNull SELF serialize(DataFunction<PARAM, ? extends Map<Object, Object>> serializer) {
|
||||
public @NotNull SELF serialize(DataFunction<PARAM, ? extends Map<String, Object>> serializer) {
|
||||
return serialize((p, value) -> serializer.handle(value));
|
||||
}
|
||||
|
||||
public @NotNull SELF serialize(ValueHandler<PARAM, ? extends Map<Object, Object>> serializer) {
|
||||
public @NotNull SELF serialize(ValueHandler<PARAM, ? extends Map<String, Object>> serializer) {
|
||||
this.serializer = serializer;
|
||||
return self();
|
||||
}
|
||||
|
||||
public @NotNull SELF serialize(Consumer<Map<Object, Object>> serializer) {
|
||||
public @NotNull SELF serialize(Consumer<Map<String, Object>> serializer) {
|
||||
return serialize((p, value) -> {
|
||||
Map<Object, Object> map = new LinkedHashMap<>();
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
serializer.accept(map);
|
||||
return map;
|
||||
});
|
||||
@@ -62,12 +62,12 @@ public abstract class AbstractSectionBuilder<
|
||||
protected ValueAdapter<PARAM> buildAdapter() {
|
||||
return new ValueAdapter<>(this.paramType)
|
||||
.parser((p, type, data) -> {
|
||||
ConfigurationSection section = p.deserialize(ConfigurationSection.class, data);
|
||||
ConfigureSection section = p.deserialize(ConfigureSection.class, data);
|
||||
if (section == null) return null;
|
||||
return this.parser.handle(p, section);
|
||||
})
|
||||
.serializer((p, type, data) -> {
|
||||
Map<Object, Object> map = this.serializer.handle(p, data);
|
||||
Map<String, Object> map = this.serializer.handle(p, data);
|
||||
return map == null || map.isEmpty() ? null : map;
|
||||
});
|
||||
}
|
||||
|
||||
+6
-6
@@ -49,13 +49,13 @@ public abstract class AbstractSourceBuilder<
|
||||
|
||||
protected ValueAdapter<PARAM> buildAdapter() {
|
||||
return new ValueAdapter<>(this.paramType)
|
||||
.parser((p, type, data) -> {
|
||||
SOURCE source = p.deserialize(this.sourceType, data);
|
||||
return this.valueParser.handle(p, source);
|
||||
.parser((holder, type, data) -> {
|
||||
SOURCE source = holder.deserialize(this.sourceType, data);
|
||||
return this.valueParser.handle(holder, source);
|
||||
})
|
||||
.serializer((p, type, data) -> {
|
||||
SOURCE source = this.valueSerializer.handle(p, data);
|
||||
return p.serialize(source);
|
||||
.serializer((holder, type, data) -> {
|
||||
SOURCE source = this.valueSerializer.handle(holder, data);
|
||||
return holder.serialize(source);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ConfigListBuilder<V> {
|
||||
}
|
||||
|
||||
public @NotNull SourceListBuilder<String, V> fromString() {
|
||||
return from(String.class);
|
||||
return new SourceListBuilder<>(ValueType.STRING, type, ValueHandler.required(), ValueHandler.stringValue(), ArrayList::new);
|
||||
}
|
||||
|
||||
public @NotNull SectionListBuilder<V> fromSection() {
|
||||
|
||||
@@ -3,7 +3,7 @@ package cc.carm.lib.configuration.builder.list;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -15,8 +15,8 @@ public class SectionListBuilder<V> extends AbstractSectionBuilder<List<V>, V, Co
|
||||
protected @NotNull Supplier<? extends List<V>> constructor;
|
||||
|
||||
public SectionListBuilder(@NotNull ValueType<V> paramType,
|
||||
@NotNull ValueHandler<ConfigurationSection, V> parser,
|
||||
@NotNull ValueHandler<V, ? extends Map<Object, Object>> serializer,
|
||||
@NotNull ValueHandler<ConfigureSection, V> parser,
|
||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer,
|
||||
@NotNull Supplier<? extends List<V>> constructor) {
|
||||
super(new ValueType<List<V>>() {
|
||||
}, paramType, parser, serializer);
|
||||
|
||||
@@ -2,7 +2,7 @@ package cc.carm.lib.configuration.builder.value;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -30,7 +30,7 @@ public class ConfigValueBuilder<V> {
|
||||
}
|
||||
|
||||
public @NotNull SourceValueBuilder<String, V> fromString() {
|
||||
return from(String.class);
|
||||
return from(ValueType.STRING, ValueHandler.required(), ValueHandler.stringValue());
|
||||
}
|
||||
|
||||
public @NotNull SectionValueBuilder<V> fromSection() {
|
||||
@@ -38,8 +38,8 @@ public class ConfigValueBuilder<V> {
|
||||
}
|
||||
|
||||
public @NotNull SectionValueBuilder<V> fromSection(
|
||||
@NotNull ValueHandler<ConfigurationSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, ? extends Map<Object, Object>> valueSerializer
|
||||
@NotNull ValueHandler<ConfigureSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> valueSerializer
|
||||
) {
|
||||
return new SectionValueBuilder<>(this.type, valueParser, valueSerializer);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package cc.carm.lib.configuration.builder.value;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -12,8 +12,8 @@ import java.util.Map;
|
||||
public class SectionValueBuilder<V> extends AbstractSectionBuilder<V, V, ConfiguredValue<V>, SectionValueBuilder<V>> {
|
||||
|
||||
public SectionValueBuilder(@NotNull ValueType<V> type,
|
||||
@NotNull ValueHandler<ConfigurationSection, V> parser,
|
||||
@NotNull ValueHandler<V, ? extends Map<Object, Object>> serializer) {
|
||||
@NotNull ValueHandler<ConfigureSection, V> parser,
|
||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
|
||||
super(type, type, parser, serializer);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,11 @@ public interface ValueHandler<T, R> {
|
||||
return ConfigurationHolder::serialize;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T> @NotNull ValueHandler<T, String> stringValue() {
|
||||
return (provider, input) -> String.valueOf(input);
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T> @NotNull ValueHandler<Object, T> fromObject(ValueType<T> type) {
|
||||
return (provider, input) -> provider.deserialize(type, input);
|
||||
|
||||
@@ -1,46 +1,38 @@
|
||||
package cc.carm.lib.configuration.source;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
||||
import cc.carm.lib.configuration.adapter.*;
|
||||
import cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapter;
|
||||
import cc.carm.lib.configuration.adapter.strandard.StandardAdapters;
|
||||
import cc.carm.lib.configuration.function.DataFunction;
|
||||
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
||||
import cc.carm.lib.configuration.source.loader.PathGenerator;
|
||||
import cc.carm.lib.configuration.source.meta.ConfigurationMetadata;
|
||||
import cc.carm.lib.configuration.source.option.ConfigurationOption;
|
||||
import cc.carm.lib.configuration.source.option.ConfigurationOptionHolder;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSource;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class ConfigurationFactory<SOURCE extends ConfigurationSource<SOURCE, ?>, PROVIDER extends ConfigurationHolder<SOURCE>, SELF> {
|
||||
|
||||
protected Function<PROVIDER, ConfigurationInitializer> loaderFunction = PROVIDER -> new ConfigurationInitializer();
|
||||
protected Consumer<ConfigurationInitializer> loaderConsumer = loader -> {
|
||||
};
|
||||
public abstract class ConfigurationFactory<
|
||||
SOURCE extends ConfigureSource<?, ?, SOURCE>,
|
||||
HOLDER extends ConfigurationHolder<SOURCE>,
|
||||
SELF
|
||||
> {
|
||||
|
||||
protected ValueAdapterRegistry adapters = new ValueAdapterRegistry();
|
||||
protected ConfigurationOptionHolder options = new ConfigurationOptionHolder();
|
||||
protected ConfigurationInitializer initializer = new ConfigurationInitializer();
|
||||
|
||||
public ConfigurationFactory() {
|
||||
this.adapters.register(PrimitiveAdapter.ADAPTERS);
|
||||
this.adapters.register(StandardAdapters.SECTION_ADAPTER);
|
||||
}
|
||||
|
||||
public abstract SELF self();
|
||||
|
||||
public SELF loader(Function<PROVIDER, ConfigurationInitializer> loaderFunction) {
|
||||
this.loaderFunction = loaderFunction;
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF loader(ConfigurationInitializer loader) {
|
||||
return loader(PROVIDER -> loader);
|
||||
}
|
||||
|
||||
public SELF loader(Consumer<ConfigurationInitializer> loaderConsumer) {
|
||||
this.loaderConsumer = this.loaderConsumer.andThen(loaderConsumer);
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF pathGenerator(PathGenerator generator) {
|
||||
return loader(loader -> {
|
||||
loader.pathGenerator(generator);
|
||||
});
|
||||
}
|
||||
|
||||
public SELF adapters(ValueAdapterRegistry adapters) {
|
||||
this.adapters = adapters;
|
||||
@@ -52,18 +44,37 @@ public abstract class ConfigurationFactory<SOURCE extends ConfigurationSource<SO
|
||||
return self();
|
||||
}
|
||||
|
||||
// public SELF adapter(@NotNull ValueAdapter<?, ?> adapter) {
|
||||
// return adapter(a -> a.register(adapter));
|
||||
// }
|
||||
//
|
||||
// public <T> SELF adapter(Class<T> clazz, @NotNull ValueAdapter<?, T> adapter) {
|
||||
// return adapter(a -> a.register(clazz, adapter));
|
||||
// }
|
||||
//
|
||||
// public <B, V> SELF adapter(Class<B> baseClass, Class<V> valueClass,
|
||||
// ConfigDataFunction<B, V> parser, ConfigDataFunction<V, B> serializer) {
|
||||
// return adapter(a -> a.register(baseClass, valueClass, parser, serializer));
|
||||
// }
|
||||
public <T> SELF adapter(@NotNull ValueAdapter<T> adapter) {
|
||||
return adapter(a -> a.register(adapter));
|
||||
}
|
||||
|
||||
public <T> SELF adapter(@NotNull ValueType<T> type, @NotNull ValueSerializer<T> serializer) {
|
||||
return adapter(a -> a.register(type, serializer));
|
||||
}
|
||||
|
||||
public <T> SELF adapter(@NotNull ValueType<T> type, @NotNull ValueParser<T> parser) {
|
||||
return adapter(a -> a.register(type, parser));
|
||||
}
|
||||
|
||||
public <FROM, TO> SELF adapter(@NotNull Class<FROM> from, @NotNull Class<TO> to,
|
||||
@NotNull DataFunction<FROM, TO> parser,
|
||||
@NotNull DataFunction<TO, FROM> serializer) {
|
||||
return adapter(a -> a.register(from, to, parser, serializer));
|
||||
}
|
||||
|
||||
public <FROM, TO> SELF adapter(@NotNull ValueType<FROM> from, @NotNull ValueType<TO> to,
|
||||
@NotNull DataFunction<FROM, TO> parser,
|
||||
@NotNull DataFunction<TO, FROM> serializer) {
|
||||
return adapter(a -> a.register(from, to, parser, serializer));
|
||||
}
|
||||
|
||||
public <T> SELF adapter(@NotNull ValueType<T> type, @NotNull ValueSerializer<T> serializer, @NotNull ValueParser<T> parser) {
|
||||
return adapter(a -> a.register(type, serializer, parser));
|
||||
}
|
||||
|
||||
public <T> SELF adapter(@NotNull Class<T> type, @NotNull ValueSerializer<T> serializer, @NotNull ValueParser<T> parser) {
|
||||
return adapter(ValueType.of(type), serializer, parser);
|
||||
}
|
||||
|
||||
public SELF options(ConfigurationOptionHolder options) {
|
||||
this.options = options;
|
||||
@@ -79,6 +90,29 @@ public abstract class ConfigurationFactory<SOURCE extends ConfigurationSource<SO
|
||||
return option(o -> o.set(option, value));
|
||||
}
|
||||
|
||||
public abstract @NotNull PROVIDER build();
|
||||
|
||||
public SELF initializer(ConfigurationInitializer initializer) {
|
||||
this.initializer = initializer;
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF initializer(Consumer<ConfigurationInitializer> initializerConsumer) {
|
||||
initializerConsumer.accept(initializer);
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF pathGenerator(PathGenerator generator) {
|
||||
return initializer(loader -> {
|
||||
loader.pathGenerator(generator);
|
||||
});
|
||||
}
|
||||
|
||||
public <M, A extends Annotation> SELF metaAnnotation(@NotNull Class<A> annotation,
|
||||
@NotNull ConfigurationMetadata<M> metadata,
|
||||
@NotNull Function<A, M> extractor) {
|
||||
return initializer(loader -> loader.registerAnnotation(annotation, metadata, extractor));
|
||||
}
|
||||
|
||||
public abstract @NotNull HOLDER build();
|
||||
|
||||
}
|
||||
|
||||
@@ -6,16 +6,15 @@ import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
||||
import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder;
|
||||
import cc.carm.lib.configuration.source.option.ConfigurationOptionHolder;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSource;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import cc.carm.lib.configuration.value.ValueManifest;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ConfigurationHolder<S extends ConfigurationSource<S, ?>> {
|
||||
public abstract class ConfigurationHolder<SOURCE extends ConfigureSource<?, ?, SOURCE>> {
|
||||
|
||||
protected final @NotNull ValueAdapterRegistry adapters;
|
||||
protected final @NotNull ConfigurationOptionHolder options;
|
||||
@@ -23,8 +22,6 @@ public class ConfigurationHolder<S extends ConfigurationSource<S, ?>> {
|
||||
|
||||
protected final @NotNull ConfigurationInitializer initializer;
|
||||
|
||||
protected @Nullable S source;
|
||||
|
||||
public ConfigurationHolder(@NotNull ValueAdapterRegistry adapters,
|
||||
@NotNull ConfigurationOptionHolder options,
|
||||
@NotNull Map<String, ConfigurationMetaHolder> metadata,
|
||||
@@ -35,16 +32,14 @@ public class ConfigurationHolder<S extends ConfigurationSource<S, ?>> {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public @NotNull S source() {
|
||||
return Objects.requireNonNull(source, "Source is not initialized");
|
||||
}
|
||||
public abstract @NotNull SOURCE config();
|
||||
|
||||
public void reload() throws Exception {
|
||||
source().reload();
|
||||
config().reload();
|
||||
}
|
||||
|
||||
public void save() throws Exception {
|
||||
source().save();
|
||||
config().save();
|
||||
}
|
||||
|
||||
public ConfigurationOptionHolder options() {
|
||||
@@ -83,7 +78,7 @@ public class ConfigurationHolder<S extends ConfigurationSource<S, ?>> {
|
||||
return adapters().serialize(this, value);
|
||||
}
|
||||
|
||||
public void load(Class<? extends Configuration> configClass) {
|
||||
public void initialize(Class<? extends Configuration> configClass) {
|
||||
try {
|
||||
initializer.initialize(this, configClass);
|
||||
} catch (Exception e) {
|
||||
@@ -91,7 +86,7 @@ public class ConfigurationHolder<S extends ConfigurationSource<S, ?>> {
|
||||
}
|
||||
}
|
||||
|
||||
public void load(@NotNull Configuration config) {
|
||||
public void initialize(@NotNull Configuration config) {
|
||||
try {
|
||||
initializer.initialize(this, config);
|
||||
} catch (Exception e) {
|
||||
@@ -99,7 +94,7 @@ public class ConfigurationHolder<S extends ConfigurationSource<S, ?>> {
|
||||
}
|
||||
}
|
||||
|
||||
public void load(@NotNull ValueManifest<?> value) {
|
||||
public void initialize(@NotNull ValueManifest<?> value) {
|
||||
value.holder(this);
|
||||
}
|
||||
|
||||
|
||||
+23
-23
@@ -70,49 +70,49 @@ public class ConfigurationInitializer {
|
||||
public <T, A extends Annotation> void registerAnnotation(@NotNull Class<A> annotation,
|
||||
@NotNull ConfigurationMetadata<T> metadata,
|
||||
@NotNull Function<A, T> extractor) {
|
||||
appendFieldInitializer((provider, path, field) -> {
|
||||
appendFieldInitializer((holder, path, field) -> {
|
||||
A data = field.getAnnotation(annotation);
|
||||
if (data == null) return;
|
||||
provider.metadata(path).setIfAbsent(metadata, extractor.apply(data));
|
||||
holder.metadata(path).setIfAbsent(metadata, extractor.apply(data));
|
||||
});
|
||||
appendClassInitializer((provider, path, clazz) -> {
|
||||
appendClassInitializer((holder, path, clazz) -> {
|
||||
A data = clazz.getAnnotation(annotation);
|
||||
if (data == null) return;
|
||||
provider.metadata(path).setIfAbsent(metadata, extractor.apply(data));
|
||||
holder.metadata(path).setIfAbsent(metadata, extractor.apply(data));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public @Nullable String getFieldPath(ConfigurationHolder<?> holder, @Nullable String parentPath, @NotNull Field field) {
|
||||
return pathGenerator.getFieldPath(provider, parentPath, field);
|
||||
return pathGenerator.getFieldPath(holder, parentPath, field);
|
||||
}
|
||||
|
||||
public @Nullable String getClassPath(ConfigurationHolder<?> holder, @Nullable String parentPath,
|
||||
@NotNull Class<?> clazz, @Nullable Field clazzField) {
|
||||
return pathGenerator.getClassPath(provider, parentPath, clazz, clazzField);
|
||||
return pathGenerator.getClassPath(holder, parentPath, clazz, clazzField);
|
||||
}
|
||||
|
||||
public void initialize(ConfigurationHolder<?> holder, @NotNull Configuration config) throws Exception {
|
||||
initializeInstance(provider, config, null, null);
|
||||
if (provider.options().get(StandardOptions.SET_DEFAULTS)) provider.save();
|
||||
initializeInstance(holder, config, null, null);
|
||||
if (holder.options().get(StandardOptions.SET_DEFAULTS)) holder.save();
|
||||
}
|
||||
|
||||
public void initialize(ConfigurationHolder<?> holder, @NotNull Class<? extends Configuration> clazz) throws Exception {
|
||||
initializeStaticClass(provider, clazz, null, null);
|
||||
if (provider.options().get(StandardOptions.SET_DEFAULTS)) provider.save();
|
||||
initializeStaticClass(holder, clazz, null, null);
|
||||
if (holder.options().get(StandardOptions.SET_DEFAULTS)) holder.save();
|
||||
}
|
||||
|
||||
|
||||
// 针对实例类的初始化方法
|
||||
protected void initializeInstance(@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull Configuration root, @Nullable String parentPath, @Nullable Field configField) {
|
||||
String path = getClassPath(provider, parentPath, root.getClass(), configField);
|
||||
String path = getClassPath(holder, parentPath, root.getClass(), configField);
|
||||
try {
|
||||
this.classInitializer.whenInitialize(provider, path, root.getClass());
|
||||
this.classInitializer.whenInitialize(holder, path, root.getClass());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Arrays.stream(root.getClass().getDeclaredFields()).forEach(field -> initializeField(provider, root, field, path));
|
||||
Arrays.stream(root.getClass().getDeclaredFields()).forEach(field -> initializeField(holder, root, field, path));
|
||||
}
|
||||
|
||||
// 针对静态类的初始化方法
|
||||
@@ -121,22 +121,22 @@ public class ConfigurationInitializer {
|
||||
@NotNull Class<?> clazz, @Nullable String parentPath, @Nullable Field configField) {
|
||||
if (!Configuration.class.isAssignableFrom(clazz)) return; // 只解析继承了 ConfigurationRoot 的类
|
||||
|
||||
String path = getClassPath(provider, parentPath, clazz, configField);
|
||||
String path = getClassPath(holder, parentPath, clazz, configField);
|
||||
|
||||
try {
|
||||
this.classInitializer.whenInitialize(provider, path, (Class<? extends Configuration>) clazz);
|
||||
this.classInitializer.whenInitialize(holder, path, (Class<? extends Configuration>) clazz);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
initializeField(provider, clazz, field, path);
|
||||
initializeField(holder, clazz, field, path);
|
||||
}
|
||||
|
||||
if (provider.options().get(StandardOptions.LOAD_SUB_CLASSES)) {
|
||||
if (holder.options().get(StandardOptions.LOAD_SUB_CLASSES)) {
|
||||
Class<?>[] classes = clazz.getDeclaredClasses();
|
||||
for (int i = classes.length - 1; i >= 0; i--) { // 逆向加载,保持顺序。
|
||||
initializeStaticClass(provider, classes[i], path, null);
|
||||
initializeStaticClass(holder, classes[i], path, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,20 +150,20 @@ public class ConfigurationInitializer {
|
||||
if (object instanceof ConfigValue<?>) {
|
||||
// 目标是 ConfigValue 实例,进行具体的初始化注入
|
||||
ConfigValue<?> value = (ConfigValue<?>) object;
|
||||
String path = getFieldPath(provider, parent, field);
|
||||
String path = getFieldPath(holder, parent, field);
|
||||
if (path == null) return;
|
||||
value.initialize(provider, path);
|
||||
value.initialize(holder, path);
|
||||
try {
|
||||
this.fieldInitializer.whenInitialize(provider, path, field);
|
||||
this.fieldInitializer.whenInitialize(holder, path, field);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (source instanceof Configuration && object instanceof Configuration) {
|
||||
// 当且仅当 源字段与字段 均为Configuration实例时,才对目标字段进行下一步初始化加载。
|
||||
initializeInstance(provider, (Configuration) object, parent, field);
|
||||
initializeInstance(holder, (Configuration) object, parent, field);
|
||||
} else if (source instanceof Class<?> && object instanceof Class<?>) {
|
||||
// 当且仅当 源字段与字段 均为静态类时,才对目标字段进行下一步初始化加载。
|
||||
initializeStaticClass(provider, (Class<?>) object, parent, field);
|
||||
initializeStaticClass(holder, (Class<?>) object, parent, field);
|
||||
}
|
||||
|
||||
// 以上判断实现以下规范:
|
||||
|
||||
@@ -40,8 +40,8 @@ public class PathGenerator {
|
||||
public @Nullable String getFieldPath(@NotNull ConfigurationHolder<?> holder,
|
||||
@Nullable String parentPath, @NotNull Field field) {
|
||||
ConfigPath path = field.getAnnotation(ConfigPath.class);
|
||||
if (path == null) return link(provider, parentPath, false, field.getName()); // No annotation, use field name.
|
||||
else return link(provider, parentPath, path.root(), select(path.value(), field.getName()));
|
||||
if (path == null) return link(holder, parentPath, false, field.getName()); // No annotation, use field name.
|
||||
else return link(holder, parentPath, path.root(), select(path.value(), field.getName()));
|
||||
}
|
||||
|
||||
public @Nullable String getClassPath(@NotNull ConfigurationHolder<?> holder,
|
||||
@@ -52,14 +52,14 @@ public class PathGenerator {
|
||||
// and use filed information.
|
||||
ConfigPath clazzPath = clazz.getAnnotation(ConfigPath.class);
|
||||
|
||||
if (clazzPath != null) return link(provider, parentPath, clazzPath.root(), clazzPath.value());
|
||||
if (clazzPath != null) return link(holder, parentPath, clazzPath.root(), clazzPath.value());
|
||||
if (clazzField == null) {
|
||||
return link(provider, parentPath, false, clazz.getSimpleName()); // No field, use class name.
|
||||
return link(holder, parentPath, false, clazz.getSimpleName()); // No field, use class name.
|
||||
}
|
||||
|
||||
ConfigPath fieldPath = clazzField.getAnnotation(ConfigPath.class);
|
||||
if (fieldPath == null) return link(provider, parentPath, false, clazzField.getName());
|
||||
else return getFieldPath(provider, parentPath, clazzField);
|
||||
if (fieldPath == null) return link(holder, parentPath, false, clazzField.getName());
|
||||
else return getFieldPath(holder, parentPath, clazzField);
|
||||
}
|
||||
|
||||
protected String select(String path, String defaultValue) {
|
||||
@@ -70,7 +70,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 ? covertPath(path) : parent + pathSeparator(provider) + covertPath(path);
|
||||
return root || parent == null ? covertPath(path) : parent + pathSeparator(holder) + covertPath(path);
|
||||
}
|
||||
|
||||
public static boolean isBlank(String path) {
|
||||
@@ -78,7 +78,7 @@ public class PathGenerator {
|
||||
}
|
||||
|
||||
public static char pathSeparator(ConfigurationHolder<?> holder) {
|
||||
return provider.options().get(StandardOptions.PATH_SEPARATOR);
|
||||
return holder.options().get(StandardOptions.PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,7 @@ public interface StandardOptions {
|
||||
* <br> if false, the values will be parsed when calling
|
||||
* {@link cc.carm.lib.configuration.value.ConfigValue#get()}
|
||||
* <br> if true, the values will be parsed when
|
||||
* {@link ConfigurationHolder#load(Configuration)}.
|
||||
* {@link ConfigurationHolder#initialize(Configuration)}.
|
||||
*/
|
||||
ConfigurationOption<Boolean> PRELOAD = of(false);
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package cc.carm.lib.configuration.source.section;
|
||||
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class ConfigurationSource<SELF extends ConfigurationSource<SELF, ORIGINAL>, ORIGINAL>
|
||||
implements ConfigurationSection {
|
||||
|
||||
protected final @NotNull ConfigurationHolder<? extends SELF> holder;
|
||||
protected long lastUpdateMillis;
|
||||
|
||||
protected ConfigurationSource(@NotNull ConfigurationHolder<? extends SELF> holder,
|
||||
long lastUpdateMillis) {
|
||||
this.holder = holder;
|
||||
this.lastUpdateMillis = lastUpdateMillis;
|
||||
}
|
||||
|
||||
public @NotNull ConfigurationHolder<? extends SELF> holder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
public void reload() throws Exception {
|
||||
onReload(); // 调用重写的Reload方法
|
||||
this.lastUpdateMillis = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
protected abstract SELF self();
|
||||
|
||||
/**
|
||||
* @return Original configuration object
|
||||
*/
|
||||
public abstract @NotNull ORIGINAL original();
|
||||
|
||||
public abstract void save() throws Exception;
|
||||
|
||||
protected abstract void onReload() throws Exception;
|
||||
|
||||
public long getLastUpdateMillis() {
|
||||
return this.lastUpdateMillis;
|
||||
}
|
||||
|
||||
public boolean isExpired(long parsedTime) {
|
||||
return getLastUpdateMillis() > parsedTime;
|
||||
}
|
||||
|
||||
}
|
||||
+9
-2
@@ -1,6 +1,7 @@
|
||||
package cc.carm.lib.configuration.source.section;
|
||||
|
||||
import cc.carm.lib.configuration.function.DataFunction;
|
||||
import cc.carm.lib.configuration.source.option.StandardOptions;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -8,7 +9,13 @@ import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface ConfigurationSection {
|
||||
public interface ConfigureSection {
|
||||
|
||||
@NotNull ConfigureSource<?, ?, ?> source();
|
||||
|
||||
default char separator() {
|
||||
return source().holder().options().get(StandardOptions.PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
default Set<String> getKeys(boolean deep) {
|
||||
@@ -33,7 +40,7 @@ public interface ConfigurationSection {
|
||||
boolean isSection(@NotNull String path);
|
||||
|
||||
@Nullable
|
||||
ConfigurationSection getSection(@NotNull String path);
|
||||
ConfigureSection getSection(@NotNull String path);
|
||||
|
||||
@Nullable Object get(@NotNull String path);
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package cc.carm.lib.configuration.source.section;
|
||||
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class ConfigureSource<
|
||||
SECTION extends ConfigureSection, ORIGINAL,
|
||||
SELF extends ConfigureSource<SECTION, ORIGINAL, SELF>>
|
||||
implements ConfigureSection {
|
||||
|
||||
protected final @NotNull ConfigurationHolder<? extends SELF> holder;
|
||||
protected long lastUpdateMillis;
|
||||
|
||||
protected ConfigureSource(@NotNull ConfigurationHolder<? extends SELF> holder, long lastUpdateMillis) {
|
||||
this.holder = holder;
|
||||
this.lastUpdateMillis = lastUpdateMillis;
|
||||
}
|
||||
|
||||
public @NotNull ConfigurationHolder<? extends SELF> holder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
|
||||
public void reload() throws Exception {
|
||||
onReload(); // 调用重写的Reload方法
|
||||
this.lastUpdateMillis = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
protected abstract SELF self();
|
||||
|
||||
/**
|
||||
* @return Original configuration object
|
||||
*/
|
||||
public abstract @NotNull ORIGINAL original();
|
||||
|
||||
/**
|
||||
* @return Configuration section
|
||||
*/
|
||||
public abstract @NotNull SECTION section();
|
||||
|
||||
public abstract void save() throws Exception;
|
||||
|
||||
protected abstract void onReload() throws Exception;
|
||||
|
||||
public long getLastUpdateMillis() {
|
||||
return this.lastUpdateMillis;
|
||||
}
|
||||
|
||||
public boolean isExpired(long parsedTime) {
|
||||
return getLastUpdateMillis() > parsedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return section().getValues(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
section().set(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull String path) {
|
||||
return section().contains(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList(@NotNull String path) {
|
||||
return section().isList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<?> getList(@NotNull String path) {
|
||||
return section().getList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSection(@NotNull String path) {
|
||||
return section().isSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigureSection getSection(@NotNull String path) {
|
||||
return section().getSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
return section().get(path);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package cc.carm.lib.configuration.value;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSource;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -101,8 +101,8 @@ public class ValueManifest<T> {
|
||||
throw new IllegalStateException("Value does not have a provider.");
|
||||
}
|
||||
|
||||
public @NotNull ConfigurationSource<?, ?> config() {
|
||||
return holder().source();
|
||||
public @NotNull ConfigureSource<?, ?, ?> config() {
|
||||
return holder().config();
|
||||
}
|
||||
|
||||
public ConfigurationMetaHolder metadata() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||
import cc.carm.lib.configuration.adapter.ValueParser;
|
||||
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.value.ValueManifest;
|
||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -58,7 +58,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
|
||||
// If the value is expired, we need to update it
|
||||
Map<K, V> map = createMap();
|
||||
|
||||
ConfigurationSection section = config().getSection(path());
|
||||
ConfigureSection section = config().getSection(path());
|
||||
if (section == null) return getDefaultFirst(map);
|
||||
|
||||
Set<String> keys = section.getKeys(false);
|
||||
|
||||
@@ -30,6 +30,11 @@ public class ConfiguredValue<V> extends CachedConfigValue<V> {
|
||||
return of(ValueType.of(type), () -> null);
|
||||
}
|
||||
|
||||
public static <V> ConfiguredValue<V> of(@NotNull Class<V> type, @NotNull V defaults) {
|
||||
return of(ValueType.of(type), () -> defaults);
|
||||
}
|
||||
|
||||
|
||||
public static <V> ConfiguredValue<V> of(@NotNull Class<V> type, @NotNull Supplier<@Nullable V> defaultSupplier) {
|
||||
return of(ValueType.of(type), defaultSupplier);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
@@ -28,10 +29,17 @@ public class AdaptTest {
|
||||
data -> Duration.between(LocalTime.now(), data)
|
||||
);
|
||||
|
||||
ConfigurationHolder<TestSource> provider = new ConfigurationHolder<>(
|
||||
new TestSource(), registry, new ConfigurationOptionHolder(),
|
||||
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);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import cc.carm.lib.configuration.source.loader.PathGenerator;
|
||||
import org.junit.Test;
|
||||
|
||||
public class NameTest {
|
||||
|
||||
@@ -6,6 +6,7 @@ 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;
|
||||
@@ -14,10 +15,17 @@ public class LoaderTest {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
ConfigurationHolder<TestSource> provider = new ConfigurationHolder<>(
|
||||
new TestSource(), new ValueAdapterRegistry(), new ConfigurationOptionHolder(),
|
||||
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);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
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,18 +1,16 @@
|
||||
package cc.carm.test.config;
|
||||
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSection;
|
||||
import cc.carm.lib.configuration.source.section.ConfigurationSource;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TestSource extends ConfigurationSource<TestSource, Map<String, String>> {
|
||||
public class TestSource extends ConfigureSource<TestSection, Map<String, String>, TestSource> {
|
||||
|
||||
public TestSource() {
|
||||
super(System.currentTimeMillis());
|
||||
|
||||
public TestSource(@NotNull ConfigurationHolder<? extends TestSource> holder, long lastUpdateMillis) {
|
||||
super(holder, lastUpdateMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,47 +34,12 @@ public class TestSource extends ConfigurationSource<TestSource, Map<String, Stri
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<String> getKeys(boolean deep) {
|
||||
public @NotNull TestSection section() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@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 null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSection(@NotNull String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigurationSection getSection(@NotNull String path) {
|
||||
public @NotNull ConfigureSource<?, ?, ?> source() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user