mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2024-09-19 20:25:51 +00:00
feat(loader): Refactor loaders and metadata.
This commit is contained in:
parent
b912ea369c
commit
da3d4d1fd2
@ -1,26 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.commentable;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.annotation.HeaderComment;
|
|
||||||
import cc.carm.lib.configuration.annotation.InlineComment;
|
|
||||||
import cc.carm.lib.easyannotation.AnnotatedMetaType;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface CommentableMetaTypes {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration's {@link HeaderComment}
|
|
||||||
*/
|
|
||||||
AnnotatedMetaType<HeaderComment, List<String>> HEADER_COMMENT = AnnotatedMetaType.of(
|
|
||||||
HeaderComment.class, h -> h.value().length == 0 ? null : Arrays.asList(h.value())
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration's {@link InlineComment}
|
|
||||||
*/
|
|
||||||
AnnotatedMetaType<InlineComment, String> INLINE_COMMENT = AnnotatedMetaType.of(
|
|
||||||
InlineComment.class, c -> c.value().isEmpty() ? null : c.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
@ -22,12 +22,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>easyoptions</artifactId>
|
<artifactId>easyoptions</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cc.carm.lib</groupId>
|
|
||||||
<artifactId>easyannotation</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package cc.carm.lib.configuration.core;
|
package cc.carm.lib.configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The root interface of the configuration file interfaces,
|
* The root interface of the configuration file interfaces,
|
@ -5,12 +5,10 @@ import cc.carm.lib.configuration.source.ConfigurationProvider;
|
|||||||
/**
|
/**
|
||||||
* Value adapter, used to convert the value of the configuration file into the objects.
|
* Value adapter, used to convert the value of the configuration file into the objects.
|
||||||
*
|
*
|
||||||
* @param <P> The type of the configuration provider.
|
|
||||||
* @param <B> The type of the base data
|
* @param <B> The type of the base data
|
||||||
* @param <V> The type of the target value
|
* @param <V> The type of the target value
|
||||||
*/
|
*/
|
||||||
public abstract class ValueAdapter<P extends ConfigurationProvider, B, V>
|
public abstract class ValueAdapter<B, V> implements ValueSerializer<B, V>, ValueDeserializer<B, V> {
|
||||||
implements ValueSerializer<P, B, V>, ValueDeserializer<P, B, V> {
|
|
||||||
|
|
||||||
protected final Class<? super B> baseType;
|
protected final Class<? super B> baseType;
|
||||||
protected final Class<? super V> valueType;
|
protected final Class<? super V> valueType;
|
||||||
@ -36,17 +34,17 @@ public abstract class ValueAdapter<P extends ConfigurationProvider, B, V>
|
|||||||
return isAdaptedFrom(object.getClass());
|
return isAdaptedFrom(object.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAdapterOf(Class<?> clazz) {
|
public boolean isAdaptedTo(Class<?> clazz) {
|
||||||
return clazz == valueType;
|
return clazz == valueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected final V deserializeObject(P provider, Class<?> valueClass, Object data) throws Exception {
|
protected final V deserializeObject(ConfigurationProvider<?> provider, Class<?> valueClass, Object data) throws Exception {
|
||||||
return deserialize(provider, (Class<? extends V>) valueClass, (B) data);
|
return deserialize(provider, (Class<? extends V>) valueClass, (B) data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected final B serializeObject(P provider, Object value) throws Exception {
|
protected final B serializeObject(ConfigurationProvider<?> provider, Object value) throws Exception {
|
||||||
return serialize(provider, (V) value);
|
return serialize(provider, (V) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.adapter;
|
package cc.carm.lib.configuration.adapter;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapters;
|
import cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapters;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -10,29 +10,29 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ValueAdapterRegistry<P extends ConfigurationProvider> {
|
public class ValueAdapterRegistry {
|
||||||
|
|
||||||
protected final Map<Class<?>, ValueAdapter<P, ?, ?>> adapters = new HashMap<>();
|
protected final Map<Class<?>, ValueAdapter<?, ?>> adapters = new HashMap<>();
|
||||||
|
|
||||||
public void register(@NotNull ValueAdapter<P, ?, ?> adapter) {
|
public void register(@NotNull ValueAdapter<?, ?> adapter) {
|
||||||
adapters.put(adapter.getValueClass(), adapter);
|
adapters.put(adapter.getValueClass(), adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void register(Class<T> clazz, @NotNull ValueAdapter<P, ?, T> adapter) {
|
public <T> void register(Class<T> clazz, @NotNull ValueAdapter<?, T> adapter) {
|
||||||
adapters.put(clazz, adapter);
|
adapters.put(clazz, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <B, V> void register(Class<B> baseClass, Class<V> valueClass,
|
public <B, V> void register(Class<B> baseClass, Class<V> valueClass,
|
||||||
ConfigDataFunction<B, V> parser,
|
ConfigDataFunction<B, V> parser,
|
||||||
ConfigDataFunction<V, B> serializer) {
|
ConfigDataFunction<V, B> serializer) {
|
||||||
register(new ValueAdapter<P, B, V>(baseClass, valueClass) {
|
register(new ValueAdapter<B, V>(baseClass, valueClass) {
|
||||||
@Override
|
@Override
|
||||||
public B serialize(@NotNull P provider, @NotNull V value) throws Exception {
|
public B serialize(@NotNull ConfigurationProvider<?> provider, @NotNull V value) throws Exception {
|
||||||
return serializer.parse(value);
|
return serializer.parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V deserialize(@NotNull P provider, @NotNull Class<? extends V> clazz, @NotNull B data) throws Exception {
|
public V deserialize(@NotNull ConfigurationProvider<?> provider, @NotNull Class<? extends V> clazz, @NotNull B data) throws Exception {
|
||||||
return parser.parse(data);
|
return parser.parse(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -44,11 +44,11 @@ public class ValueAdapterRegistry<P extends ConfigurationProvider> {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Contract("_,_,null -> null")
|
@Contract("_,_,null -> null")
|
||||||
public <T> T deserialize(@NotNull P provider, @NotNull Class<T> type, @Nullable Object source) throws Exception {
|
public <T> T deserialize(@NotNull ConfigurationProvider<?> provider, @NotNull Class<T> type, @Nullable Object source) throws Exception {
|
||||||
if (source == null) return null; // Null check
|
if (source == null) return null; // Null check
|
||||||
if (type.isInstance(source)) return type.cast(source); // Not required to deserialize
|
if (type.isInstance(source)) return type.cast(source); // Not required to deserialize
|
||||||
|
|
||||||
ValueAdapter<P, ?, ?> adapter = getAdapter(type);
|
ValueAdapter<?, ?> adapter = getAdapter(type);
|
||||||
if (adapter == null) throw new RuntimeException("No adapter for type " + type.getName());
|
if (adapter == null) throw new RuntimeException("No adapter for type " + type.getName());
|
||||||
|
|
||||||
// Check if value is adapted from given value's type
|
// Check if value is adapted from given value's type
|
||||||
@ -64,10 +64,10 @@ public class ValueAdapterRegistry<P extends ConfigurationProvider> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Contract("_,null -> null")
|
@Contract("_,null -> null")
|
||||||
public <T> Object serialize(@NotNull P provider, @Nullable T value) throws Exception {
|
public <T> Object serialize(@NotNull ConfigurationProvider<?> provider, @Nullable T value) throws Exception {
|
||||||
if (value == null) return null; // Null check
|
if (value == null) return null; // Null check
|
||||||
|
|
||||||
ValueAdapter<P, ?, ?> adapter = getAdapter(value.getClass());
|
ValueAdapter<?, ?> adapter = getAdapter(value.getClass());
|
||||||
if (adapter == null) return value; // No adapters, try to return the original value
|
if (adapter == null) return value; // No adapters, try to return the original value
|
||||||
|
|
||||||
if (adapter instanceof PrimitiveAdapters) {
|
if (adapter instanceof PrimitiveAdapters) {
|
||||||
@ -80,12 +80,12 @@ public class ValueAdapterRegistry<P extends ConfigurationProvider> {
|
|||||||
return serialize(provider, adapter.serializeObject(provider, value));
|
return serialize(provider, adapter.serializeObject(provider, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueAdapter<P, ?, ?> getAdapter(Class<?> clazz) {
|
public ValueAdapter<?, ?> getAdapter(Class<?> clazz) {
|
||||||
return adapters.getOrDefault(clazz, findAdapter(clazz));
|
return adapters.getOrDefault(clazz, findAdapter(clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueAdapter<P, ?, ?> findAdapter(Class<?> clazz) {
|
public ValueAdapter<?, ?> findAdapter(Class<?> clazz) {
|
||||||
return adapters.values().stream().filter(adapter -> adapter.isAdapterOf(clazz)).findFirst().orElse(null);
|
return adapters.values().stream().filter(adapter -> adapter.isAdaptedTo(clazz)).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,13 +6,12 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
/**
|
/**
|
||||||
* Value deserializer, convert base data to target value.
|
* Value deserializer, convert base data to target value.
|
||||||
*
|
*
|
||||||
* @param <P> Configuration provider
|
|
||||||
* @param <B> The type of base data
|
* @param <B> The type of base data
|
||||||
* @param <V> The type of target value
|
* @param <V> The type of target value
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ValueDeserializer<P extends ConfigurationProvider, B, V> {
|
public interface ValueDeserializer<B, V> {
|
||||||
|
|
||||||
V deserialize(@NotNull P provider, @NotNull Class<? extends V> clazz, @NotNull B data) throws Exception;
|
V deserialize(@NotNull ConfigurationProvider<?> provider, @NotNull Class<? extends V> clazz, @NotNull B data) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,12 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
/**
|
/**
|
||||||
* Value serializer, convert target value to base data.
|
* Value serializer, convert target value to base data.
|
||||||
*
|
*
|
||||||
* @param <P> Configuration provider
|
|
||||||
* @param <B> The type of base data
|
* @param <B> The type of base data
|
||||||
* @param <V> The type of value
|
* @param <V> The type of value
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ValueSerializer<P extends ConfigurationProvider, B, V> {
|
public interface ValueSerializer<B, V> {
|
||||||
|
|
||||||
B serialize(@NotNull P provider, @NotNull V value) throws Exception;
|
B serialize(@NotNull ConfigurationProvider<?> provider, @NotNull V value) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,24 +5,24 @@ import cc.carm.lib.configuration.source.ConfigurationProvider;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public class EnumAdapter<P extends ConfigurationProvider> extends ValueAdapter<P, String, Enum> {
|
public class EnumAdapter extends ValueAdapter<String, Enum> {
|
||||||
|
|
||||||
public EnumAdapter() {
|
public EnumAdapter() {
|
||||||
super(String.class, Enum.class);
|
super(String.class, Enum.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String serialize(@NotNull P provider, @NotNull Enum value) throws Exception {
|
public String serialize(@NotNull ConfigurationProvider<?> provider, @NotNull Enum value) throws Exception {
|
||||||
return value.name();
|
return value.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Enum deserialize(@NotNull P provider, @NotNull Class<? extends Enum> clazz, @NotNull String data) throws Exception {
|
public Enum deserialize(@NotNull ConfigurationProvider<?> provider, @NotNull Class<? extends Enum> clazz, @NotNull String data) throws Exception {
|
||||||
return Enum.valueOf(clazz, data);
|
return Enum.valueOf(clazz, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAdapterOf(Class<?> clazz) {
|
public boolean isAdaptedTo(Class<?> clazz) {
|
||||||
return clazz.isEnum();
|
return clazz.isEnum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,45 +1,45 @@
|
|||||||
package cc.carm.lib.configuration.adapter.strandard;
|
package cc.carm.lib.configuration.adapter.strandard;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class PrimitiveAdapters<P extends ConfigurationProvider, T> extends ValueAdapter<P, Object, T> {
|
public abstract class PrimitiveAdapters<T> extends ValueAdapter<Object, T> {
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, String> ofString() {
|
public static PrimitiveAdapters<String> ofString() {
|
||||||
return of(String.class, o -> o instanceof String ? (String) o : o.toString());
|
return of(String.class, o -> o instanceof String ? (String) o : o.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Boolean> ofBoolean() {
|
public static PrimitiveAdapters<Boolean> ofBoolean() {
|
||||||
return of(Boolean.class, o -> o instanceof Boolean ? (Boolean) o : Boolean.parseBoolean(o.toString()));
|
return of(Boolean.class, o -> o instanceof Boolean ? (Boolean) o : Boolean.parseBoolean(o.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Character> ofCharacter() {
|
public static PrimitiveAdapters<Character> ofCharacter() {
|
||||||
return of(Character.class, o -> o instanceof Character ? (Character) o : o.toString().charAt(0));
|
return of(Character.class, o -> o instanceof Character ? (Character) o : o.toString().charAt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Integer> ofInteger() {
|
public static PrimitiveAdapters<Integer> ofInteger() {
|
||||||
return ofNumber(Integer.class, Number::intValue, Integer::parseInt);
|
return ofNumber(Integer.class, Number::intValue, Integer::parseInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Long> ofLong() {
|
public static PrimitiveAdapters<Long> ofLong() {
|
||||||
return ofNumber(Long.class, Number::longValue, Long::parseLong);
|
return ofNumber(Long.class, Number::longValue, Long::parseLong);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Double> ofDouble() {
|
public static PrimitiveAdapters<Double> ofDouble() {
|
||||||
return ofNumber(Double.class, Number::doubleValue, Double::parseDouble);
|
return ofNumber(Double.class, Number::doubleValue, Double::parseDouble);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Float> ofFloat() {
|
public static PrimitiveAdapters<Float> ofFloat() {
|
||||||
return ofNumber(Float.class, Number::floatValue, Float::parseFloat);
|
return ofNumber(Float.class, Number::floatValue, Float::parseFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Short> ofShort() {
|
public static PrimitiveAdapters<Short> ofShort() {
|
||||||
return ofNumber(Short.class, Number::shortValue, Short::parseShort);
|
return ofNumber(Short.class, Number::shortValue, Short::parseShort);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider> PrimitiveAdapters<P, Byte> ofByte() {
|
public static PrimitiveAdapters<Byte> ofByte() {
|
||||||
return ofNumber(Byte.class, Number::byteValue, Byte::parseByte);
|
return ofNumber(Byte.class, Number::byteValue, Byte::parseByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,21 +48,21 @@ public abstract class PrimitiveAdapters<P extends ConfigurationProvider, T> exte
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object serialize(@NotNull P provider, @NotNull T value) throws Exception {
|
public Object serialize(@NotNull ConfigurationProvider<?> provider, @NotNull T value) throws Exception {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider, T> PrimitiveAdapters<P, T> of(@NotNull Class<T> clazz,
|
public static <T> PrimitiveAdapters<T> of(@NotNull Class<T> clazz,
|
||||||
@NotNull ConfigDataFunction<Object, T> function) {
|
@NotNull ConfigDataFunction<Object, T> function) {
|
||||||
return new PrimitiveAdapters<P, T>(clazz) {
|
return new PrimitiveAdapters<T>(clazz) {
|
||||||
@Override
|
@Override
|
||||||
public T deserialize(@NotNull P provider, @NotNull Class<? extends T> clazz, @NotNull Object data) throws Exception {
|
public T deserialize(@NotNull ConfigurationProvider<?> provider, @NotNull Class<? extends T> clazz, @NotNull Object data) throws Exception {
|
||||||
return function.parse(data);
|
return function.parse(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <P extends ConfigurationProvider, T extends Number> PrimitiveAdapters<P, T> ofNumber(@NotNull Class<T> numberClass,
|
public static <T extends Number> PrimitiveAdapters<T> ofNumber(@NotNull Class<T> numberClass,
|
||||||
@NotNull ConfigDataFunction<Number, T> castFunction,
|
@NotNull ConfigDataFunction<Number, T> castFunction,
|
||||||
@NotNull ConfigDataFunction<String, T> parseFunction) {
|
@NotNull ConfigDataFunction<String, T> parseFunction) {
|
||||||
return of(numberClass, o -> o instanceof Number ? castFunction.parse((Number) o) : parseFunction.parse(o.toString()));
|
return of(numberClass, o -> o instanceof Number ? castFunction.parse((Number) o) : parseFunction.parse(o.toString()));
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.annotation;
|
package cc.carm.lib.configuration.annotation;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.loader.PathGenerator;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@ -14,7 +16,7 @@ public @interface ConfigPath {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The path value of the current configuration.
|
* The path value of the current configuration.
|
||||||
* If not set,will generate the path by {@link cc.carm.lib.configuration.source.path.PathGenerator}.
|
* If not set,will generate the path by {@link PathGenerator}.
|
||||||
*
|
*
|
||||||
* @return The path value of the current configuration
|
* @return The path value of the current configuration
|
||||||
*/
|
*/
|
||||||
|
@ -1,159 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.core.function;
|
|
||||||
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ConfigValueParser<T, R> {
|
|
||||||
|
|
||||||
@Nullable R parse(@NotNull T data, @Nullable R defaultValue) throws Exception;
|
|
||||||
|
|
||||||
default <V> ConfigValueParser<T, V> andThen(@NotNull ConfigValueParser<R, V> after) {
|
|
||||||
Objects.requireNonNull(after);
|
|
||||||
return ((data, defaultValue) -> {
|
|
||||||
R result = parse(data, null);
|
|
||||||
if (result == null) return defaultValue;
|
|
||||||
else return after.parse(result, defaultValue);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
default <V> ConfigValueParser<V, R> compose(@NotNull ConfigDataFunction<? super V, ? extends T> before) {
|
|
||||||
Objects.requireNonNull(before);
|
|
||||||
return ((data, defaultValue) -> {
|
|
||||||
T result = before.parse(data);
|
|
||||||
return parse(result, defaultValue);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static <T> @NotNull ConfigValueParser<T, T> identity() {
|
|
||||||
return (input, defaultValue) -> input;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static <T> @NotNull ConfigValueParser<T, Object> toObject() {
|
|
||||||
return (input, defaultValue) -> input;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static <T, V> @NotNull ConfigValueParser<T, V> required() {
|
|
||||||
return (input, defaultValue) -> {
|
|
||||||
throw new IllegalArgumentException("Please specify the value parser.");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static <V> @NotNull ConfigValueParser<Object, V> castObject(Class<V> valueClass) {
|
|
||||||
if (Number.class.isAssignableFrom(valueClass)) return castNumber(valueClass);
|
|
||||||
else return (input, defaultValue) -> {
|
|
||||||
if (Boolean.class.isAssignableFrom(valueClass) || boolean.class.isAssignableFrom(valueClass)) {
|
|
||||||
input = booleanValue().parse(input, (Boolean) defaultValue);
|
|
||||||
} else if (Enum.class.isAssignableFrom(valueClass) && input instanceof String) {
|
|
||||||
String enumName = (String) input;
|
|
||||||
input = valueClass.getDeclaredMethod("valueOf", String.class).invoke(null, enumName);
|
|
||||||
} else if (UUID.class.isAssignableFrom(valueClass) && input instanceof String) {
|
|
||||||
input = UUID.fromString((String) input);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valueClass.isInstance(input)) return valueClass.cast(input);
|
|
||||||
else throw new IllegalArgumentException("Cannot cast value to " + valueClass.getName());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static <V> @NotNull ConfigValueParser<Object, V> castNumber(Class<V> valueClass) {
|
|
||||||
return (input, defaultValue) -> {
|
|
||||||
if (Long.class.isAssignableFrom(valueClass) || long.class.isAssignableFrom(valueClass)) {
|
|
||||||
input = longValue().parse(input, (Long) defaultValue);
|
|
||||||
} else if (Integer.class.isAssignableFrom(valueClass) || int.class.isAssignableFrom(valueClass)) {
|
|
||||||
input = intValue().parse(input, (Integer) defaultValue);
|
|
||||||
} else if (Float.class.isAssignableFrom(valueClass) || float.class.isAssignableFrom(valueClass)) {
|
|
||||||
input = floatValue().parse(input, (Float) defaultValue);
|
|
||||||
} else if (Double.class.isAssignableFrom(valueClass) || double.class.isAssignableFrom(valueClass)) {
|
|
||||||
input = doubleValue().parse(input, (Double) defaultValue);
|
|
||||||
} else if (Byte.class.isAssignableFrom(valueClass) || byte.class.isAssignableFrom(valueClass)) {
|
|
||||||
input = byteValue().parse(input, (Byte) defaultValue);
|
|
||||||
} else if (Short.class.isAssignableFrom(valueClass) || short.class.isAssignableFrom(valueClass)) {
|
|
||||||
input = shortValue().parse(input, (Short) defaultValue);
|
|
||||||
}
|
|
||||||
if (valueClass.isInstance(input)) return valueClass.cast(input);
|
|
||||||
else throw new IllegalArgumentException("Cannot cast value to " + valueClass.getName());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static <V> @NotNull ConfigValueParser<String, V> parseString(Class<V> valueClass) {
|
|
||||||
return (input, defaultValue) -> {
|
|
||||||
if (valueClass.isInstance(input)) return valueClass.cast(input);
|
|
||||||
else throw new IllegalArgumentException("Cannot cast string to " + valueClass.getName());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, String> castToString() {
|
|
||||||
return (input, defaultValue) -> {
|
|
||||||
if (input instanceof String) return (String) input;
|
|
||||||
else return input.toString();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, Integer> intValue() {
|
|
||||||
return (input, defaultValue) -> ConfigDataFunction.intValue().parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, Short> shortValue() {
|
|
||||||
return (input, defaultValue) -> ConfigDataFunction.shortValue().parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, Double> doubleValue() {
|
|
||||||
return (input, defaultValue) -> ConfigDataFunction.doubleValue().parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, Byte> byteValue() {
|
|
||||||
return (input, defaultValue) -> ConfigDataFunction.byteValue().parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, Float> floatValue() {
|
|
||||||
return (input, defaultValue) -> ConfigDataFunction.floatValue().parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, Long> longValue() {
|
|
||||||
return (input, defaultValue) -> ConfigDataFunction.longValue().parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull ConfigValueParser<Object, Boolean> booleanValue() {
|
|
||||||
return (input, defaultValue) -> ConfigDataFunction.booleanValue().parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
static @NotNull <E extends Enum<E>> ConfigValueParser<Object, E> enumValue(Class<E> enumClass) {
|
|
||||||
return (input, defaultValue) -> {
|
|
||||||
if (input instanceof Enum) {
|
|
||||||
return enumClass.cast(input);
|
|
||||||
} else if (input instanceof String) {
|
|
||||||
return Enum.valueOf(enumClass, (String) input);
|
|
||||||
} else if (input instanceof Number) {
|
|
||||||
return enumClass.getEnumConstants()[((Number) input).intValue()];
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Cannot cast value to " + enumClass.getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.core.source;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.Configuration;
|
|
||||||
import cc.carm.lib.configuration.source.comment.ConfigurationComments;
|
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
|
||||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 配置文件提供者,用于为 {@link ConfigValue} 提供配置文件的源,以便实现读取、保存等操作。
|
|
||||||
*
|
|
||||||
* @param <W> 配置文件的原生功能类
|
|
||||||
*/
|
|
||||||
public abstract class ConfigurationProvider<W extends ConfigurationWrapper<?>> {
|
|
||||||
|
|
||||||
protected long updateTime;
|
|
||||||
|
|
||||||
protected ConfigurationProvider() {
|
|
||||||
this.updateTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到配置文件的更新(最后加载)时间。
|
|
||||||
*
|
|
||||||
* @return 更新时间
|
|
||||||
*/
|
|
||||||
public long getUpdateTime() {
|
|
||||||
return updateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于 {@link CachedConfigValue} 判断缓存值是否过期(即缓存的时间早于配置文件的最后加载时间)。
|
|
||||||
*
|
|
||||||
* @param time 缓存值时的时间戳
|
|
||||||
* @return 缓存值是否过期
|
|
||||||
*/
|
|
||||||
public boolean isExpired(long time) {
|
|
||||||
return getUpdateTime() > time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到配置文件的原生功能类。
|
|
||||||
*
|
|
||||||
* @return 原生类
|
|
||||||
*/
|
|
||||||
public abstract @NotNull W getConfiguration();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重载当前配置文件。(将不会保存已修改的内容)
|
|
||||||
*
|
|
||||||
* @throws Exception 当重载出现错误时抛出
|
|
||||||
*/
|
|
||||||
public void reload() throws Exception {
|
|
||||||
onReload(); // 调用重写的Reload方法
|
|
||||||
this.updateTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将当前对配置文件的更改进行保存。
|
|
||||||
*
|
|
||||||
* @throws Exception 当保存出现错误时抛出
|
|
||||||
*/
|
|
||||||
public abstract void save() throws Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 针对于不同配置文件类型所执行的重载操作。
|
|
||||||
*
|
|
||||||
* @throws Exception 当操作出现错误时抛出。
|
|
||||||
*/
|
|
||||||
protected abstract void onReload() throws Exception;
|
|
||||||
|
|
||||||
public abstract @Nullable ConfigurationComments getComments();
|
|
||||||
|
|
||||||
public void setHeaderComment(@Nullable String path, @Nullable List<String> comments) {
|
|
||||||
if (getComments() == null) return;
|
|
||||||
getComments().setHeaderComments(path, comments);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInlineComment(@NotNull String path, @Nullable String comment) {
|
|
||||||
if (getComments() == null) return;
|
|
||||||
getComments().setInlineComment(path, comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Unmodifiable
|
|
||||||
public List<String> getHeaderComment(@Nullable String path) {
|
|
||||||
return Optional.ofNullable(getComments()).map(c -> c.getHeaderComment(path)).orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable String getInlineComment(@NotNull String path) {
|
|
||||||
return Optional.ofNullable(getComments()).map(c -> c.getInlineComment(path)).orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract @NotNull ConfigInitializer<? extends ConfigurationProvider<W>> getInitializer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定类以及其子类的所有 {@link ConfigValue} 对象。
|
|
||||||
*
|
|
||||||
* @param configClazz 配置文件类,须继承于 {@link Configuration} 。
|
|
||||||
*/
|
|
||||||
public void initialize(Class<? extends Configuration> configClazz) {
|
|
||||||
initialize(configClazz, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定类以及其子类的所有 {@link ConfigValue} 对象。
|
|
||||||
*
|
|
||||||
* @param configClazz 配置文件类,须继承于 {@link Configuration} 。
|
|
||||||
* @param saveDefaults 是否写入默认值(默认为 true)。
|
|
||||||
*/
|
|
||||||
public void initialize(Class<? extends Configuration> configClazz, boolean saveDefaults) {
|
|
||||||
this.getInitializer().initialize(configClazz, saveDefaults);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定类的所有 {@link ConfigValue} 对象。
|
|
||||||
*
|
|
||||||
* @param configClazz 配置文件类,须继承于 {@link Configuration} 。
|
|
||||||
* @param saveDefaults 是否写入默认值(默认为 true)。
|
|
||||||
* @param loadSubClasses 是否加载内部子类(默认为 true)。
|
|
||||||
*/
|
|
||||||
public void initialize(Class<? extends Configuration> configClazz, boolean saveDefaults, boolean loadSubClasses) {
|
|
||||||
this.getInitializer().initialize(configClazz, saveDefaults, loadSubClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定实例的所有 {@link ConfigValue} 与内部 {@link Configuration} 对象。
|
|
||||||
*
|
|
||||||
* @param config 配置文件实例类,须实现 {@link Configuration} 。
|
|
||||||
*/
|
|
||||||
public void initialize(@NotNull Configuration config) {
|
|
||||||
this.getInitializer().initialize(config, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定实例的所有 {@link ConfigValue} 与内部 {@link Configuration} 对象。
|
|
||||||
*
|
|
||||||
* @param config 配置文件实例类,须实现 {@link Configuration} 。
|
|
||||||
* @param saveDefaults 是否写入默认值(默认为 true)。
|
|
||||||
*/
|
|
||||||
public void initialize(@NotNull Configuration config, boolean saveDefaults) {
|
|
||||||
this.getInitializer().initialize(config, saveDefaults);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.core.source;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.function.ConfigValueParser;
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public interface ConfigurationWrapper<S> extends ConfigurationReader {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default ConfigurationWrapper<S> getWrapper() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull S getSource();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
Set<String> getKeys(boolean deep);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
Map<String, Object> getValues(boolean deep);
|
|
||||||
|
|
||||||
void set(@NotNull String path, @Nullable Object value);
|
|
||||||
|
|
||||||
boolean contains(@NotNull String path);
|
|
||||||
|
|
||||||
default <T> boolean isType(@NotNull String path, @NotNull Class<T> typeClass) {
|
|
||||||
return typeClass.isInstance(get(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable Object get(@NotNull String path);
|
|
||||||
|
|
||||||
default @Nullable <T> T get(@NotNull String path, @NotNull Class<T> clazz) {
|
|
||||||
return get(path, null, clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
default @Nullable <T> T get(@NotNull String path, @NotNull ConfigValueParser<Object, T> parser) {
|
|
||||||
return get(path, null, parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract("_,!null,_->!null")
|
|
||||||
default @Nullable <T> T get(@NotNull String path, @Nullable T defaultValue, @NotNull Class<T> clazz) {
|
|
||||||
return get(path, defaultValue, ConfigValueParser.castObject(clazz));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract("_,!null,_->!null")
|
|
||||||
default @Nullable <T> T get(@NotNull String path, @Nullable T defaultValue,
|
|
||||||
@NotNull ConfigValueParser<Object, T> parser) {
|
|
||||||
Object value = get(path);
|
|
||||||
if (value != null) {
|
|
||||||
try {
|
|
||||||
return parser.parse(value, defaultValue);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isList(@NotNull String path);
|
|
||||||
|
|
||||||
@Nullable List<?> getList(@NotNull String path);
|
|
||||||
|
|
||||||
boolean isConfigurationSection(@NotNull String path);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
ConfigurationWrapper<S> getConfigurationSection(@NotNull String path);
|
|
||||||
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.core.source.impl;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public abstract class FileConfigProvider<W extends ConfigurationWrapper<?>> extends ConfigurationProvider<W> {
|
|
||||||
|
|
||||||
protected final @NotNull File file;
|
|
||||||
|
|
||||||
protected FileConfigProvider(@NotNull File file) {
|
|
||||||
this.file = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initializeFile(@Nullable String sourcePath) throws IOException {
|
|
||||||
if (this.file.exists()) return;
|
|
||||||
|
|
||||||
File parent = this.file.getParentFile();
|
|
||||||
if (parent != null && !parent.exists() && !parent.mkdirs()) {
|
|
||||||
throw new IOException("Failed to create directory " + file.getParentFile().getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.file.createNewFile()) {
|
|
||||||
throw new IOException("Failed to create file " + file.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourcePath != null) {
|
|
||||||
try {
|
|
||||||
saveResource(sourcePath, true);
|
|
||||||
} catch (IllegalArgumentException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveResource(@NotNull String resourcePath, boolean replace)
|
|
||||||
throws IOException, IllegalArgumentException {
|
|
||||||
Objects.requireNonNull(resourcePath, "ResourcePath cannot be null");
|
|
||||||
if (resourcePath.isEmpty()) throw new IllegalArgumentException("ResourcePath cannot be empty");
|
|
||||||
|
|
||||||
resourcePath = resourcePath.replace('\\', '/');
|
|
||||||
|
|
||||||
URL url = this.getClass().getClassLoader().getResource(resourcePath);
|
|
||||||
if (url == null) throw new IllegalArgumentException("The resource '" + resourcePath + "' not exists");
|
|
||||||
|
|
||||||
File outDir = file.getParentFile();
|
|
||||||
|
|
||||||
if (!outDir.exists() && !outDir.mkdirs()) throw new IOException("Failed to create directory " + outDir);
|
|
||||||
if (!file.exists() || replace) {
|
|
||||||
try (OutputStream out = Files.newOutputStream(file.toPath())) {
|
|
||||||
URLConnection connection = url.openConnection();
|
|
||||||
connection.setUseCaches(false);
|
|
||||||
try (InputStream in = connection.getInputStream()) {
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = in.read(buf)) > 0) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public InputStream getResource(@NotNull String filename) {
|
|
||||||
try {
|
|
||||||
URL url = this.getClass().getClassLoader().getResource(filename);
|
|
||||||
if (url == null) return null;
|
|
||||||
URLConnection connection = url.openConnection();
|
|
||||||
connection.setUseCaches(false);
|
|
||||||
return connection.getInputStream();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package cc.carm.lib.configuration.core.function;
|
package cc.carm.lib.configuration.function;
|
||||||
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
@ -0,0 +1,62 @@
|
|||||||
|
package cc.carm.lib.configuration.function;
|
||||||
|
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ConfigValueParser<T, R> {
|
||||||
|
|
||||||
|
@Nullable R parse(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@NotNull T data, @Nullable R defaultValue) throws Exception;
|
||||||
|
|
||||||
|
default <V> ConfigValueParser<T, V> andThen(@NotNull ConfigValueParser<R, V> after) {
|
||||||
|
Objects.requireNonNull(after);
|
||||||
|
return ((provider, data, defaultValue) -> {
|
||||||
|
R result = parse(provider, data, null);
|
||||||
|
if (result == null) return defaultValue;
|
||||||
|
else return after.parse(provider, result, defaultValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default <V> ConfigValueParser<V, R> compose(@NotNull ConfigValueParser<? super V, ? extends T> before) {
|
||||||
|
Objects.requireNonNull(before);
|
||||||
|
return ((provider, data, defaultValue) -> {
|
||||||
|
T result = before.parse(provider, data, null);
|
||||||
|
if (result == null) return null;
|
||||||
|
return parse(provider, result, defaultValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default <V> ConfigValueParser<V, R> compose(@NotNull ConfigDataFunction<? super V, ? extends T> before) {
|
||||||
|
Objects.requireNonNull(before);
|
||||||
|
return ((provider, data, defaultValue) -> {
|
||||||
|
T result = before.parse(data);
|
||||||
|
return parse(provider, result, defaultValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(pure = true)
|
||||||
|
static <T> @NotNull ConfigValueParser<T, T> identity() {
|
||||||
|
return (provider, input, defaultValue) -> input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(pure = true)
|
||||||
|
static <T> @NotNull ConfigValueParser<T, Object> toObject() {
|
||||||
|
return (provider, input, defaultValue) -> input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(pure = true)
|
||||||
|
static <T, V> @NotNull ConfigValueParser<T, V> required() {
|
||||||
|
return (provider, input, defaultValue) -> {
|
||||||
|
throw new IllegalArgumentException("Please specify the value parser.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
|||||||
|
package cc.carm.lib.configuration.loader;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.Configuration;
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
|
import cc.carm.lib.configuration.option.ConfigurationOptions;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration loader,
|
||||||
|
* used to load configuration values from {@link Configuration} classes.
|
||||||
|
*/
|
||||||
|
public class ConfigurationLoader {
|
||||||
|
|
||||||
|
protected PathGenerator pathGenerator;
|
||||||
|
|
||||||
|
public ConfigurationLoader() {
|
||||||
|
this(StandardPathGenerator.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationLoader(PathGenerator pathGenerator) {
|
||||||
|
this.pathGenerator = pathGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPathGenerator(PathGenerator pathGenerator) {
|
||||||
|
this.pathGenerator = pathGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathGenerator getPathGenerator() {
|
||||||
|
return pathGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getFieldPath(ConfigurationProvider<?> provider, @Nullable String parentPath, @NotNull Field field) {
|
||||||
|
return pathGenerator.getFieldPath(provider, parentPath, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getClassPath(ConfigurationProvider<?> provider, @Nullable String parentPath,
|
||||||
|
@NotNull Class<?> clazz, @Nullable Field clazzField) {
|
||||||
|
return pathGenerator.getClassPath(provider, parentPath, clazz, clazzField);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(ConfigurationProvider<?> provider, @NotNull Configuration config) throws Exception {
|
||||||
|
initializeInstance(provider, config, null, null);
|
||||||
|
if (provider.option(ConfigurationOptions.SET_DEFAULTS)) provider.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(ConfigurationProvider<?> provider, @NotNull Class<? extends Configuration> clazz) throws Exception {
|
||||||
|
initializeStaticClass(provider, clazz, null, null);
|
||||||
|
if (provider.option(ConfigurationOptions.SET_DEFAULTS)) provider.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 针对实例类的初始化方法
|
||||||
|
private void initializeInstance(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@NotNull Configuration root, @Nullable String parentPath, @Nullable Field configField) {
|
||||||
|
String path = getClassPath(provider, parentPath, root.getClass(), configField);
|
||||||
|
Arrays.stream(root.getClass().getDeclaredFields()).forEach(field -> initializeField(provider, root, field, path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 针对静态类的初始化方法
|
||||||
|
private void initializeStaticClass(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@NotNull Class<?> clazz, @Nullable String parentPath, @Nullable Field configField) {
|
||||||
|
if (!Configuration.class.isAssignableFrom(clazz)) return; // 只解析继承了 ConfigurationRoot 的类
|
||||||
|
String path = getClassPath(provider, parentPath, clazz, configField);
|
||||||
|
|
||||||
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
|
initializeField(provider, clazz, field, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!provider.option(ConfigurationOptions.LOAD_SUB_CLASSES)) return;
|
||||||
|
Class<?>[] classes = clazz.getDeclaredClasses();
|
||||||
|
for (int i = classes.length - 1; i >= 0; i--) { // 逆向加载,保持顺序。
|
||||||
|
initializeStaticClass(provider, classes[i], path, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeField(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@NotNull Object source, @NotNull Field field, @Nullable String parent) {
|
||||||
|
try {
|
||||||
|
field.setAccessible(true);
|
||||||
|
Object object = field.get(source);
|
||||||
|
//
|
||||||
|
// if (object instanceof ConfigValue<?>) {
|
||||||
|
// // 目标是 ConfigValue 实例,进行具体的初始化注入
|
||||||
|
//
|
||||||
|
// } else
|
||||||
|
|
||||||
|
if (source instanceof Configuration && object instanceof Configuration) {
|
||||||
|
// 当且仅当 源字段与字段 均为ConfigurationRoot实例时,才对目标字段进行下一步初始化加载。
|
||||||
|
initializeInstance(provider, (Configuration) object, parent, field);
|
||||||
|
} else if (source instanceof Class<?> && object instanceof Class<?>) {
|
||||||
|
// 当且仅当 源字段与字段 均为静态类时,才对目标字段进行下一步初始化加载。
|
||||||
|
initializeStaticClass(provider, (Class<?>) object, parent, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以上判断实现以下规范:
|
||||||
|
// - 实例类中仅加载 ConfigValue实例 与 ConfigurationRoot实例
|
||||||
|
// - 静态类中仅加载 静态ConfigValue实例 与 静态ConfigurationRoot类
|
||||||
|
|
||||||
|
} catch (IllegalAccessException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package cc.carm.lib.configuration.loader;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public interface PathGenerator {
|
||||||
|
|
||||||
|
@Nullable String getFieldPath(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@Nullable String parentPath, @NotNull Field field);
|
||||||
|
|
||||||
|
@Nullable String getClassPath(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@Nullable String parentPath, @NotNull Class<?> clazz, @Nullable Field clazzField);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configuration name of the specified element.
|
||||||
|
* Use the naming convention of all lowercase and "-" links.
|
||||||
|
*
|
||||||
|
* @param name source name
|
||||||
|
* @return the final path
|
||||||
|
*/
|
||||||
|
static String covertPathName(String name) {
|
||||||
|
return name
|
||||||
|
// Replace all uppercase letters with dashes
|
||||||
|
.replaceAll("[A-Z]", "-$0")
|
||||||
|
// If the first letter is also capitalized,
|
||||||
|
// it will also be converted and the first dash will need to be removed
|
||||||
|
.replaceAll("-(.*)", "$1")
|
||||||
|
// Because the name may contain _, it needs to be treated a little differently
|
||||||
|
.replaceAll("_-([A-Z])", "_$1")
|
||||||
|
// The content that is not named in all caps is then converted
|
||||||
|
.replaceAll("([a-z])-([A-Z])", "$1_$2")
|
||||||
|
// Remove any extra horizontal lines
|
||||||
|
.replace("-", "")
|
||||||
|
// Replace the underscore with a dash
|
||||||
|
.replace("_", "-")
|
||||||
|
// Finally, convert it to all lowercase
|
||||||
|
.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package cc.carm.lib.configuration.loader;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
|
import cc.carm.lib.configuration.option.ConfigurationOptions;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
|
public class StandardPathGenerator implements PathGenerator {
|
||||||
|
|
||||||
|
public static StandardPathGenerator of() {
|
||||||
|
return of(PathGenerator::covertPathName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StandardPathGenerator of(UnaryOperator<String> pathConverter) {
|
||||||
|
return new StandardPathGenerator(pathConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected UnaryOperator<String> pathConverter;
|
||||||
|
|
||||||
|
public StandardPathGenerator(UnaryOperator<String> pathConverter) {
|
||||||
|
this.pathConverter = pathConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull UnaryOperator<String> getPathConverter() {
|
||||||
|
return pathConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPathConverter(UnaryOperator<String> pathConverter) {
|
||||||
|
this.pathConverter = pathConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String covertPath(String name) {
|
||||||
|
return pathConverter.apply(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public char pathSeparator(ConfigurationProvider<?> provider) {
|
||||||
|
return provider.option(ConfigurationOptions.PATH_SEPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getFieldPath(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getClassPath(@NotNull ConfigurationProvider<?> provider,
|
||||||
|
@Nullable String parentPath, @NotNull Class<?> clazz, @Nullable Field clazzField) {
|
||||||
|
// For standard path generator, we generate path following by:
|
||||||
|
// 1. Check if the class has a ConfigPath annotation, if so, use the root and value as the path.
|
||||||
|
// 2. If the class defined as a field, check if the field has a ConfigPath annotation,
|
||||||
|
// and use filed information.
|
||||||
|
ConfigPath clazzPath = clazz.getAnnotation(ConfigPath.class);
|
||||||
|
|
||||||
|
if (clazzPath != null) return link(provider, parentPath, clazzPath.root(), clazzPath.value());
|
||||||
|
if (clazzField == null) {
|
||||||
|
return link(provider, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String select(String path, String defaultValue) {
|
||||||
|
if (path == null || path.isEmpty()) return defaultValue;
|
||||||
|
else return isBlank(path) ? null : path;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isBlank(String path) {
|
||||||
|
return path == null || path.replace(" ", "").isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected @Nullable String link(@NotNull ConfigurationProvider<?> provider, @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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.manifest;
|
|
||||||
|
|
||||||
public class ValueManifest {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package cc.carm.lib.configuration.source.standard;
|
package cc.carm.lib.configuration.option;
|
||||||
|
|
||||||
|
|
||||||
import cc.carm.lib.easyoptions.OptionType;
|
import cc.carm.lib.easyoptions.OptionType;
|
||||||
@ -13,14 +13,9 @@ public interface ConfigurationOptions {
|
|||||||
OptionType<Character> PATH_SEPARATOR = of('.');
|
OptionType<Character> PATH_SEPARATOR = of('.');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to copy files from resource if exists.
|
* Whether to set & save default values if offered and not exists in configuration.
|
||||||
*/
|
*/
|
||||||
OptionType<Boolean> COPY_DEFAULTS = of(true);
|
OptionType<Boolean> SET_DEFAULTS = of(true);
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to save default values if offered and not exists in configuration.
|
|
||||||
*/
|
|
||||||
OptionType<Boolean> SAVE_DEFAULTS = of(true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to load subclasses of configuration class.
|
* Whether to load subclasses of configuration class.
|
@ -2,8 +2,9 @@ package cc.carm.lib.configuration.source;
|
|||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.source.path.PathGenerator;
|
import cc.carm.lib.configuration.loader.ConfigurationLoader;
|
||||||
|
import cc.carm.lib.configuration.loader.PathGenerator;
|
||||||
import cc.carm.lib.easyoptions.OptionHolder;
|
import cc.carm.lib.easyoptions.OptionHolder;
|
||||||
import cc.carm.lib.easyoptions.OptionType;
|
import cc.carm.lib.easyoptions.OptionType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -11,53 +12,52 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public abstract class ConfigurationBuilder<P extends ConfigurationProvider<P>, C> {
|
public abstract class ConfigurationFactory<P extends ConfigurationSource<P, ?>, C> {
|
||||||
|
|
||||||
|
protected Function<P, ConfigurationLoader> loaderFunction = p -> new ConfigurationLoader();
|
||||||
protected Function<P, ConfigurationLoader<P>> loaderFunction = ConfigurationLoader::new;
|
protected Consumer<ConfigurationLoader> loaderConsumer = loader -> {
|
||||||
protected Consumer<ConfigurationLoader<P>> loaderConsumer = loader -> {
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected ValueAdapterRegistry<P> adapters = new ValueAdapterRegistry<>();
|
protected ValueAdapterRegistry adapters = new ValueAdapterRegistry();
|
||||||
protected OptionHolder options = new OptionHolder();
|
protected OptionHolder options = new OptionHolder();
|
||||||
|
|
||||||
public abstract C getThis();
|
public abstract C getThis();
|
||||||
|
|
||||||
public C loader(Function<P, ConfigurationLoader<P>> loaderFunction) {
|
public C loader(Function<P, ConfigurationLoader> loaderFunction) {
|
||||||
this.loaderFunction = loaderFunction;
|
this.loaderFunction = loaderFunction;
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public C loader(ConfigurationLoader<P> loader) {
|
public C loader(ConfigurationLoader loader) {
|
||||||
return loader(p -> loader);
|
return loader(p -> loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public C loader(Consumer<ConfigurationLoader<P>> loaderConsumer) {
|
public C loader(Consumer<ConfigurationLoader> loaderConsumer) {
|
||||||
this.loaderConsumer = this.loaderConsumer.andThen(loaderConsumer);
|
this.loaderConsumer = this.loaderConsumer.andThen(loaderConsumer);
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public C pathGenerator(PathGenerator<P> pathGenerator) {
|
public C pathGenerator(PathGenerator pathGenerator) {
|
||||||
return loader(loader -> {
|
return loader(loader -> {
|
||||||
loader.setPathGenerator(pathGenerator);
|
loader.setPathGenerator(pathGenerator);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public C adapters(ValueAdapterRegistry<P> adapters) {
|
public C adapters(ValueAdapterRegistry adapters) {
|
||||||
this.adapters = adapters;
|
this.adapters = adapters;
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public C adapter(Consumer<ValueAdapterRegistry<P>> adapterRegistryConsumer) {
|
public C adapter(Consumer<ValueAdapterRegistry> adapterRegistryConsumer) {
|
||||||
adapterRegistryConsumer.accept(adapters);
|
adapterRegistryConsumer.accept(adapters);
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public C adapter(@NotNull ValueAdapter<P, ?, ?> adapter) {
|
public C adapter(@NotNull ValueAdapter<?, ?> adapter) {
|
||||||
return adapter(a -> a.register(adapter));
|
return adapter(a -> a.register(adapter));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> C adapter(Class<T> clazz, @NotNull ValueAdapter<P, ?, T> adapter) {
|
public <T> C adapter(Class<T> clazz, @NotNull ValueAdapter<?, T> adapter) {
|
||||||
return adapter(a -> a.register(clazz, adapter));
|
return adapter(a -> a.register(clazz, adapter));
|
||||||
}
|
}
|
||||||
|
|
@ -1,196 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.source;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
|
||||||
import cc.carm.lib.configuration.core.Configuration;
|
|
||||||
import cc.carm.lib.configuration.source.path.PathGenerator;
|
|
||||||
import cc.carm.lib.configuration.source.path.StandardPathGenerator;
|
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration loader,
|
|
||||||
* used to load configuration values from {@link cc.carm.lib.configuration.core.Configuration} classes.
|
|
||||||
*/
|
|
||||||
public class ConfigurationLoader<P extends ConfigurationProvider<P>> {
|
|
||||||
|
|
||||||
protected final P provider;
|
|
||||||
protected PathGenerator<P> pathGenerator;
|
|
||||||
|
|
||||||
public ConfigurationLoader(P provider) {
|
|
||||||
this(provider, StandardPathGenerator.of(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigurationLoader(P provider, PathGenerator<P> pathGenerator) {
|
|
||||||
this.provider = provider;
|
|
||||||
this.pathGenerator = pathGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPathGenerator(PathGenerator<P> pathGenerator) {
|
|
||||||
this.pathGenerator = pathGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PathGenerator<P> getPathGenerator() {
|
|
||||||
return pathGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定类以及其子类的所有 {@link ConfigValue} 对象。
|
|
||||||
*
|
|
||||||
* @param clazz 配置文件类,须继承于 {@link Configuration} 。
|
|
||||||
*/
|
|
||||||
public void initialize(@NotNull P provider, @NotNull Class<? extends Configuration> clazz) {
|
|
||||||
initialize(clazz, saveDefaults, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定类的所有 {@link ConfigValue} 对象。
|
|
||||||
*
|
|
||||||
* @param clazz 配置文件类,须继承于 {@link Configuration} 。
|
|
||||||
* @param saveDefaults 是否写入默认值(默认为 true)。
|
|
||||||
* @param loadSubClasses 是否加载内部子类(默认为 true)。
|
|
||||||
*/
|
|
||||||
public void initialize(@NotNull Class<? extends Configuration> clazz) {
|
|
||||||
initializeStaticClass(
|
|
||||||
clazz, null, null,
|
|
||||||
null, null, null,
|
|
||||||
saveDefaults, loadSubClasses
|
|
||||||
);
|
|
||||||
if (saveDefaults) {
|
|
||||||
try {
|
|
||||||
provider.save();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定实例的所有 {@link ConfigValue} 与内部 {@link Configuration} 对象。
|
|
||||||
*
|
|
||||||
* @param config 配置文件实例类,须实现 {@link Configuration} 。
|
|
||||||
*/
|
|
||||||
public void initialize(@NotNull Configuration config) {
|
|
||||||
initialize(config, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化指定实例的所有 {@link ConfigValue} 与内部 {@link Configuration} 对象。
|
|
||||||
*
|
|
||||||
* @param config 配置文件实例类,须实现 {@link Configuration} 。
|
|
||||||
* @param saveDefaults 是否写入默认值(默认为 true)。
|
|
||||||
*/
|
|
||||||
public void initialize(@NotNull Configuration config, boolean saveDefaults) {
|
|
||||||
initializeInstance(
|
|
||||||
config, null, null,
|
|
||||||
null, null, null,
|
|
||||||
saveDefaults
|
|
||||||
);
|
|
||||||
if (saveDefaults) {
|
|
||||||
try {
|
|
||||||
provider.save();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 针对实例类的初始化方法
|
|
||||||
private void initializeInstance(@NotNull Configuration root,
|
|
||||||
@Nullable String parentPath, @Nullable String fieldName,
|
|
||||||
@Nullable ConfigPath fieldPath,
|
|
||||||
@Nullable HeaderComment fieldHeaderComments,
|
|
||||||
@Nullable InlineComment fieldInlineComments,
|
|
||||||
boolean saveDefaults) {
|
|
||||||
String path = getClassPath(root.getClass(), parentPath, fieldName, fieldPath);
|
|
||||||
this.provider.setHeaderComment(path, getClassHeaderComments(root.getClass(), fieldHeaderComments));
|
|
||||||
if (path != null) this.provider.setInlineComment(path, readInlineComments(fieldInlineComments));
|
|
||||||
|
|
||||||
for (Field field : root.getClass().getDeclaredFields()) {
|
|
||||||
initializeField(root, field, path, saveDefaults, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 针对静态类的初始化方法
|
|
||||||
private void initializeStaticClass(@NotNull Class<?> clazz,
|
|
||||||
@Nullable String parentPath, @Nullable String fieldName,
|
|
||||||
@Nullable ConfigPath fieldPath,
|
|
||||||
@Nullable HeaderComment fieldHeaderComments,
|
|
||||||
@Nullable InlineComment fieldInlineComments,
|
|
||||||
boolean saveDefaults, boolean loadSubClasses) {
|
|
||||||
if (!Configuration.class.isAssignableFrom(clazz)) return; // 只解析继承了 ConfigurationRoot 的类
|
|
||||||
String path = getClassPath(clazz, parentPath, fieldName, fieldPath);
|
|
||||||
this.provider.setHeaderComment(path, getClassHeaderComments(clazz, fieldHeaderComments));
|
|
||||||
if (path != null) this.provider.setInlineComment(path, readInlineComments(fieldInlineComments));
|
|
||||||
|
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
|
||||||
initializeField(clazz, field, path, saveDefaults, loadSubClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!loadSubClasses) return;
|
|
||||||
Class<?>[] classes = clazz.getDeclaredClasses();
|
|
||||||
for (int i = classes.length - 1; i >= 0; i--) { // 逆向加载,保持顺序。
|
|
||||||
initializeStaticClass(
|
|
||||||
classes[i], path, classes[i].getSimpleName(),
|
|
||||||
null, null, null,
|
|
||||||
saveDefaults, true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeField(@NotNull Object source, @NotNull Field field,
|
|
||||||
@Nullable String parent, boolean saveDefaults, boolean loadSubClasses) {
|
|
||||||
try {
|
|
||||||
field.setAccessible(true);
|
|
||||||
Object object = field.get(source);
|
|
||||||
|
|
||||||
if (object instanceof ConfigValue<?>) {
|
|
||||||
initializeValue(
|
|
||||||
(ConfigValue<?>) object, getFieldPath(field, parent),
|
|
||||||
field.getAnnotation(HeaderComment.class),
|
|
||||||
field.getAnnotation(InlineComment.class),
|
|
||||||
saveDefaults
|
|
||||||
);
|
|
||||||
} else if (source instanceof Configuration && object instanceof Configuration) {
|
|
||||||
// 当且仅当 源字段与字段 均为ConfigurationRoot实例时,才对目标字段进行下一步初始化加载。
|
|
||||||
initializeInstance(
|
|
||||||
(Configuration) object, parent, field.getName(),
|
|
||||||
field.getAnnotation(ConfigPath.class),
|
|
||||||
field.getAnnotation(HeaderComment.class),
|
|
||||||
field.getAnnotation(InlineComment.class),
|
|
||||||
saveDefaults
|
|
||||||
);
|
|
||||||
} else if (source instanceof Class<?> && object instanceof Class<?>) {
|
|
||||||
// 当且仅当 源字段与字段 均为静态类时,才对目标字段进行下一步初始化加载。
|
|
||||||
initializeStaticClass(
|
|
||||||
(Class<?>) object, parent, field.getName(),
|
|
||||||
field.getAnnotation(ConfigPath.class),
|
|
||||||
field.getAnnotation(HeaderComment.class),
|
|
||||||
field.getAnnotation(InlineComment.class),
|
|
||||||
saveDefaults, loadSubClasses
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 以上判断实现以下规范:
|
|
||||||
// - 实例类中仅加载 ConfigValue实例 与 ConfigurationRoot实例
|
|
||||||
// - 静态类中仅加载 静态ConfigValue实例 与 静态ConfigurationRoot类
|
|
||||||
|
|
||||||
} catch (IllegalAccessException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void initializeValue(@NotNull ConfigValue<?> value, @NotNull String path,
|
|
||||||
@Nullable HeaderComment fieldHeaderComment,
|
|
||||||
@Nullable InlineComment fieldInlineComment,
|
|
||||||
boolean saveDefaults) {
|
|
||||||
value.initialize(
|
|
||||||
provider, saveDefaults, path,
|
|
||||||
readHeaderComments(fieldHeaderComment),
|
|
||||||
readInlineComments(fieldInlineComment)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,17 +1,38 @@
|
|||||||
package cc.carm.lib.configuration.source;
|
package cc.carm.lib.configuration.source;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.Configuration;
|
||||||
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
||||||
import cc.carm.lib.configuration.core.Configuration;
|
import cc.carm.lib.configuration.loader.ConfigurationLoader;
|
||||||
import cc.carm.lib.easyoptions.OptionHolder;
|
import cc.carm.lib.easyoptions.OptionHolder;
|
||||||
import cc.carm.lib.easyoptions.OptionType;
|
import cc.carm.lib.easyoptions.OptionType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class ConfigurationProvider<P extends ConfigurationProvider<P>> {
|
public class ConfigurationProvider<S extends ConfigurationSource<S, ?>> {
|
||||||
|
|
||||||
protected @NotNull ConfigurationLoader<P> loader = new ConfigurationLoader<>();
|
protected final @NotNull S source;
|
||||||
protected @NotNull ValueAdapterRegistry<P> adapters = new ValueAdapterRegistry<>();
|
protected final @NotNull ConfigurationLoader loader;
|
||||||
protected @NotNull OptionHolder options = new OptionHolder();
|
protected final @NotNull ValueAdapterRegistry adapters;
|
||||||
|
protected final @NotNull OptionHolder options;
|
||||||
|
|
||||||
|
public ConfigurationProvider(@NotNull S source, @NotNull ConfigurationLoader loader,
|
||||||
|
@NotNull ValueAdapterRegistry adapters, @NotNull OptionHolder options) {
|
||||||
|
this.source = source;
|
||||||
|
this.loader = loader;
|
||||||
|
this.adapters = adapters;
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull S source() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() throws Exception {
|
||||||
|
source().reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() throws Exception {
|
||||||
|
source().save();
|
||||||
|
}
|
||||||
|
|
||||||
public OptionHolder options() {
|
public OptionHolder options() {
|
||||||
return options;
|
return options;
|
||||||
@ -25,13 +46,29 @@ public abstract class ConfigurationProvider<P extends ConfigurationProvider<P>>
|
|||||||
options.set(option, value);
|
options.set(option, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationLoader<P> loader() {
|
public ValueAdapterRegistry adapters() {
|
||||||
|
return this.adapters;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ConfigurationLoader loader() {
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(Configuration configuration) {
|
public void load(Class<? extends Configuration> configClass) {
|
||||||
loader().load(configuration);
|
try {
|
||||||
|
loader.load(this, configClass);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void load(@NotNull Configuration config) {
|
||||||
|
try {
|
||||||
|
loader.load(this, config);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,71 @@
|
|||||||
package cc.carm.lib.configuration.core.source;
|
package cc.carm.lib.configuration.source;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.function.ConfigValueParser;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
|
import cc.carm.lib.configuration.function.ConfigValueParser;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
interface ConfigurationReader {
|
public interface ConfigurationSection {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
Set<String> getKeys(boolean deep);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
Map<String, Object> getValues(boolean deep);
|
||||||
|
|
||||||
|
void set(@NotNull String path, @Nullable Object value);
|
||||||
|
|
||||||
|
boolean contains(@NotNull String path);
|
||||||
|
|
||||||
|
default <T> boolean isType(@NotNull String path, @NotNull Class<T> typeClass) {
|
||||||
|
return typeClass.isInstance(get(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isList(@NotNull String path);
|
||||||
|
|
||||||
|
@Nullable List<?> getList(@NotNull String path);
|
||||||
|
|
||||||
|
boolean isSection(@NotNull String path);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
ConfigurationSection getSection(@NotNull String path);
|
||||||
|
|
||||||
|
@Nullable Object get(@NotNull String path);
|
||||||
|
|
||||||
|
default @Nullable <T> T get(@NotNull String path, @NotNull Class<T> clazz) {
|
||||||
|
return get(path, null, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
default @Nullable <T> T get(@NotNull String path, @NotNull ConfigValueParser<Object, T> parser) {
|
||||||
|
return get(path, null, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract("_,!null,_->!null")
|
||||||
|
default @Nullable <T> T get(@NotNull String path, @Nullable T defaultValue, @NotNull Class<T> clazz) {
|
||||||
|
return get(path, defaultValue, ConfigValueParser.castObject(clazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract("_,!null,_->!null")
|
||||||
|
default @Nullable <T> T get(@NotNull String path, @Nullable T defaultValue,
|
||||||
|
@NotNull ConfigValueParser<Object, T> parser) {
|
||||||
|
Object value = get(path);
|
||||||
|
if (value != null) {
|
||||||
|
try {
|
||||||
|
return parser.parse(value, defaultValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
ConfigurationWrapper<?> getWrapper();
|
|
||||||
|
|
||||||
default boolean isBoolean(@NotNull String path) {
|
default boolean isBoolean(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Boolean.class);
|
return isType(path, Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean getBoolean(@NotNull String path) {
|
default boolean getBoolean(@NotNull String path) {
|
||||||
@ -24,11 +74,11 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Boolean getBoolean(@NotNull String path, @Nullable Boolean def) {
|
default @Nullable Boolean getBoolean(@NotNull String path, @Nullable Boolean def) {
|
||||||
return getWrapper().get(path, def, ConfigValueParser.booleanValue());
|
return get(path, def, ConfigValueParser.booleanValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Boolean isByte(@NotNull String path) {
|
default @Nullable Boolean isByte(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Byte.class);
|
return isType(path, Byte.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Byte getByte(@NotNull String path) {
|
default @Nullable Byte getByte(@NotNull String path) {
|
||||||
@ -37,11 +87,11 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Byte getByte(@NotNull String path, @Nullable Byte def) {
|
default @Nullable Byte getByte(@NotNull String path, @Nullable Byte def) {
|
||||||
return getWrapper().get(path, def, ConfigValueParser.byteValue());
|
return get(path, def, ConfigValueParser.byteValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean isShort(@NotNull String path) {
|
default boolean isShort(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Short.class);
|
return isType(path, Short.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Short getShort(@NotNull String path) {
|
default @Nullable Short getShort(@NotNull String path) {
|
||||||
@ -50,12 +100,12 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Short getShort(@NotNull String path, @Nullable Short def) {
|
default @Nullable Short getShort(@NotNull String path, @Nullable Short def) {
|
||||||
return getWrapper().get(path, def, ConfigValueParser.shortValue());
|
return get(path, def, ConfigValueParser.shortValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default boolean isInt(@NotNull String path) {
|
default boolean isInt(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Integer.class);
|
return isType(path, Integer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Integer getInt(@NotNull String path) {
|
default @Nullable Integer getInt(@NotNull String path) {
|
||||||
@ -64,12 +114,12 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Integer getInt(@NotNull String path, @Nullable Integer def) {
|
default @Nullable Integer getInt(@NotNull String path, @Nullable Integer def) {
|
||||||
return getWrapper().get(path, def, ConfigValueParser.intValue());
|
return get(path, def, ConfigValueParser.intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default boolean isLong(@NotNull String path) {
|
default boolean isLong(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Long.class);
|
return isType(path, Long.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Long getLong(@NotNull String path) {
|
default @Nullable Long getLong(@NotNull String path) {
|
||||||
@ -78,12 +128,12 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Long getLong(@NotNull String path, @Nullable Long def) {
|
default @Nullable Long getLong(@NotNull String path, @Nullable Long def) {
|
||||||
return getWrapper().get(path, def, ConfigValueParser.longValue());
|
return get(path, def, ConfigValueParser.longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default boolean isFloat(@NotNull String path) {
|
default boolean isFloat(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Float.class);
|
return isType(path, Float.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Float getFloat(@NotNull String path) {
|
default @Nullable Float getFloat(@NotNull String path) {
|
||||||
@ -92,12 +142,12 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Float getFloat(@NotNull String path, @Nullable Float def) {
|
default @Nullable Float getFloat(@NotNull String path, @Nullable Float def) {
|
||||||
return getWrapper().get(path, def, ConfigValueParser.floatValue());
|
return get(path, def, ConfigValueParser.floatValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default boolean isDouble(@NotNull String path) {
|
default boolean isDouble(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Double.class);
|
return isType(path, Double.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Double getDouble(@NotNull String path) {
|
default @Nullable Double getDouble(@NotNull String path) {
|
||||||
@ -106,12 +156,12 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Double getDouble(@NotNull String path, @Nullable Double def) {
|
default @Nullable Double getDouble(@NotNull String path, @Nullable Double def) {
|
||||||
return getWrapper().get(path, def, ConfigValueParser.doubleValue());
|
return get(path, def, ConfigValueParser.doubleValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default boolean isChar(@NotNull String path) {
|
default boolean isChar(@NotNull String path) {
|
||||||
return getWrapper().isType(path, Boolean.class);
|
return isType(path, Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable Character getChar(@NotNull String path) {
|
default @Nullable Character getChar(@NotNull String path) {
|
||||||
@ -120,12 +170,12 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable Character getChar(@NotNull String path, @Nullable Character def) {
|
default @Nullable Character getChar(@NotNull String path, @Nullable Character def) {
|
||||||
return getWrapper().get(path, def, Character.class);
|
return get(path, def, Character.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default boolean isString(@NotNull String path) {
|
default boolean isString(@NotNull String path) {
|
||||||
return getWrapper().isType(path, String.class);
|
return isType(path, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable String getString(@NotNull String path) {
|
default @Nullable String getString(@NotNull String path) {
|
||||||
@ -134,61 +184,59 @@ interface ConfigurationReader {
|
|||||||
|
|
||||||
@Contract("_, !null -> !null")
|
@Contract("_, !null -> !null")
|
||||||
default @Nullable String getString(@NotNull String path, @Nullable String def) {
|
default @Nullable String getString(@NotNull String path, @Nullable String def) {
|
||||||
return getWrapper().get(path, def, String.class);
|
return get(path, def, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
default <V> @NotNull List<V> getList(@NotNull String path, @NotNull ConfigValueParser<Object, V> parser) {
|
default <V> @NotNull List<V> getList(@NotNull String path, @NotNull ConfigDataFunction<Object, V> parser) {
|
||||||
return parseList(getWrapper().getList(path), parser);
|
return parseList(getList(path), parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
default @NotNull List<String> getStringList(@NotNull String path) {
|
default @NotNull List<String> getStringList(@NotNull String path) {
|
||||||
return getList(path, ConfigValueParser.castToString());
|
return getList(path, ConfigDataFunction.castToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
default @NotNull List<Integer> getIntegerList(@NotNull String path) {
|
default @NotNull List<Integer> getIntegerList(@NotNull String path) {
|
||||||
return getList(path, ConfigValueParser.intValue());
|
return getList(path, ConfigDataFunction.intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
default @NotNull List<Long> getLongList(@NotNull String path) {
|
default @NotNull List<Long> getLongList(@NotNull String path) {
|
||||||
return getList(path, ConfigValueParser.longValue());
|
return getList(path, ConfigDataFunction.longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
default @NotNull List<Double> getDoubleList(@NotNull String path) {
|
default @NotNull List<Double> getDoubleList(@NotNull String path) {
|
||||||
return getList(path, ConfigValueParser.doubleValue());
|
return getList(path, ConfigDataFunction.doubleValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
default @NotNull List<Float> getFloatList(@NotNull String path) {
|
default @NotNull List<Float> getFloatList(@NotNull String path) {
|
||||||
return getList(path, ConfigValueParser.floatValue());
|
return getList(path, ConfigDataFunction.floatValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
default @NotNull List<Byte> getByteList(@NotNull String path) {
|
default @NotNull List<Byte> getByteList(@NotNull String path) {
|
||||||
return getList(path, ConfigValueParser.byteValue());
|
return getList(path, ConfigDataFunction.byteValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
default @NotNull List<Character> getCharList(@NotNull String path) {
|
default @NotNull List<Character> getCharList(@NotNull String path) {
|
||||||
return getList(path, ConfigValueParser.castObject(Character.class));
|
return getList(path, ConfigDataFunction.castObject(Character.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
static <T> @NotNull List<T> parseList(@Nullable List<?> list, ConfigValueParser<Object, T> parser) {
|
static <T> @NotNull List<T> parseList(@Nullable List<?> list, ConfigDataFunction<Object, T> parser) {
|
||||||
if (list == null) return Collections.emptyList();
|
if (list == null) return Collections.emptyList();
|
||||||
List<T> values = new ArrayList<>();
|
List<T> values = new ArrayList<>();
|
||||||
for (Object o : list) {
|
for (Object o : list) {
|
||||||
try {
|
try {
|
||||||
T parsed = parser.parse(o, null);
|
values.add(parser.parse(o));
|
||||||
if (parsed != null) values.add(parsed);
|
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package cc.carm.lib.configuration.source;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public abstract class ConfigurationSource<S extends ConfigurationSource<S, O>, O> implements ConfigurationSection {
|
||||||
|
|
||||||
|
protected long updateMillis;
|
||||||
|
|
||||||
|
protected ConfigurationSource(long updateMillis) {
|
||||||
|
this.updateMillis = updateMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() throws Exception {
|
||||||
|
onReload(); // 调用重写的Reload方法
|
||||||
|
this.updateMillis = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract S getThis();
|
||||||
|
|
||||||
|
public abstract void save() throws Exception;
|
||||||
|
|
||||||
|
protected abstract void onReload() throws Exception;
|
||||||
|
|
||||||
|
public abstract @NotNull O original();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Set<String> getKeys(boolean deep) {
|
||||||
|
return getValues(deep).keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getUpdateMillis() {
|
||||||
|
return this.updateMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExpired(long time) {
|
||||||
|
return getUpdateMillis() > time;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.source.path;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public interface PathGenerator<P extends ConfigurationProvider<P>> {
|
|
||||||
|
|
||||||
@Nullable String getFieldPath(@Nullable String parentPath, @NotNull Field field);
|
|
||||||
|
|
||||||
@Nullable String getClassPath(@Nullable String parentPath,
|
|
||||||
@NotNull Class<?> clazz, @Nullable Field clazzField);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configuration name of the specified element.
|
|
||||||
* Use the naming convention of all lowercase and "-" links.
|
|
||||||
*
|
|
||||||
* @param name source name
|
|
||||||
* @return the final path
|
|
||||||
*/
|
|
||||||
static String covertPathName(String name) {
|
|
||||||
return name.replaceAll("[A-Z]", "-$0") // 将驼峰形转换为蛇形;
|
|
||||||
.replaceAll("-(.*)", "$1") // 若首字母也为大写,则也会被转换,需要去掉第一个横线
|
|
||||||
.replaceAll("_-([A-Z])", "_$1") // 因为命名中可能包含 _,因此需要被特殊处理一下
|
|
||||||
.replaceAll("([a-z])-([A-Z])", "$1_$2") // 然后将非全大写命名的内容进行转换
|
|
||||||
.replace("-", "") // 移除掉多余的横线
|
|
||||||
.replace("_", "-") // 将下划线替换为横线
|
|
||||||
.toLowerCase(); // 最后转为全小写
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.source.path;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
|
||||||
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
|
||||||
import cc.carm.lib.configuration.source.standard.ConfigurationOptions;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class StandardPathGenerator<P extends ConfigurationProvider<P>> implements PathGenerator<P> {
|
|
||||||
|
|
||||||
public static <T extends ConfigurationProvider<T>> StandardPathGenerator<T> of(T provider) {
|
|
||||||
return of(provider, PathGenerator::covertPathName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends ConfigurationProvider<T>> StandardPathGenerator<T> of(T provider, UnaryOperator<String> pathConverter) {
|
|
||||||
return new StandardPathGenerator<>(provider, pathConverter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final P provider;
|
|
||||||
protected UnaryOperator<String> pathConverter;
|
|
||||||
|
|
||||||
public StandardPathGenerator(P provider, UnaryOperator<String> pathConverter) {
|
|
||||||
this.provider = provider;
|
|
||||||
this.pathConverter = pathConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull UnaryOperator<String> getPathConverter() {
|
|
||||||
return pathConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPathConverter(UnaryOperator<String> pathConverter) {
|
|
||||||
this.pathConverter = pathConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String covertPath(String name) {
|
|
||||||
return pathConverter.apply(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public char pathSeparator() {
|
|
||||||
return provider.option(ConfigurationOptions.PATH_SEPARATOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String link(@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() + covertPath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable String getFieldPath(@Nullable String parentPath, @NotNull Field field) {
|
|
||||||
ConfigPath path = field.getAnnotation(ConfigPath.class);
|
|
||||||
if (path == null) return link(parentPath, false, field.getName()); // No annotation, use field name.
|
|
||||||
else return link(parentPath, path.root(), path.value().isEmpty() ? field.getName() : path.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable String getClassPath(@Nullable String parentPath, @NotNull Class<?> clazz, @Nullable Field clazzField) {
|
|
||||||
// For standard path generator, we generate path following by:
|
|
||||||
// 1. Check if the class has a ConfigPath annotation, if so, use the root and value as the path.
|
|
||||||
// 2. If the class defined as a field, check if the field has a ConfigPath annotation,
|
|
||||||
// and use filed information.
|
|
||||||
ConfigPath clazzPath = clazz.getAnnotation(ConfigPath.class);
|
|
||||||
|
|
||||||
if (clazzPath != null) return link(parentPath, clazzPath.root(), clazzPath.value());
|
|
||||||
if (clazzField == null) return parentPath; // No field, return same as parent.
|
|
||||||
|
|
||||||
ConfigPath fieldPath = clazzField.getAnnotation(ConfigPath.class);
|
|
||||||
if (fieldPath == null) return link(parentPath, false, clazzField.getName());
|
|
||||||
else return getFieldPath(parentPath, clazzField);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.source.standard;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
|
||||||
import cc.carm.lib.easyannotation.AnnotatedMetaType;
|
|
||||||
|
|
||||||
public interface ConfigurationMetaTypes {
|
|
||||||
|
|
||||||
AnnotatedMetaType<ConfigPath, String> PATH = AnnotatedMetaType.of(ConfigPath.class, ConfigPath::value);
|
|
||||||
|
|
||||||
AnnotatedMetaType<ConfigPath, Boolean> ROOT = AnnotatedMetaType.of(ConfigPath.class, ConfigPath::root);
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +1,20 @@
|
|||||||
package cc.carm.lib.configuration.value;
|
package cc.carm.lib.configuration.value;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.ConfigBuilder;
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public abstract class ConfigValue<T> extends ValueManifest<T> {
|
public abstract class ConfigValue<T> extends ValueManifest<T> {
|
||||||
|
|
||||||
public static @NotNull ConfigBuilder builder() {
|
// public static @NotNull ConfigBuilder builder() {
|
||||||
return new ConfigBuilder();
|
// return new ConfigBuilder();
|
||||||
}
|
// }
|
||||||
|
|
||||||
protected ConfigValue(@NotNull ValueManifest<T> manifest) {
|
protected ConfigValue(@NotNull ValueManifest<T> manifest) {
|
||||||
super(manifest.provider, manifest.configPath, manifest.headerComments, manifest.inlineComment, manifest.defaultValue);
|
super(manifest.metadata, manifest.provider, manifest.defaultSupplier);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param provider Provider of config files {@link ConfigurationProvider}
|
|
||||||
* @param configPath Config path of this value
|
|
||||||
* @param headerComments Header comment contents
|
|
||||||
* @param inlineComments Inline comment contents
|
|
||||||
* @param defaultValue The default value
|
|
||||||
* @deprecated Please use {@link #ConfigValue(ValueManifest)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
protected ConfigValue(@Nullable ConfigurationProvider<?> provider, @Nullable String configPath,
|
|
||||||
@Nullable List<String> headerComments, @Nullable String inlineComments,
|
|
||||||
@Nullable T defaultValue) {
|
|
||||||
super(provider, configPath, headerComments, inlineComments, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize(@NotNull ConfigurationProvider<?> provider, boolean saveDefault, @NotNull String configPath,
|
|
||||||
@Nullable List<String> headerComments, @Nullable String inlineComments) {
|
|
||||||
this.initialize(provider, configPath, headerComments, inlineComments);
|
|
||||||
if (saveDefault) setDefault();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,8 +30,8 @@ public abstract class ConfigValue<T> extends ValueManifest<T> {
|
|||||||
*
|
*
|
||||||
* @return 设定值或默认值
|
* @return 设定值或默认值
|
||||||
*/
|
*/
|
||||||
public @Nullable T getOrDefault() {
|
public T getOrDefault() {
|
||||||
return getOptional().orElse(getDefaultValue());
|
return optional().orElse(defaults());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,10 +41,10 @@ public abstract class ConfigValue<T> extends ValueManifest<T> {
|
|||||||
* @throws NullPointerException 对应数据为空时抛出
|
* @throws NullPointerException 对应数据为空时抛出
|
||||||
*/
|
*/
|
||||||
public @NotNull T getNotNull() {
|
public @NotNull T getNotNull() {
|
||||||
return Objects.requireNonNull(getOrDefault(), "Value(" + configPath + ") is null.");
|
return Objects.requireNonNull(getOrDefault(), "Value(" + path() + ") is null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull Optional<@Nullable T> getOptional() {
|
public @NotNull Optional<@Nullable T> optional() {
|
||||||
return Optional.ofNullable(get());
|
return Optional.ofNullable(get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,8 +71,8 @@ public abstract class ConfigValue<T> extends ValueManifest<T> {
|
|||||||
* @param override 是否覆盖已设定的值
|
* @param override 是否覆盖已设定的值
|
||||||
*/
|
*/
|
||||||
public void setDefault(boolean override) {
|
public void setDefault(boolean override) {
|
||||||
if (!override && getConfiguration().contains(getConfigPath())) return;
|
if (!override && config().contains(path())) return;
|
||||||
Optional.ofNullable(getDefaultValue()).ifPresent(this::set);
|
Optional.ofNullable(defaults()).ifPresent(this::set);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +81,7 @@ public abstract class ConfigValue<T> extends ValueManifest<T> {
|
|||||||
* @return 获取当前值是否为默认值。
|
* @return 获取当前值是否为默认值。
|
||||||
*/
|
*/
|
||||||
public boolean isDefault() {
|
public boolean isDefault() {
|
||||||
return Objects.equals(getDefaultValue(), get());
|
return Objects.equals(defaults(), get());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,124 +1,150 @@
|
|||||||
package cc.carm.lib.configuration.value;
|
package cc.carm.lib.configuration.value;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
import cc.carm.lib.configuration.source.ConfigurationSource;
|
||||||
|
import cc.carm.lib.configuration.value.meta.ValueMetaList;
|
||||||
|
import cc.carm.lib.configuration.value.meta.ValueMetaType;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Optional;
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
|
||||||
* ConfigValue Manifests.
|
|
||||||
* The basic information that describes a configuration value.
|
|
||||||
*
|
|
||||||
* @param <T> Value type
|
|
||||||
* @author CarmJos
|
|
||||||
*/
|
|
||||||
public class ValueManifest<T> {
|
public class ValueManifest<T> {
|
||||||
|
|
||||||
public static <V> ValueManifest<V> of(@Nullable ConfigurationProvider<?> provider, @Nullable String configPath,
|
protected final @NotNull Map<ValueMetaType<?>, Object> metadata;
|
||||||
@Nullable List<String> headerComments, @Nullable String inlineComments) {
|
|
||||||
return new ValueManifest<>(provider, configPath, headerComments, inlineComments, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <V> ValueManifest<V> of(@Nullable ConfigurationProvider<?> provider, @Nullable String configPath,
|
|
||||||
@Nullable List<String> headerComments, @Nullable String inlineComments,
|
|
||||||
@Nullable V defaultValue) {
|
|
||||||
return new ValueManifest<>(provider, configPath, headerComments, inlineComments, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected @Nullable ConfigurationProvider<?> provider;
|
protected @Nullable ConfigurationProvider<?> provider;
|
||||||
protected @Nullable String configPath;
|
protected @NotNull Supplier<@Nullable T> defaultSupplier;
|
||||||
|
|
||||||
protected @Nullable List<String> headerComments;
|
public ValueManifest(@NotNull Map<ValueMetaType<?>, Object> metadata,
|
||||||
protected @Nullable String inlineComment;
|
@Nullable ConfigurationProvider<?> provider, @NotNull Supplier<@Nullable T> defaultSupplier) {
|
||||||
|
this.metadata = metadata;
|
||||||
protected @Nullable T defaultValue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param provider Provider of config files {@link ConfigurationProvider}
|
|
||||||
* @param configPath Config path of this value
|
|
||||||
* @param headerComments Header comment contents
|
|
||||||
* @param inlineComment Inline comment content
|
|
||||||
* @param defaultValue The default value
|
|
||||||
*/
|
|
||||||
public ValueManifest(@Nullable ConfigurationProvider<?> provider, @Nullable String configPath,
|
|
||||||
@Nullable List<String> headerComments, @Nullable String inlineComment,
|
|
||||||
@Nullable T defaultValue) {
|
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.configPath = configPath;
|
this.defaultSupplier = defaultSupplier;
|
||||||
this.headerComments = headerComments;
|
|
||||||
this.inlineComment = inlineComment;
|
|
||||||
this.defaultValue = defaultValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public @Nullable T defaults() {
|
||||||
* The initialize method for {@link ConfigInitializer}, which is used to initialize the value.
|
return this.defaultSupplier.get();
|
||||||
*
|
|
||||||
* @param provider Provider of config files {@link ConfigurationProvider}
|
|
||||||
* @param configPath Config path of this value
|
|
||||||
* @param headerComments Header comment contents
|
|
||||||
* @param inlineComment Inline comment content
|
|
||||||
*/
|
|
||||||
protected void initialize(@NotNull ConfigurationProvider<?> provider, @NotNull String configPath,
|
|
||||||
@Nullable List<String> headerComments, @Nullable String inlineComment) {
|
|
||||||
if (this.provider == null) this.provider = provider;
|
|
||||||
if (this.configPath == null) this.configPath = configPath;
|
|
||||||
if (this.headerComments == null) this.headerComments = headerComments;
|
|
||||||
if (this.inlineComment == null) this.inlineComment = inlineComment;
|
|
||||||
|
|
||||||
if (getHeaderComments() != null) {
|
|
||||||
this.provider.setHeaderComment(getConfigPath(), getHeaderComments());
|
|
||||||
}
|
|
||||||
if (getInlineComment() != null) {
|
|
||||||
this.provider.setInlineComment(getConfigPath(), getInlineComment());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable T getDefaultValue() {
|
public void defaults(@Nullable T defaultValue) {
|
||||||
return this.defaultValue;
|
defaults(() -> defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultValue(@Nullable T defaultValue) {
|
public void defaults(@NotNull Supplier<@Nullable T> defaultValue) {
|
||||||
this.defaultValue = defaultValue;
|
this.defaultSupplier = defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull ConfigurationProvider<?> getProvider() {
|
public @NotNull ConfigurationProvider<?> provider() {
|
||||||
return Optional.ofNullable(this.provider)
|
if (this.provider != null) return this.provider;
|
||||||
.orElseThrow(() -> new IllegalStateException("Value(" + configPath + ") does not have a provider."));
|
throw new IllegalStateException("Value does not have a provider.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public final @NotNull ConfigurationWrapper<?> getConfiguration() {
|
public @NotNull ConfigurationSource<?, ?> config() {
|
||||||
try {
|
return provider().source();
|
||||||
return getProvider().getConfiguration();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new IllegalStateException("Value(" + configPath + ") has not been initialized", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull String getConfigPath() {
|
public @NotNull String path() {
|
||||||
return Optional.ofNullable(this.configPath)
|
String path = getMeta(ValueMetaList.PATH);
|
||||||
.orElseThrow(() -> new IllegalStateException("No section path provided."));
|
if (path != null) return path;
|
||||||
|
else throw new IllegalStateException("No section path provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object getValue() {
|
protected Object getValue() {
|
||||||
String path = getConfigPath(); // 当未指定路径时,优先抛出异常
|
return config().get(path());
|
||||||
return getConfiguration().get(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setValue(@Nullable Object value) {
|
protected void setValue(@Nullable Object value) {
|
||||||
getConfiguration().set(getConfigPath(), value);
|
config().set(path(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String getInlineComment() {
|
public Map<ValueMetaType<?>, Object> metadata() {
|
||||||
return inlineComment;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmodifiable
|
/**
|
||||||
public @Nullable List<String> getHeaderComments() {
|
* Get the value of option.
|
||||||
return headerComments;
|
*
|
||||||
|
* @param type {@link ValueMetaType}
|
||||||
|
* @param defaultValue Default value if the value of option is not set.
|
||||||
|
* @param <V> Value type
|
||||||
|
* @return Value of option
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Contract("_, !null -> !null")
|
||||||
|
public <V> @Nullable V getMeta(@NotNull ValueMetaType<V> type, @Nullable V defaultValue) {
|
||||||
|
return (V) metadata().getOrDefault(type, type.getDefault(this, defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of option.
|
||||||
|
*
|
||||||
|
* @param type {@link ValueMetaType}
|
||||||
|
* @param <V> Value type
|
||||||
|
* @return Value of option
|
||||||
|
*/
|
||||||
|
public <V> @Nullable V getMeta(@NotNull ValueMetaType<V> type) {
|
||||||
|
return getMeta(type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMeta(@NotNull ValueMetaType<?> type) {
|
||||||
|
return metadata().containsKey(type) || type.hasDefaults(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of meta, if the value is null, the meta will be removed.
|
||||||
|
* <br> Will only be changed in current holder.
|
||||||
|
*
|
||||||
|
* @param type {@link ValueMetaType}
|
||||||
|
* @param value Value of meta
|
||||||
|
* @param <V> Value type
|
||||||
|
* @return Previous value of meta
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <V> @Nullable V setMeta(@NotNull ValueMetaType<V> type, @Nullable V value) {
|
||||||
|
if (value == null || type.isDefault(this, value)) {
|
||||||
|
return (V) metadata().remove(type);
|
||||||
|
} else {
|
||||||
|
return (V) metadata().put(type, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of meta, if the value is null, the meta will not be changed.
|
||||||
|
* <br> Will only be changed in current holder.
|
||||||
|
*
|
||||||
|
* @param type {@link ValueMetaType}
|
||||||
|
* @param value Value of meta
|
||||||
|
* @param <V> Value type
|
||||||
|
*/
|
||||||
|
public <V> void setMetaIfAbsent(@NotNull ValueMetaType<V> type, @Nullable V value) {
|
||||||
|
if (value == null || type.isDefault(this, value)) {
|
||||||
|
metadata().remove(type);
|
||||||
|
} else {
|
||||||
|
metadata().putIfAbsent(type, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of meta, if the value is null, the meta will not be changed.
|
||||||
|
* <br> Will only be changed in current holder.
|
||||||
|
*
|
||||||
|
* @param type {@link ValueMetaType}
|
||||||
|
* @param value Value of meta
|
||||||
|
* @param <V> Value type
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <V> @Nullable V setMetaIfPresent(@NotNull ValueMetaType<V> type, @Nullable V value) {
|
||||||
|
Object exists = metadata().get(type);
|
||||||
|
if (exists == null) return null;
|
||||||
|
|
||||||
|
if (value == null || type.isDefault(this, value)) {
|
||||||
|
return (V) metadata().remove(type);
|
||||||
|
} else {
|
||||||
|
return (V) metadata().put(type, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
public abstract class CachedConfigValue<T> extends ConfigValue<T> {
|
public abstract class CachedConfigValue<T> extends ConfigValue<T> {
|
||||||
|
|
||||||
|
|
||||||
protected @Nullable T cachedValue;
|
protected @Nullable T cachedValue;
|
||||||
protected long parsedTime = -1;
|
protected long parsedTime = -1;
|
||||||
|
|
||||||
@ -27,11 +26,11 @@ public abstract class CachedConfigValue<T> extends ConfigValue<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
return this.parsedTime <= 0 || getProvider().isExpired(this.parsedTime);
|
return this.parsedTime <= 0 || config().isExpired(this.parsedTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final T getDefaultFirst(@Nullable T value) {
|
protected final T getDefaultFirst(@Nullable T value) {
|
||||||
return updateCache(this.defaultValue == null ? value : this.defaultValue);
|
return updateCache(this.defaultSupplier == null ? value : this.defaultSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected @Nullable T getCachedOrDefault() {
|
protected @Nullable T getCachedOrDefault() {
|
||||||
@ -41,7 +40,7 @@ public abstract class CachedConfigValue<T> extends ConfigValue<T> {
|
|||||||
@Contract("!null->!null")
|
@Contract("!null->!null")
|
||||||
protected T getCachedOrDefault(@Nullable T emptyValue) {
|
protected T getCachedOrDefault(@Nullable T emptyValue) {
|
||||||
if (getCachedValue() != null) return getCachedValue();
|
if (getCachedValue() != null) return getCachedValue();
|
||||||
else if (getDefaultValue() != null) return getDefaultValue();
|
else if (defaults() != null) return defaults();
|
||||||
else return emptyValue;
|
else return emptyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,214 +1,213 @@
|
|||||||
package cc.carm.lib.configuration.value.impl;
|
//package cc.carm.lib.configuration.value.impl;
|
||||||
|
//
|
||||||
import cc.carm.lib.configuration.core.builder.map.ConfigMapCreator;
|
//import cc.carm.lib.configuration.builder.map.ConfigMapCreator;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
//import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
//import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
//import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.NotNull;
|
//import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.Nullable;
|
//import org.jetbrains.annotations.Unmodifiable;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
//
|
||||||
|
//import java.util.*;
|
||||||
import java.util.*;
|
//import java.util.function.Consumer;
|
||||||
import java.util.function.Consumer;
|
//import java.util.function.Function;
|
||||||
import java.util.function.Function;
|
//import java.util.function.Supplier;
|
||||||
import java.util.function.Supplier;
|
//
|
||||||
|
//public abstract class ConfigValueMap<K, V, S> extends CachedConfigValue<Map<K, V>> implements Map<K, V> {
|
||||||
public abstract class ConfigValueMap<K, V, S> extends CachedConfigValue<Map<K, V>> implements Map<K, V> {
|
//
|
||||||
|
// public static <K, V> @NotNull ConfigMapCreator<K, V> builderOf(@NotNull Class<K> keyClass,
|
||||||
public static <K, V> @NotNull ConfigMapCreator<K, V> builderOf(@NotNull Class<K> keyClass,
|
// @NotNull Class<V> valueClass) {
|
||||||
@NotNull Class<V> valueClass) {
|
// return builder().asMap(keyClass, valueClass);
|
||||||
return builder().asMap(keyClass, valueClass);
|
// }
|
||||||
}
|
//
|
||||||
|
// protected final @NotNull Supplier<? extends Map<K, V>> supplier;
|
||||||
protected final @NotNull Supplier<? extends Map<K, V>> supplier;
|
//
|
||||||
|
// protected final @NotNull Class<? super S> sourceClass;
|
||||||
protected final @NotNull Class<? super S> sourceClass;
|
// protected final @NotNull Class<K> keyClass;
|
||||||
protected final @NotNull Class<K> keyClass;
|
// protected final @NotNull Class<V> valueClass;
|
||||||
protected final @NotNull Class<V> valueClass;
|
//
|
||||||
|
// protected final @NotNull ConfigDataFunction<String, K> keyParser;
|
||||||
protected final @NotNull ConfigDataFunction<String, K> keyParser;
|
// protected final @NotNull ConfigDataFunction<S, V> valueParser;
|
||||||
protected final @NotNull ConfigDataFunction<S, V> valueParser;
|
//
|
||||||
|
// protected final @NotNull ConfigDataFunction<K, String> keySerializer;
|
||||||
protected final @NotNull ConfigDataFunction<K, String> keySerializer;
|
// protected final @NotNull ConfigDataFunction<V, Object> valueSerializer;
|
||||||
protected final @NotNull ConfigDataFunction<V, Object> valueSerializer;
|
//
|
||||||
|
//
|
||||||
|
// protected ConfigValueMap(@NotNull ValueManifest<Map<K, V>> manifest, @NotNull Class<? super S> sourceClass,
|
||||||
protected ConfigValueMap(@NotNull ValueManifest<Map<K, V>> manifest, @NotNull Class<? super S> sourceClass,
|
// @NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
||||||
@NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
// @NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
||||||
@NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
// @NotNull Class<V> valueClass, @NotNull ConfigDataFunction<S, V> valueParser,
|
||||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<S, V> valueParser,
|
// @NotNull ConfigDataFunction<K, String> keySerializer,
|
||||||
@NotNull ConfigDataFunction<K, String> keySerializer,
|
// @NotNull ConfigDataFunction<V, Object> valueSerializer) {
|
||||||
@NotNull ConfigDataFunction<V, Object> valueSerializer) {
|
// super(manifest);
|
||||||
super(manifest);
|
// this.supplier = mapObjSupplier;
|
||||||
this.supplier = mapObjSupplier;
|
// this.sourceClass = sourceClass;
|
||||||
this.sourceClass = sourceClass;
|
// this.keyClass = keyClass;
|
||||||
this.keyClass = keyClass;
|
// this.valueClass = valueClass;
|
||||||
this.valueClass = valueClass;
|
// this.keyParser = keyParser;
|
||||||
this.keyParser = keyParser;
|
// this.valueParser = valueParser;
|
||||||
this.valueParser = valueParser;
|
// this.keySerializer = keySerializer;
|
||||||
this.keySerializer = keySerializer;
|
// this.valueSerializer = valueSerializer;
|
||||||
this.valueSerializer = valueSerializer;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull Class<? super S> getSourceClass() {
|
||||||
public @NotNull Class<? super S> getSourceClass() {
|
// return sourceClass;
|
||||||
return sourceClass;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull Class<K> getKeyClass() {
|
||||||
public @NotNull Class<K> getKeyClass() {
|
// return keyClass;
|
||||||
return keyClass;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull Class<V> getValueClass() {
|
||||||
public @NotNull Class<V> getValueClass() {
|
// return valueClass;
|
||||||
return valueClass;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull ConfigDataFunction<String, K> getKeyParser() {
|
||||||
public @NotNull ConfigDataFunction<String, K> getKeyParser() {
|
// return keyParser;
|
||||||
return keyParser;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull ConfigDataFunction<S, V> getValueParser() {
|
||||||
public @NotNull ConfigDataFunction<S, V> getValueParser() {
|
// return valueParser;
|
||||||
return valueParser;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull ConfigDataFunction<K, String> getKeySerializer() {
|
||||||
public @NotNull ConfigDataFunction<K, String> getKeySerializer() {
|
// return keySerializer;
|
||||||
return keySerializer;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull ConfigDataFunction<V, Object> getValueSerializer() {
|
||||||
public @NotNull ConfigDataFunction<V, Object> getValueSerializer() {
|
// return valueSerializer;
|
||||||
return valueSerializer;
|
// }
|
||||||
}
|
//
|
||||||
|
// public abstract S getSource(ConfigurationWrapper<?> section, String dataKey);
|
||||||
public abstract S getSource(ConfigurationWrapper<?> section, String dataKey);
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public @NotNull Map<K, V> get() {
|
||||||
public @NotNull Map<K, V> get() {
|
// if (!isExpired()) return getCachedOrDefault(supplier.get());
|
||||||
if (!isExpired()) return getCachedOrDefault(supplier.get());
|
//
|
||||||
|
// // 已过时的数据,需要重新解析一次。
|
||||||
// 已过时的数据,需要重新解析一次。
|
// Map<K, V> map = supplier.get();
|
||||||
Map<K, V> map = supplier.get();
|
//
|
||||||
|
// ConfigurationWrapper<?> section = getConfiguration().getConfigurationSection(getConfigPath());
|
||||||
ConfigurationWrapper<?> section = getConfiguration().getConfigurationSection(getConfigPath());
|
// if (section == null) return getDefaultFirst(map);
|
||||||
if (section == null) return getDefaultFirst(map);
|
//
|
||||||
|
// Set<String> keys = section.getKeys(false);
|
||||||
Set<String> keys = section.getKeys(false);
|
// if (keys.isEmpty()) return getDefaultFirst(map);
|
||||||
if (keys.isEmpty()) return getDefaultFirst(map);
|
//
|
||||||
|
// for (String dataKey : keys) {
|
||||||
for (String dataKey : keys) {
|
// S dataVal = getSource(section, dataKey);
|
||||||
S dataVal = getSource(section, dataKey);
|
// if (dataVal == null) continue;
|
||||||
if (dataVal == null) continue;
|
// try {
|
||||||
try {
|
// K key = keyParser.parse(dataKey);
|
||||||
K key = keyParser.parse(dataKey);
|
// V value = valueParser.parse(dataVal);
|
||||||
V value = valueParser.parse(dataVal);
|
// map.put(key, value);
|
||||||
map.put(key, value);
|
// } catch (Exception e) {
|
||||||
} catch (Exception e) {
|
// e.printStackTrace();
|
||||||
e.printStackTrace();
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
// return updateCache(map);
|
||||||
return updateCache(map);
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public V get(Object key) {
|
||||||
public V get(Object key) {
|
// return get().get(key);
|
||||||
return get().get(key);
|
// }
|
||||||
}
|
//
|
||||||
|
// public V getNotNull(Object key) {
|
||||||
public V getNotNull(Object key) {
|
// return Objects.requireNonNull(get(key));
|
||||||
return Objects.requireNonNull(get(key));
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public void set(@Nullable Map<K, V> value) {
|
||||||
public void set(@Nullable Map<K, V> value) {
|
// updateCache(value);
|
||||||
updateCache(value);
|
// if (value == null) setValue(null);
|
||||||
if (value == null) setValue(null);
|
// else {
|
||||||
else {
|
// Map<String, Object> data = new LinkedHashMap<>();
|
||||||
Map<String, Object> data = new LinkedHashMap<>();
|
// for (Map.Entry<K, V> entry : value.entrySet()) {
|
||||||
for (Map.Entry<K, V> entry : value.entrySet()) {
|
// try {
|
||||||
try {
|
// data.put(
|
||||||
data.put(
|
// keySerializer.parse(entry.getKey()),
|
||||||
keySerializer.parse(entry.getKey()),
|
// valueSerializer.parse(entry.getValue())
|
||||||
valueSerializer.parse(entry.getValue())
|
// );
|
||||||
);
|
// } catch (Exception e) {
|
||||||
} catch (Exception e) {
|
// e.printStackTrace();
|
||||||
e.printStackTrace();
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// setValue(data);
|
||||||
setValue(data);
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
// public <T> @NotNull T modifyValue(Function<Map<K, V>, T> function) {
|
||||||
public <T> @NotNull T modifyValue(Function<Map<K, V>, T> function) {
|
// Map<K, V> m = get();
|
||||||
Map<K, V> m = get();
|
// T result = function.apply(m);
|
||||||
T result = function.apply(m);
|
// set(m);
|
||||||
set(m);
|
// return result;
|
||||||
return result;
|
// }
|
||||||
}
|
//
|
||||||
|
// public @NotNull Map<K, V> modifyMap(Consumer<Map<K, V>> consumer) {
|
||||||
public @NotNull Map<K, V> modifyMap(Consumer<Map<K, V>> consumer) {
|
// Map<K, V> m = get();
|
||||||
Map<K, V> m = get();
|
// consumer.accept(m);
|
||||||
consumer.accept(m);
|
// set(m);
|
||||||
set(m);
|
// return m;
|
||||||
return m;
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public int size() {
|
||||||
public int size() {
|
// return get().size();
|
||||||
return get().size();
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public boolean isEmpty() {
|
||||||
public boolean isEmpty() {
|
// return get().isEmpty();
|
||||||
return get().isEmpty();
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public boolean containsKey(Object key) {
|
||||||
public boolean containsKey(Object key) {
|
// return get().containsKey(key);
|
||||||
return get().containsKey(key);
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public boolean containsValue(Object value) {
|
||||||
public boolean containsValue(Object value) {
|
// return get().containsValue(value);
|
||||||
return get().containsValue(value);
|
// }
|
||||||
}
|
//
|
||||||
|
// @Nullable
|
||||||
@Nullable
|
// @Override
|
||||||
@Override
|
// public V put(K key, V value) {
|
||||||
public V put(K key, V value) {
|
// return modifyValue(m -> m.put(key, value));
|
||||||
return modifyValue(m -> m.put(key, value));
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public V remove(Object key) {
|
||||||
public V remove(Object key) {
|
// return modifyValue(m -> m.remove(key));
|
||||||
return modifyValue(m -> m.remove(key));
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public void putAll(@NotNull Map<? extends K, ? extends V> m) {
|
||||||
public void putAll(@NotNull Map<? extends K, ? extends V> m) {
|
// modifyMap(map -> map.putAll(m));
|
||||||
modifyMap(map -> map.putAll(m));
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public void clear() {
|
||||||
public void clear() {
|
// modifyMap(Map::clear);
|
||||||
modifyMap(Map::clear);
|
// }
|
||||||
}
|
//
|
||||||
|
// @NotNull
|
||||||
@NotNull
|
// @Override
|
||||||
@Override
|
// public Set<K> keySet() {
|
||||||
public Set<K> keySet() {
|
// return get().keySet();
|
||||||
return get().keySet();
|
// }
|
||||||
}
|
//
|
||||||
|
// @NotNull
|
||||||
@NotNull
|
// @Override
|
||||||
@Override
|
// public Collection<V> values() {
|
||||||
public Collection<V> values() {
|
// return get().values();
|
||||||
return get().values();
|
// }
|
||||||
}
|
//
|
||||||
|
// @NotNull
|
||||||
@NotNull
|
// @Override
|
||||||
@Override
|
// @Unmodifiable
|
||||||
@Unmodifiable
|
// public Set<Entry<K, V>> entrySet() {
|
||||||
public Set<Entry<K, V>> entrySet() {
|
// return get().entrySet();
|
||||||
return get().entrySet();
|
// }
|
||||||
}
|
//
|
||||||
|
//}
|
||||||
}
|
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package cc.carm.lib.configuration.value.meta;
|
||||||
|
|
||||||
|
public interface ValueMetaList {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value path in configuration.
|
||||||
|
* Also see {@link cc.carm.lib.configuration.option.ConfigurationOptions#PATH_SEPARATOR}
|
||||||
|
*/
|
||||||
|
ValueMetaType<String> PATH = ValueMetaType.of();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package cc.carm.lib.configuration.value.meta;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ValueMetaType<T> {
|
||||||
|
|
||||||
|
public static <T> ValueMetaType<T> of() {
|
||||||
|
return of(() -> null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ValueMetaType<T> of(T defaults) {
|
||||||
|
return of(() -> defaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ValueMetaType<T> of(@NotNull Supplier<@Nullable T> defaults) {
|
||||||
|
return of(v -> defaults.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ValueMetaType<T> of(@NotNull Function<ValueManifest<?>, @Nullable T> defaults) {
|
||||||
|
return new ValueMetaType<>(defaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Function<ValueManifest<?>, @Nullable T> defaultFunction;
|
||||||
|
|
||||||
|
public ValueMetaType(@NotNull Function<ValueManifest<?>, @Nullable T> defaults) {
|
||||||
|
this.defaultFunction = defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefault(ValueManifest<?> manifest, @NotNull T value) {
|
||||||
|
return value.equals(defaults(manifest));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDefaults(ValueManifest<?> manifest) {
|
||||||
|
return defaults(manifest) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getDefault(ValueManifest<?> manifest, @Nullable T suppliedValue) {
|
||||||
|
T defaults = defaults(manifest);
|
||||||
|
return defaults == null ? suppliedValue : defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable T defaults(ValueManifest<?> manifest) {
|
||||||
|
return defaultFunction.apply(manifest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaults(Function<ValueManifest<?>, T> defaultFunction) {
|
||||||
|
this.defaultFunction = defaultFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaults(T value) {
|
||||||
|
setDefaults((v) -> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,229 +1,229 @@
|
|||||||
package cc.carm.lib.configuration.value.standard;
|
//package cc.carm.lib.configuration.value.standard;
|
||||||
|
//
|
||||||
import cc.carm.lib.configuration.core.builder.list.ConfigListBuilder;
|
//import cc.carm.lib.configuration.builder.list.ConfigListBuilder;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
//import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
//import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
//import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
||||||
import org.jetbrains.annotations.NotNull;
|
//import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
//import org.jetbrains.annotations.Nullable;
|
||||||
|
//
|
||||||
import java.util.*;
|
//import java.util.*;
|
||||||
import java.util.function.Consumer;
|
//import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
//import java.util.function.Function;
|
||||||
|
//
|
||||||
public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements List<V> {
|
//public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements List<V> {
|
||||||
|
//
|
||||||
public static <V> @NotNull ConfigListBuilder<V> builderOf(@NotNull Class<V> valueClass) {
|
// public static <V> @NotNull ConfigListBuilder<V> builderOf(@NotNull Class<V> valueClass) {
|
||||||
return builder().asList(valueClass);
|
// return builder().asList(valueClass);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public static <V> @NotNull ConfiguredList<V> of(@NotNull Class<V> valueClass, @NotNull Collection<V> defaults) {
|
// public static <V> @NotNull ConfiguredList<V> of(@NotNull Class<V> valueClass, @NotNull Collection<V> defaults) {
|
||||||
return builderOf(valueClass).fromObject().defaults(defaults).build();
|
// return builderOf(valueClass).fromObject().defaults(defaults).build();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@SafeVarargs
|
// @SafeVarargs
|
||||||
public static <V> @NotNull ConfiguredList<V> of(@NotNull Class<V> valueClass, @NotNull V... defaults) {
|
// public static <V> @NotNull ConfiguredList<V> of(@NotNull Class<V> valueClass, @NotNull V... defaults) {
|
||||||
return builderOf(valueClass).fromObject().defaults(defaults).build();
|
// return builderOf(valueClass).fromObject().defaults(defaults).build();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@SafeVarargs
|
// @SafeVarargs
|
||||||
@SuppressWarnings("unchecked")
|
// @SuppressWarnings("unchecked")
|
||||||
public static <V> @NotNull ConfiguredList<V> of(@NotNull V defaultValue, @NotNull V... moreDefaults) {
|
// public static <V> @NotNull ConfiguredList<V> of(@NotNull V defaultValue, @NotNull V... moreDefaults) {
|
||||||
Collection<V> values = new ArrayList<>();
|
// Collection<V> values = new ArrayList<>();
|
||||||
values.add(defaultValue);
|
// values.add(defaultValue);
|
||||||
values.addAll(Arrays.asList(moreDefaults));
|
// values.addAll(Arrays.asList(moreDefaults));
|
||||||
return of((Class<V>) defaultValue.getClass(), values);
|
// return of((Class<V>) defaultValue.getClass(), values);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected final @NotNull Class<V> valueClass;
|
// protected final @NotNull Class<V> valueClass;
|
||||||
|
//
|
||||||
protected final @NotNull ConfigDataFunction<Object, V> parser;
|
// protected final @NotNull ConfigDataFunction<Object, V> parser;
|
||||||
protected final @NotNull ConfigDataFunction<V, Object> serializer;
|
// protected final @NotNull ConfigDataFunction<V, Object> serializer;
|
||||||
|
//
|
||||||
public ConfiguredList(@NotNull ValueManifest<List<V>> manifest, @NotNull Class<V> valueClass,
|
// public ConfiguredList(@NotNull ValueManifest<List<V>> manifest, @NotNull Class<V> valueClass,
|
||||||
@NotNull ConfigDataFunction<Object, V> parser,
|
// @NotNull ConfigDataFunction<Object, V> parser,
|
||||||
@NotNull ConfigDataFunction<V, Object> serializer) {
|
// @NotNull ConfigDataFunction<V, Object> serializer) {
|
||||||
super(manifest);
|
// super(manifest);
|
||||||
this.valueClass = valueClass;
|
// this.valueClass = valueClass;
|
||||||
this.parser = parser;
|
// this.parser = parser;
|
||||||
this.serializer = serializer;
|
// this.serializer = serializer;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public @NotNull List<V> get() {
|
// public @NotNull List<V> get() {
|
||||||
if (!isExpired()) return getCachedOrDefault(new ArrayList<>());
|
// if (!isExpired()) return getCachedOrDefault(new ArrayList<>());
|
||||||
// Data that is outdated and needs to be parsed again.
|
// // Data that is outdated and needs to be parsed again.
|
||||||
List<V> list = new ArrayList<>();
|
// List<V> list = new ArrayList<>();
|
||||||
List<?> data = getConfiguration().contains(getConfigPath()) ?
|
// List<?> data = getConfiguration().contains(getConfigPath()) ?
|
||||||
getConfiguration().getList(getConfigPath()) : null;
|
// getConfiguration().getList(getConfigPath()) : null;
|
||||||
if (data == null) return getDefaultFirst(list);
|
// if (data == null) return getDefaultFirst(list);
|
||||||
for (Object dataVal : data) {
|
// for (Object dataVal : data) {
|
||||||
if (dataVal == null) continue;
|
// if (dataVal == null) continue;
|
||||||
try {
|
// try {
|
||||||
list.add(parser.parse(dataVal));
|
// list.add(parser.parse(dataVal));
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return updateCache(list);
|
// return updateCache(list);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public V get(int index) {
|
// public V get(int index) {
|
||||||
return get().get(index);
|
// return get().get(index);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public @NotNull List<V> copy() {
|
// public @NotNull List<V> copy() {
|
||||||
return new ArrayList<>(get());
|
// return new ArrayList<>(get());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public <T> @NotNull T handle(Function<List<V>, T> function) {
|
// public <T> @NotNull T handle(Function<List<V>, T> function) {
|
||||||
List<V> list = get();
|
// List<V> list = get();
|
||||||
T result = function.apply(list);
|
// T result = function.apply(list);
|
||||||
set(list);
|
// set(list);
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public @NotNull List<V> modify(Consumer<List<V>> consumer) {
|
// public @NotNull List<V> modify(Consumer<List<V>> consumer) {
|
||||||
List<V> list = get();
|
// List<V> list = get();
|
||||||
consumer.accept(list);
|
// consumer.accept(list);
|
||||||
set(list);
|
// set(list);
|
||||||
return list;
|
// return list;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void set(@Nullable List<V> value) {
|
// public void set(@Nullable List<V> value) {
|
||||||
updateCache(value);
|
// updateCache(value);
|
||||||
if (value == null) setValue(null);
|
// if (value == null) setValue(null);
|
||||||
else {
|
// else {
|
||||||
List<Object> data = new ArrayList<>();
|
// List<Object> data = new ArrayList<>();
|
||||||
for (V val : value) {
|
// for (V val : value) {
|
||||||
if (val == null) continue;
|
// if (val == null) continue;
|
||||||
try {
|
// try {
|
||||||
data.add(serializer.parse(val));
|
// data.add(serializer.parse(val));
|
||||||
} catch (Exception ex) {
|
// } catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
// ex.printStackTrace();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
setValue(data);
|
// setValue(data);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public V set(int index, V element) {
|
// public V set(int index, V element) {
|
||||||
return handle(list -> list.set(index, element));
|
// return handle(list -> list.set(index, element));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public int size() {
|
// public int size() {
|
||||||
return get().size();
|
// return get().size();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean isEmpty() {
|
// public boolean isEmpty() {
|
||||||
return get().isEmpty();
|
// return get().isEmpty();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean contains(Object o) {
|
// public boolean contains(Object o) {
|
||||||
return get().contains(o);
|
// return get().contains(o);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public Iterator<V> iterator() {
|
// public Iterator<V> iterator() {
|
||||||
return get().iterator();
|
// return get().iterator();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public Object @NotNull [] toArray() {
|
// public Object @NotNull [] toArray() {
|
||||||
return get().toArray();
|
// return get().toArray();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public <T> T @NotNull [] toArray(@NotNull T[] a) {
|
// public <T> T @NotNull [] toArray(@NotNull T[] a) {
|
||||||
return get().toArray(a);
|
// return get().toArray(a);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean containsAll(@NotNull Collection<?> c) {
|
// public boolean containsAll(@NotNull Collection<?> c) {
|
||||||
return new HashSet<>(get()).containsAll(c);
|
// return new HashSet<>(get()).containsAll(c);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean add(V v) {
|
// public boolean add(V v) {
|
||||||
handle(list -> list.add(v));
|
// handle(list -> list.add(v));
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void add(int index, V element) {
|
// public void add(int index, V element) {
|
||||||
modify(list -> list.add(index, element));
|
// modify(list -> list.add(index, element));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean addAll(@NotNull Collection<? extends V> c) {
|
// public boolean addAll(@NotNull Collection<? extends V> c) {
|
||||||
return handle(list -> list.addAll(c));
|
// return handle(list -> list.addAll(c));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean addAll(int index, @NotNull Collection<? extends V> c) {
|
// public boolean addAll(int index, @NotNull Collection<? extends V> c) {
|
||||||
return handle(list -> list.addAll(index, c));
|
// return handle(list -> list.addAll(index, c));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean remove(Object o) {
|
// public boolean remove(Object o) {
|
||||||
return handle(list -> list.remove(o));
|
// return handle(list -> list.remove(o));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public V remove(int index) {
|
// public V remove(int index) {
|
||||||
return handle(list -> list.remove(index));
|
// return handle(list -> list.remove(index));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean removeAll(@NotNull Collection<?> c) {
|
// public boolean removeAll(@NotNull Collection<?> c) {
|
||||||
return handle(list -> list.removeAll(c));
|
// return handle(list -> list.removeAll(c));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean retainAll(@NotNull Collection<?> c) {
|
// public boolean retainAll(@NotNull Collection<?> c) {
|
||||||
return handle(list -> list.retainAll(c));
|
// return handle(list -> list.retainAll(c));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void clear() {
|
// public void clear() {
|
||||||
modify(List::clear);
|
// modify(List::clear);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public int indexOf(Object o) {
|
// public int indexOf(Object o) {
|
||||||
return get().indexOf(o);
|
// return get().indexOf(o);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public int lastIndexOf(Object o) {
|
// public int lastIndexOf(Object o) {
|
||||||
return get().lastIndexOf(o);
|
// return get().lastIndexOf(o);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public ListIterator<V> listIterator() {
|
// public ListIterator<V> listIterator() {
|
||||||
return get().listIterator();
|
// return get().listIterator();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public ListIterator<V> listIterator(int index) {
|
// public ListIterator<V> listIterator(int index) {
|
||||||
return get().listIterator(index);
|
// return get().listIterator(index);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public List<V> subList(int fromIndex, int toIndex) {
|
// public List<V> subList(int fromIndex, int toIndex) {
|
||||||
return get().subList(fromIndex, toIndex);
|
// return get().subList(fromIndex, toIndex);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
@ -1,28 +1,27 @@
|
|||||||
package cc.carm.lib.configuration.value.standard;
|
//package cc.carm.lib.configuration.value.standard;
|
||||||
|
//
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
//import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
//import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
//import cc.carm.lib.configuration.value.impl.ConfigValueMap;
|
||||||
import cc.carm.lib.configuration.value.impl.ConfigValueMap;
|
//import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.NotNull;
|
//
|
||||||
|
//import java.util.Map;
|
||||||
import java.util.Map;
|
//import java.util.function.Supplier;
|
||||||
import java.util.function.Supplier;
|
//
|
||||||
|
//public class ConfiguredMap<K, V> extends ConfigValueMap<K, V, Object> {
|
||||||
public class ConfiguredMap<K, V> extends ConfigValueMap<K, V, Object> {
|
//
|
||||||
|
// public ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
||||||
public ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
// @NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
||||||
@NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
// @NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
||||||
@NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
// @NotNull Class<V> valueClass, @NotNull ConfigDataFunction<Object, V> valueParser,
|
||||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<Object, V> valueParser,
|
// @NotNull ConfigDataFunction<K, String> keySerializer,
|
||||||
@NotNull ConfigDataFunction<K, String> keySerializer,
|
// @NotNull ConfigDataFunction<V, Object> valueSerializer) {
|
||||||
@NotNull ConfigDataFunction<V, Object> valueSerializer) {
|
// super(manifest, Object.class, mapObjSupplier, keyClass, keyParser, valueClass, valueParser, keySerializer, valueSerializer);
|
||||||
super(manifest, Object.class, mapObjSupplier, keyClass, keyParser, valueClass, valueParser, keySerializer, valueSerializer);
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public Object getSource(ConfigurationWrapper<?> section, String dataKey) {
|
||||||
public Object getSource(ConfigurationWrapper<?> section, String dataKey) {
|
// return section.get(dataKey);
|
||||||
return section.get(dataKey);
|
// }
|
||||||
}
|
//
|
||||||
|
//}
|
||||||
}
|
|
||||||
|
@ -1,97 +1,96 @@
|
|||||||
package cc.carm.lib.configuration.value.standard;
|
//package cc.carm.lib.configuration.value.standard;
|
||||||
|
//
|
||||||
import cc.carm.lib.configuration.core.builder.value.SectionValueBuilder;
|
//import cc.carm.lib.configuration.builder.value.SectionValueBuilder;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
//import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigValueParser;
|
//import cc.carm.lib.configuration.function.ConfigValueParser;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
//import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
//import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
||||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
//import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.NotNull;
|
//import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.Nullable;
|
//
|
||||||
|
//import java.util.Map;
|
||||||
import java.util.Map;
|
//
|
||||||
|
//public class ConfiguredSection<V> extends CachedConfigValue<V> {
|
||||||
public class ConfiguredSection<V> extends CachedConfigValue<V> {
|
//
|
||||||
|
// public static <V> @NotNull SectionValueBuilder<V> builderOf(@NotNull Class<V> valueClass) {
|
||||||
public static <V> @NotNull SectionValueBuilder<V> builderOf(@NotNull Class<V> valueClass) {
|
// return builder().asValue(valueClass).fromSection();
|
||||||
return builder().asValue(valueClass).fromSection();
|
// }
|
||||||
}
|
//
|
||||||
|
// protected final @NotNull Class<V> valueClass;
|
||||||
protected final @NotNull Class<V> valueClass;
|
//
|
||||||
|
// protected final @NotNull ConfigValueParser<ConfigurationWrapper<?>, V> parser;
|
||||||
protected final @NotNull ConfigValueParser<ConfigurationWrapper<?>, V> parser;
|
// protected final @NotNull ConfigDataFunction<V, ? extends Map<String, Object>> serializer;
|
||||||
protected final @NotNull ConfigDataFunction<V, ? extends Map<String, Object>> serializer;
|
//
|
||||||
|
// public ConfiguredSection(@NotNull ValueManifest<V> manifest, @NotNull Class<V> valueClass,
|
||||||
public ConfiguredSection(@NotNull ValueManifest<V> manifest, @NotNull Class<V> valueClass,
|
// @NotNull ConfigValueParser<ConfigurationWrapper<?>, V> parser,
|
||||||
@NotNull ConfigValueParser<ConfigurationWrapper<?>, V> parser,
|
// @NotNull ConfigDataFunction<V, ? extends Map<String, Object>> serializer) {
|
||||||
@NotNull ConfigDataFunction<V, ? extends Map<String, Object>> serializer) {
|
// super(manifest);
|
||||||
super(manifest);
|
// this.valueClass = valueClass;
|
||||||
this.valueClass = valueClass;
|
// this.parser = parser;
|
||||||
this.parser = parser;
|
// this.serializer = serializer;
|
||||||
this.serializer = serializer;
|
// }
|
||||||
}
|
//
|
||||||
|
// /**
|
||||||
/**
|
// * @return Value's type class
|
||||||
* @return Value's type class
|
// */
|
||||||
*/
|
// public @NotNull Class<V> getValueClass() {
|
||||||
public @NotNull Class<V> getValueClass() {
|
// return valueClass;
|
||||||
return valueClass;
|
// }
|
||||||
}
|
//
|
||||||
|
// /**
|
||||||
/**
|
// * @return Value's parser, cast value from section.
|
||||||
* @return Value's parser, cast value from section.
|
// */
|
||||||
*/
|
// public @NotNull ConfigValueParser<ConfigurationWrapper<?>, V> getParser() {
|
||||||
public @NotNull ConfigValueParser<ConfigurationWrapper<?>, V> getParser() {
|
// return parser;
|
||||||
return parser;
|
// }
|
||||||
}
|
//
|
||||||
|
// /**
|
||||||
/**
|
// * @return Value's serializer, serialize value to section.
|
||||||
* @return Value's serializer, serialize value to section.
|
// */
|
||||||
*/
|
// public @NotNull ConfigDataFunction<V, ? extends Map<String, Object>> getSerializer() {
|
||||||
public @NotNull ConfigDataFunction<V, ? extends Map<String, Object>> getSerializer() {
|
// return serializer;
|
||||||
return serializer;
|
// }
|
||||||
}
|
//
|
||||||
|
// /**
|
||||||
/**
|
// * @return Get the value that parsed from the configuration section.
|
||||||
* @return Get the value that parsed from the configuration section.
|
// */
|
||||||
*/
|
// @Override
|
||||||
@Override
|
// public @Nullable V get() {
|
||||||
public @Nullable V get() {
|
// if (!isExpired()) return getCachedOrDefault();
|
||||||
if (!isExpired()) return getCachedOrDefault();
|
// // Data that is outdated and needs to be parsed again.
|
||||||
// Data that is outdated and needs to be parsed again.
|
//
|
||||||
|
// ConfigurationWrapper<?> section = getConfiguration().getConfigurationSection(getConfigPath());
|
||||||
ConfigurationWrapper<?> section = getConfiguration().getConfigurationSection(getConfigPath());
|
// if (section == null) return getDefaultValue();
|
||||||
if (section == null) return getDefaultValue();
|
//
|
||||||
|
// try {
|
||||||
try {
|
// // If there are no errors, update the cache and return.
|
||||||
// If there are no errors, update the cache and return.
|
// return updateCache(this.parser.parse(section, this.defaultValue));
|
||||||
return updateCache(this.parser.parse(section, this.defaultValue));
|
// } catch (Exception e) {
|
||||||
} catch (Exception e) {
|
// // There was a parsing error, prompted and returned the default value.
|
||||||
// There was a parsing error, prompted and returned the default value.
|
// e.printStackTrace();
|
||||||
e.printStackTrace();
|
// return getDefaultValue();
|
||||||
return getDefaultValue();
|
// }
|
||||||
}
|
//
|
||||||
|
// }
|
||||||
}
|
//
|
||||||
|
// /**
|
||||||
/**
|
// * Use the specified value to update the configuration section.
|
||||||
* Use the specified value to update the configuration section.
|
// * Will use {@link #getSerializer()} to serialize the value to section.
|
||||||
* Will use {@link #getSerializer()} to serialize the value to section.
|
// *
|
||||||
*
|
// * @param value The value that needs to be set in the configuration.
|
||||||
* @param value The value that needs to be set in the configuration.
|
// */
|
||||||
*/
|
// @Override
|
||||||
@Override
|
// public void set(V value) {
|
||||||
public void set(V value) {
|
// updateCache(value);
|
||||||
updateCache(value);
|
// if (value == null) setValue(null);
|
||||||
if (value == null) setValue(null);
|
// else {
|
||||||
else {
|
// try {
|
||||||
try {
|
// setValue(serializer.parse(value));
|
||||||
setValue(serializer.parse(value));
|
// } catch (Exception e) {
|
||||||
} catch (Exception e) {
|
// e.printStackTrace();
|
||||||
e.printStackTrace();
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
//
|
||||||
|
//}
|
||||||
}
|
|
||||||
|
@ -1,32 +1,31 @@
|
|||||||
package cc.carm.lib.configuration.value.standard;
|
//package cc.carm.lib.configuration.value.standard;
|
||||||
|
//
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
//import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
//import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
//import cc.carm.lib.configuration.value.impl.ConfigValueMap;
|
||||||
import cc.carm.lib.configuration.value.impl.ConfigValueMap;
|
//import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.NotNull;
|
//
|
||||||
|
//import java.util.Map;
|
||||||
import java.util.Map;
|
//import java.util.function.Supplier;
|
||||||
import java.util.function.Supplier;
|
//
|
||||||
|
//public class ConfiguredSectionMap<K, V> extends ConfigValueMap<K, V, ConfigurationWrapper<?>> {
|
||||||
public class ConfiguredSectionMap<K, V> extends ConfigValueMap<K, V, ConfigurationWrapper<?>> {
|
//
|
||||||
|
// public ConfiguredSectionMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
||||||
public ConfiguredSectionMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
// @NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
||||||
@NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
// @NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
||||||
@NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
// @NotNull Class<V> valueClass, @NotNull ConfigDataFunction<ConfigurationWrapper<?>, V> valueParser,
|
||||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<ConfigurationWrapper<?>, V> valueParser,
|
// @NotNull ConfigDataFunction<K, String> keySerializer,
|
||||||
@NotNull ConfigDataFunction<K, String> keySerializer,
|
// @NotNull ConfigDataFunction<V, ? extends Map<String, Object>> valueSerializer) {
|
||||||
@NotNull ConfigDataFunction<V, ? extends Map<String, Object>> valueSerializer) {
|
// super(
|
||||||
super(
|
// manifest, ConfigurationWrapper.class, mapObjSupplier,
|
||||||
manifest, ConfigurationWrapper.class, mapObjSupplier,
|
// keyClass, keyParser, valueClass, valueParser,
|
||||||
keyClass, keyParser, valueClass, valueParser,
|
// keySerializer, valueSerializer.andThen(s -> (Object) s)
|
||||||
keySerializer, valueSerializer.andThen(s -> (Object) s)
|
// );
|
||||||
);
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public ConfigurationWrapper<?> getSource(ConfigurationWrapper<?> section, String dataKey) {
|
||||||
public ConfigurationWrapper<?> getSource(ConfigurationWrapper<?> section, String dataKey) {
|
// return section.getConfigurationSection(dataKey);
|
||||||
return section.getConfigurationSection(dataKey);
|
// }
|
||||||
}
|
//
|
||||||
|
//}
|
||||||
}
|
|
||||||
|
@ -1,31 +1,29 @@
|
|||||||
package cc.carm.lib.configuration.value.standard;
|
package cc.carm.lib.configuration.value.standard;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.value.ConfigValueBuilder;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigValueParser;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigValueParser;
|
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class ConfiguredValue<V> extends CachedConfigValue<V> {
|
public class ConfiguredValue<V> extends CachedConfigValue<V> {
|
||||||
|
|
||||||
public static <V> ConfigValueBuilder<V> builderOf(Class<V> valueClass) {
|
// public static <V> ConfigValueBuilder<V> builderOf(Class<V> valueClass) {
|
||||||
return builder().asValue(valueClass);
|
// return builder().asValue(valueClass);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@SuppressWarnings("unchecked")
|
// @SuppressWarnings("unchecked")
|
||||||
public static <V> ConfiguredValue<V> of(@NotNull V defaultValue) {
|
// public static <V> ConfiguredValue<V> of(@NotNull V defaultValue) {
|
||||||
return of((Class<V>) defaultValue.getClass(), defaultValue);
|
// return of((Class<V>) defaultValue.getClass(), defaultValue);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public static <V> ConfiguredValue<V> of(Class<V> valueClass) {
|
// public static <V> ConfiguredValue<V> of(Class<V> valueClass) {
|
||||||
return of(valueClass, null);
|
// return of(valueClass, null);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public static <V> ConfiguredValue<V> of(Class<V> valueClass, @Nullable V defaultValue) {
|
// public static <V> ConfiguredValue<V> of(Class<V> valueClass, @Nullable V defaultValue) {
|
||||||
return builderOf(valueClass).fromObject().defaults(defaultValue).build();
|
// return builderOf(valueClass).fromObject().defaults(defaultValue).build();
|
||||||
}
|
// }
|
||||||
|
|
||||||
protected final @NotNull Class<V> valueClass;
|
protected final @NotNull Class<V> valueClass;
|
||||||
|
|
||||||
@ -68,14 +66,15 @@ public class ConfiguredValue<V> extends CachedConfigValue<V> {
|
|||||||
// Data that is outdated and needs to be parsed again.
|
// Data that is outdated and needs to be parsed again.
|
||||||
|
|
||||||
Object value = getValue();
|
Object value = getValue();
|
||||||
if (value == null) return getDefaultValue(); // 获取的值不存在,直接使用默认值。
|
if (value == null) return defaults();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// If there are no errors, update the cache and return.
|
// If there are no errors, update the cache and return.
|
||||||
return updateCache(this.parser.parse(value, this.defaultValue));
|
return updateCache(this.parser.parse(provider(), value, defaults()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// There was a parsing error, prompted and returned the default value.
|
// There was a parsing error, prompted and returned the default value.
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return getDefaultValue();
|
return defaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
123
core/src/main/old/ValueManifestv.java
Normal file
123
core/src/main/old/ValueManifestv.java
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
package cc.carm.lib.configuration.value;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigValue Manifests.
|
||||||
|
* The basic information that describes a configuration value.
|
||||||
|
*
|
||||||
|
* @param <T> Value type
|
||||||
|
* @author CarmJos
|
||||||
|
*/
|
||||||
|
public class ValueManifest<T> {
|
||||||
|
|
||||||
|
public static <V> ValueManifest<V> of(@Nullable ConfigurationProvider<?> provider, @Nullable String configPath,
|
||||||
|
@Nullable List<String> headerComments, @Nullable String inlineComments) {
|
||||||
|
return new ValueManifest<>(provider, configPath, headerComments, inlineComments, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <V> ValueManifest<V> of(@Nullable ConfigurationProvider<?> provider, @Nullable String configPath,
|
||||||
|
@Nullable List<String> headerComments, @Nullable String inlineComments,
|
||||||
|
@Nullable V defaultValue) {
|
||||||
|
return new ValueManifest<>(provider, configPath, headerComments, inlineComments, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected @Nullable ConfigurationProvider<?> provider;
|
||||||
|
protected @Nullable String configPath;
|
||||||
|
|
||||||
|
protected @Nullable List<String> headerComments;
|
||||||
|
protected @Nullable String inlineComment;
|
||||||
|
|
||||||
|
protected @Nullable T defaultValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param provider Provider of config files {@link ConfigurationProvider}
|
||||||
|
* @param configPath Config path of this value
|
||||||
|
* @param headerComments Header comment contents
|
||||||
|
* @param inlineComment Inline comment content
|
||||||
|
* @param defaultValue The default value
|
||||||
|
*/
|
||||||
|
public ValueManifest(@Nullable ConfigurationProvider<?> provider, @Nullable String configPath,
|
||||||
|
@Nullable List<String> headerComments, @Nullable String inlineComment,
|
||||||
|
@Nullable T defaultValue) {
|
||||||
|
this.provider = provider;
|
||||||
|
this.configPath = configPath;
|
||||||
|
this.headerComments = headerComments;
|
||||||
|
this.inlineComment = inlineComment;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initialize method for {@link ConfigInitializer}, which is used to initialize the value.
|
||||||
|
*
|
||||||
|
* @param provider Provider of config files {@link ConfigurationProvider}
|
||||||
|
* @param configPath Config path of this value
|
||||||
|
* @param headerComments Header comment contents
|
||||||
|
* @param inlineComment Inline comment content
|
||||||
|
*/
|
||||||
|
protected void initialize(@NotNull ConfigurationProvider<?> provider, @NotNull String configPath,
|
||||||
|
@Nullable List<String> headerComments, @Nullable String inlineComment) {
|
||||||
|
if (this.provider == null) this.provider = provider;
|
||||||
|
if (this.configPath == null) this.configPath = configPath;
|
||||||
|
if (this.headerComments == null) this.headerComments = headerComments;
|
||||||
|
if (this.inlineComment == null) this.inlineComment = inlineComment;
|
||||||
|
|
||||||
|
if (getHeaderComments() != null) {
|
||||||
|
this.provider.setHeaderComment(getConfigPath(), getHeaderComments());
|
||||||
|
}
|
||||||
|
if (getInlineComment() != null) {
|
||||||
|
this.provider.setInlineComment(getConfigPath(), getInlineComment());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable T getDefaultValue() {
|
||||||
|
return this.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultValue(@Nullable T defaultValue) {
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ConfigurationProvider<?> getProvider() {
|
||||||
|
return Optional.ofNullable(this.provider)
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Value(" + configPath + ") does not have a provider."));
|
||||||
|
}
|
||||||
|
|
||||||
|
public final @NotNull ConfigurationWrapper<?> getConfiguration() {
|
||||||
|
try {
|
||||||
|
return getProvider().getConfiguration();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new IllegalStateException("Value(" + configPath + ") has not been initialized", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull String getConfigPath() {
|
||||||
|
return Optional.ofNullable(this.configPath)
|
||||||
|
.orElseThrow(() -> new IllegalStateException("No section path provided."));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getValue() {
|
||||||
|
String path = getConfigPath(); // 当未指定路径时,优先抛出异常
|
||||||
|
return getConfiguration().get(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setValue(@Nullable Object value) {
|
||||||
|
getConfiguration().set(getConfigPath(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getInlineComment() {
|
||||||
|
return inlineComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unmodifiable
|
||||||
|
public @Nullable List<String> getHeaderComments() {
|
||||||
|
return headerComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.core.builder;
|
package cc.carm.lib.configuration.builder;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
import cc.carm.lib.configuration.value.ConfigValue;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
@ -1,6 +1,4 @@
|
|||||||
package cc.carm.lib.configuration.core.builder;
|
package cc.carm.lib.configuration.builder;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
|
||||||
|
|
||||||
public abstract class CommonConfigBuilder<T, B extends CommonConfigBuilder<T, B>>
|
public abstract class CommonConfigBuilder<T, B extends CommonConfigBuilder<T, B>>
|
||||||
extends AbstractConfigBuilder<T, B, ConfigurationProvider<?>> {
|
extends AbstractConfigBuilder<T, B, ConfigurationProvider<?>> {
|
@ -1,9 +1,9 @@
|
|||||||
package cc.carm.lib.configuration.core.builder;
|
package cc.carm.lib.configuration.builder;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.list.ConfigListBuilder;
|
import cc.carm.lib.configuration.builder.map.ConfigMapBuilder;
|
||||||
import cc.carm.lib.configuration.core.builder.map.ConfigMapBuilder;
|
import cc.carm.lib.configuration.builder.map.ConfigMapCreator;
|
||||||
import cc.carm.lib.configuration.core.builder.map.ConfigMapCreator;
|
import cc.carm.lib.configuration.builder.list.ConfigListBuilder;
|
||||||
import cc.carm.lib.configuration.core.builder.value.ConfigValueBuilder;
|
import cc.carm.lib.configuration.builder.value.ConfigValueBuilder;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
@ -1,6 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.list;
|
package cc.carm.lib.configuration.builder.list;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -1,7 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.list;
|
package cc.carm.lib.configuration.builder.list;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.CommonConfigBuilder;
|
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.map;
|
package cc.carm.lib.configuration.builder.map;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -1,4 +1,4 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.map;
|
package cc.carm.lib.configuration.builder.map;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
@ -1,8 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.map;
|
package cc.carm.lib.configuration.builder.map;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.CommonConfigBuilder;
|
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredSectionMap;
|
import cc.carm.lib.configuration.value.standard.ConfiguredSectionMap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
@ -1,7 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.map;
|
package cc.carm.lib.configuration.builder.map;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.CommonConfigBuilder;
|
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
@ -1,8 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.value;
|
package cc.carm.lib.configuration.builder.value;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigValueParser;
|
import cc.carm.lib.configuration.function.ConfigValueParser;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -1,9 +1,8 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.value;
|
package cc.carm.lib.configuration.builder.value;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.CommonConfigBuilder;
|
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigValueParser;
|
import cc.carm.lib.configuration.function.ConfigValueParser;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredSection;
|
import cc.carm.lib.configuration.value.standard.ConfiguredSection;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
package cc.carm.lib.configuration.core.builder.value;
|
package cc.carm.lib.configuration.builder.value;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.builder.CommonConfigBuilder;
|
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
import cc.carm.lib.configuration.function.ConfigDataFunction;
|
||||||
import cc.carm.lib.configuration.core.function.ConfigValueParser;
|
import cc.carm.lib.configuration.function.ConfigValueParser;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
@ -2,6 +2,9 @@ import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
|||||||
import cc.carm.lib.configuration.adapter.strandard.EnumAdapter;
|
import cc.carm.lib.configuration.adapter.strandard.EnumAdapter;
|
||||||
import cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapters;
|
import cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapters;
|
||||||
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
import cc.carm.lib.configuration.source.ConfigurationProvider;
|
||||||
|
import cc.carm.lib.configuration.loader.ConfigurationLoader;
|
||||||
|
import cc.carm.lib.easyoptions.OptionHolder;
|
||||||
|
import cc.carm.test.config.TestSource;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -12,7 +15,7 @@ public class AdaptTest {
|
|||||||
@Test
|
@Test
|
||||||
public void test() throws Exception {
|
public void test() throws Exception {
|
||||||
|
|
||||||
ValueAdapterRegistry<ConfigurationProvider> registry = new ValueAdapterRegistry<>();
|
ValueAdapterRegistry registry = new ValueAdapterRegistry();
|
||||||
registry.register(Long.class, PrimitiveAdapters.ofLong());
|
registry.register(Long.class, PrimitiveAdapters.ofLong());
|
||||||
registry.register(long.class, PrimitiveAdapters.ofLong());
|
registry.register(long.class, PrimitiveAdapters.ofLong());
|
||||||
registry.register(Integer.class, PrimitiveAdapters.ofInteger());
|
registry.register(Integer.class, PrimitiveAdapters.ofInteger());
|
||||||
@ -30,7 +33,7 @@ public class AdaptTest {
|
|||||||
registry.register(Boolean.class, PrimitiveAdapters.ofBoolean());
|
registry.register(Boolean.class, PrimitiveAdapters.ofBoolean());
|
||||||
registry.register(boolean.class, PrimitiveAdapters.ofBoolean());
|
registry.register(boolean.class, PrimitiveAdapters.ofBoolean());
|
||||||
registry.register(String.class, PrimitiveAdapters.ofString());
|
registry.register(String.class, PrimitiveAdapters.ofString());
|
||||||
registry.register(new EnumAdapter<>());
|
registry.register(new EnumAdapter());
|
||||||
|
|
||||||
registry.register(Long.class, Duration.class, Duration::ofSeconds, Duration::getSeconds);
|
registry.register(Long.class, Duration.class, Duration::ofSeconds, Duration::getSeconds);
|
||||||
registry.register(
|
registry.register(
|
||||||
@ -39,7 +42,7 @@ public class AdaptTest {
|
|||||||
data -> Duration.between(LocalTime.now(), data)
|
data -> Duration.between(LocalTime.now(), data)
|
||||||
);
|
);
|
||||||
|
|
||||||
ConfigurationProvider provider = new ConfigurationProvider();
|
ConfigurationProvider<TestSource> provider = new ConfigurationProvider<>(new TestSource(), new ConfigurationLoader(), registry, new OptionHolder());
|
||||||
|
|
||||||
LocalTime v = registry.deserialize(provider, LocalTime.class, "600");
|
LocalTime v = registry.deserialize(provider, LocalTime.class, "600");
|
||||||
Object d = registry.serialize(provider, v);
|
Object d = registry.serialize(provider, v);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import cc.carm.lib.configuration.loader.PathGenerator;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class NameTest {
|
public class NameTest {
|
||||||
@ -6,10 +7,10 @@ public class NameTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onTest() {
|
public void onTest() {
|
||||||
|
|
||||||
System.out.println(ConfigInitializer.getPathFromName("LoveGames")); // -> love-games
|
System.out.println(PathGenerator.covertPathName("LoveGames")); // -> love-games
|
||||||
System.out.println(ConfigInitializer.getPathFromName("EASY_GAME")); // -> easy-game
|
System.out.println(PathGenerator.covertPathName("EASY_GAME")); // -> easy-game
|
||||||
System.out.println(ConfigInitializer.getPathFromName("F")); //-? f
|
System.out.println(PathGenerator.covertPathName("F")); //-? f
|
||||||
System.out.println(ConfigInitializer.getPathFromName("Test123123")); // -? test123123123
|
System.out.println(PathGenerator.covertPathName("Test123123")); // -? test123123123
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
42
core/src/test/java/cc/carm/test/config/LoaderTest.java
Normal file
42
core/src/test/java/cc/carm/test/config/LoaderTest.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
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.ConfigurationProvider;
|
||||||
|
import cc.carm.lib.configuration.loader.ConfigurationLoader;
|
||||||
|
import cc.carm.lib.easyoptions.OptionHolder;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class LoaderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
ConfigurationProvider<TestSource> provider = new ConfigurationProvider<>(new TestSource(), new ConfigurationLoader(), new ValueAdapterRegistry(), new OptionHolder());
|
||||||
|
|
||||||
|
ConfigurationLoader loader = new ConfigurationLoader();
|
||||||
|
loader.load(provider, ROOT.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ROOT extends Configuration {
|
||||||
|
|
||||||
|
interface SUB extends Configuration {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ConfigPath(root = true)
|
||||||
|
interface EXTERNAL extends Configuration {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigPath("NO")
|
||||||
|
interface YES extends Configuration {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
82
core/src/test/java/cc/carm/test/config/TestSource.java
Normal file
82
core/src/test/java/cc/carm/test/config/TestSource.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package cc.carm.test.config;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationSection;
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationSource;
|
||||||
|
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 TestSource() {
|
||||||
|
super(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TestSource getThis() {
|
||||||
|
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 Set<String> getKeys(boolean deep) {
|
||||||
|
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) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.demo;
|
package cc.carm.lib.configuration.demo;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.Configuration;
|
import cc.carm.lib.configuration.source.Configuration;
|
||||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||||
import cc.carm.lib.configuration.annotation.HeaderComment;
|
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
import cc.carm.lib.configuration.value.ConfigValue;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.demo.tests;
|
package cc.carm.lib.configuration.demo.tests;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
|
||||||
import cc.carm.lib.configuration.demo.tests.conf.DemoConfiguration;
|
import cc.carm.lib.configuration.demo.tests.conf.DemoConfiguration;
|
||||||
import cc.carm.lib.configuration.demo.tests.conf.TestConfiguration;
|
import cc.carm.lib.configuration.demo.tests.conf.TestConfiguration;
|
||||||
import cc.carm.lib.configuration.demo.tests.model.TestModel;
|
import cc.carm.lib.configuration.demo.tests.model.TestModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.demo.tests.conf;
|
package cc.carm.lib.configuration.demo.tests.conf;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.Configuration;
|
import cc.carm.lib.configuration.source.Configuration;
|
||||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||||
import cc.carm.lib.configuration.annotation.HeaderComment;
|
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||||
import cc.carm.lib.configuration.annotation.InlineComment;
|
import cc.carm.lib.configuration.annotation.InlineComment;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.demo.tests.conf;
|
package cc.carm.lib.configuration.demo.tests.conf;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.Configuration;
|
import cc.carm.lib.configuration.source.Configuration;
|
||||||
import cc.carm.lib.configuration.annotation.ConfigPath;
|
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||||
import cc.carm.lib.configuration.annotation.HeaderComment;
|
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||||
import cc.carm.lib.configuration.annotation.InlineComment;
|
import cc.carm.lib.configuration.annotation.InlineComment;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.demo.tests.conf;
|
package cc.carm.lib.configuration.demo.tests.conf;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.Configuration;
|
import cc.carm.lib.configuration.source.Configuration;
|
||||||
import cc.carm.lib.configuration.annotation.HeaderComment;
|
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
import cc.carm.lib.configuration.value.ConfigValue;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.demo.tests.model;
|
package cc.carm.lib.configuration.demo.tests.model;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
51
features/commentable/pom.xml
Normal file
51
features/commentable/pom.xml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>easyconfiguration-parent</artifactId>
|
||||||
|
<version>3.9.1</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<artifactId>easyconfiguration-feature-commentable</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>easyconfiguration-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,22 @@
|
|||||||
|
package cc.carm.lib.configuration.commentable;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||||
|
import cc.carm.lib.configuration.annotation.InlineComment;
|
||||||
|
import cc.carm.lib.configuration.value.meta.ValueMetaType;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface CommentableMetaTypes {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration's {@link HeaderComment}
|
||||||
|
*/
|
||||||
|
ValueMetaType<List<String>> HEADER_COMMENTS = ValueMetaType.of(Collections.emptyList());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration's {@link InlineComment}
|
||||||
|
*/
|
||||||
|
ValueMetaType<String> INLINE_COMMENT_VALUE = ValueMetaType.of();
|
||||||
|
|
||||||
|
}
|
@ -1,9 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.commentable;
|
package cc.carm.lib.configuration.option;
|
||||||
|
|
||||||
import cc.carm.lib.easyoptions.OptionType;
|
import cc.carm.lib.easyoptions.OptionType;
|
||||||
|
|
||||||
import static cc.carm.lib.easyoptions.OptionType.of;
|
|
||||||
|
|
||||||
public interface CommentableOptions {
|
public interface CommentableOptions {
|
||||||
|
|
||||||
/**
|
/**
|
@ -7,6 +7,7 @@
|
|||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>easyconfiguration-parent</artifactId>
|
<artifactId>easyconfiguration-parent</artifactId>
|
||||||
<version>3.9.1</version>
|
<version>3.9.1</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
||||||
@ -15,8 +16,8 @@
|
|||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<artifactId>easyconfiguration-commentable</artifactId>
|
<artifactId>easyconfiguration-feature-file</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -26,4 +27,24 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</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>
|
</project>
|
@ -0,0 +1,15 @@
|
|||||||
|
package cc.carm.lib.configuration.option;
|
||||||
|
|
||||||
|
import cc.carm.lib.easyoptions.OptionType;
|
||||||
|
|
||||||
|
import static cc.carm.lib.easyoptions.OptionType.of;
|
||||||
|
|
||||||
|
public class FileConfigOptions {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to copy files from resource if exists.
|
||||||
|
*/
|
||||||
|
OptionType<Boolean> COPY_DEFAULTS = of(true);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
//package cc.carm.lib.configuration.core.source.impl;
|
||||||
|
//
|
||||||
|
//import org.jetbrains.annotations.NotNull;
|
||||||
|
//import org.jetbrains.annotations.Nullable;
|
||||||
|
//
|
||||||
|
//import java.io.File;
|
||||||
|
//import java.io.IOException;
|
||||||
|
//import java.io.InputStream;
|
||||||
|
//import java.io.OutputStream;
|
||||||
|
//import java.net.URL;
|
||||||
|
//import java.net.URLConnection;
|
||||||
|
//import java.nio.file.Files;
|
||||||
|
//import java.util.Objects;
|
||||||
|
//
|
||||||
|
//public abstract class FileConfigProvider<W extends ConfigurationWrapper<?>> extends ConfigurationProvider<W> {
|
||||||
|
//
|
||||||
|
// protected final @NotNull File file;
|
||||||
|
//
|
||||||
|
// protected FileConfigProvider(@NotNull File file) {
|
||||||
|
// this.file = file;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public @NotNull File getFile() {
|
||||||
|
// return file;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void initializeFile(@Nullable String sourcePath) throws IOException {
|
||||||
|
// if (this.file.exists()) return;
|
||||||
|
//
|
||||||
|
// File parent = this.file.getParentFile();
|
||||||
|
// if (parent != null && !parent.exists() && !parent.mkdirs()) {
|
||||||
|
// throw new IOException("Failed to create directory " + file.getParentFile().getAbsolutePath());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!this.file.createNewFile()) {
|
||||||
|
// throw new IOException("Failed to create file " + file.getAbsolutePath());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (sourcePath != null) {
|
||||||
|
// try {
|
||||||
|
// saveResource(sourcePath, true);
|
||||||
|
// } catch (IllegalArgumentException ignored) {
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void saveResource(@NotNull String resourcePath, boolean replace)
|
||||||
|
// throws IOException, IllegalArgumentException {
|
||||||
|
// Objects.requireNonNull(resourcePath, "ResourcePath cannot be null");
|
||||||
|
// if (resourcePath.isEmpty()) throw new IllegalArgumentException("ResourcePath cannot be empty");
|
||||||
|
//
|
||||||
|
// resourcePath = resourcePath.replace('\\', '/');
|
||||||
|
//
|
||||||
|
// URL url = this.getClass().getClassLoader().getResource(resourcePath);
|
||||||
|
// if (url == null) throw new IllegalArgumentException("The resource '" + resourcePath + "' not exists");
|
||||||
|
//
|
||||||
|
// File outDir = file.getParentFile();
|
||||||
|
//
|
||||||
|
// if (!outDir.exists() && !outDir.mkdirs()) throw new IOException("Failed to create directory " + outDir);
|
||||||
|
// if (!file.exists() || replace) {
|
||||||
|
// try (OutputStream out = Files.newOutputStream(file.toPath())) {
|
||||||
|
// URLConnection connection = url.openConnection();
|
||||||
|
// connection.setUseCaches(false);
|
||||||
|
// try (InputStream in = connection.getInputStream()) {
|
||||||
|
// byte[] buf = new byte[1024];
|
||||||
|
// int len;
|
||||||
|
// while ((len = in.read(buf)) > 0) {
|
||||||
|
// out.write(buf, 0, len);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Nullable
|
||||||
|
// public InputStream getResource(@NotNull String filename) {
|
||||||
|
// try {
|
||||||
|
// URL url = this.getClass().getClassLoader().getResource(filename);
|
||||||
|
// if (url == null) return null;
|
||||||
|
// URLConnection connection = url.openConnection();
|
||||||
|
// connection.setUseCaches(false);
|
||||||
|
// return connection.getInputStream();
|
||||||
|
// } catch (IOException ex) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
@ -0,0 +1,6 @@
|
|||||||
|
package cc.carm.lib.configuration.source;
|
||||||
|
|
||||||
|
public class FileConfigSource {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
14
pom.xml
14
pom.xml
@ -18,12 +18,14 @@
|
|||||||
<version>3.9.1</version>
|
<version>3.9.1</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>core</module>
|
<module>core</module>
|
||||||
<module>demo</module>
|
<module>features/commentable</module>
|
||||||
<module>impl/yaml</module>
|
<module>features/file</module>
|
||||||
<module>impl/json</module>
|
|
||||||
<module>impl/sql</module>
|
<!-- <module>demo</module>-->
|
||||||
<module>impl/hocon</module>
|
<!-- <module>providers/yaml</module>-->
|
||||||
<module>commentable</module>
|
<!-- <module>providers/gson</module>-->
|
||||||
|
<!-- <module>providers/sql</module>-->
|
||||||
|
<!-- <module>providers/hocon</module>-->
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<name>EasyConfiguration</name>
|
<name>EasyConfiguration</name>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
</properties>
|
</properties>
|
||||||
<artifactId>easyconfiguration-json</artifactId>
|
<artifactId>easyconfiguration-gson</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
@ -1,7 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.json;
|
package cc.carm.lib.configuration.json;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.source.comment.ConfigurationComments;
|
import cc.carm.lib.configuration.source.comment.ConfigurationComments;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
|
||||||
import cc.carm.lib.configuration.core.source.impl.FileConfigProvider;
|
import cc.carm.lib.configuration.core.source.impl.FileConfigProvider;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
@ -1,6 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.json;
|
package cc.carm.lib.configuration.json;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
@ -1,6 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.hocon;
|
package cc.carm.lib.configuration.hocon;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import cc.carm.lib.configuration.hocon.util.HOCONUtils;
|
import cc.carm.lib.configuration.hocon.util.HOCONUtils;
|
||||||
import com.typesafe.config.*;
|
import com.typesafe.config.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
@ -1,7 +1,6 @@
|
|||||||
package cc.carm.lib.configuration.sql;
|
package cc.carm.lib.configuration.sql;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.source.comment.ConfigurationComments;
|
import cc.carm.lib.configuration.source.comment.ConfigurationComments;
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
|
|
||||||
import cc.carm.lib.easysql.api.SQLManager;
|
import cc.carm.lib.easysql.api.SQLManager;
|
||||||
import cc.carm.lib.easysql.api.SQLQuery;
|
import cc.carm.lib.easysql.api.SQLQuery;
|
||||||
import cc.carm.lib.easysql.api.SQLTable;
|
import cc.carm.lib.easysql.api.SQLTable;
|
@ -1,6 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.sql;
|
package cc.carm.lib.configuration.sql;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user