mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ee074474c | |||
| 27a68ead7c | |||
| c6cce5208f | |||
| bc67de06f6 | |||
| b668794f5d | |||
| 07424284b7 | |||
| 81e024e309 | |||
| 763fc7c758 | |||
| 56557221a4 | |||
| e4435bf883 | |||
| eee4a278d9 | |||
| 3a0a8e79b9 | |||
| 3b2b1b27cc | |||
| d84ea1b7da | |||
| a1f2cdca04 | |||
| c52183aadd | |||
| d71aabad2d |
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
|
||||
+12
-2
@@ -1,9 +1,10 @@
|
||||
package cc.carm.lib.configuration.core.builder.list;
|
||||
|
||||
import cc.carm.lib.configuration.core.annotation.InlineComment;
|
||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class ConfigListBuilder<V> {
|
||||
|
||||
@@ -13,7 +14,7 @@ public class ConfigListBuilder<V> {
|
||||
this.valueClass = valueClass;
|
||||
}
|
||||
|
||||
public @NotNull <S> SourceListBuilder<S, V> from(@NotNull Class<S> sourceClass,
|
||||
public @NotNull <S> SourceListBuilder<S, V> from(@NotNull Class<? super S> sourceClass,
|
||||
@NotNull ConfigDataFunction<Object, S> sourceParser,
|
||||
@NotNull ConfigDataFunction<S, V> valueParser,
|
||||
@NotNull ConfigDataFunction<V, S> valueSerializer,
|
||||
@@ -45,4 +46,13 @@ public class ConfigListBuilder<V> {
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SourceListBuilder<Map<String, Object>, V> fromMap() {
|
||||
return from(
|
||||
Map.class, obj -> (Map<String, Object>) obj,
|
||||
ConfigDataFunction.required(),
|
||||
ConfigDataFunction.required(),
|
||||
ConfigDataFunction.toObject()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import java.util.List;
|
||||
|
||||
public class SourceListBuilder<S, V> extends CommonConfigBuilder<List<V>, SourceListBuilder<S, V>> {
|
||||
|
||||
protected final @NotNull Class<S> sourceClass;
|
||||
protected final @NotNull Class<? super S> sourceClass;
|
||||
protected @NotNull ConfigDataFunction<Object, S> sourceParser;
|
||||
|
||||
protected final @NotNull Class<V> valueClass;
|
||||
@@ -21,7 +21,7 @@ public class SourceListBuilder<S, V> extends CommonConfigBuilder<List<V>, Source
|
||||
protected @NotNull ConfigDataFunction<V, S> valueSerializer;
|
||||
protected @NotNull ConfigDataFunction<S, Object> sourceSerializer;
|
||||
|
||||
public SourceListBuilder(@NotNull Class<S> sourceClass, @NotNull ConfigDataFunction<Object, S> sourceParser,
|
||||
public SourceListBuilder(@NotNull Class<? super S> sourceClass, @NotNull ConfigDataFunction<Object, S> sourceParser,
|
||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<S, V> valueParser,
|
||||
@NotNull ConfigDataFunction<V, S> valueSerializer,
|
||||
@NotNull ConfigDataFunction<S, Object> sourceSerializer) {
|
||||
|
||||
@@ -48,6 +48,14 @@ public class ConfigMapBuilder<M extends Map<K, V>, K, V> {
|
||||
return fromString(ConfigDataFunction.castFromString(this.valueClass));
|
||||
}
|
||||
|
||||
public SectionMapBuilder<M, K, V> fromSection() {
|
||||
return new SectionMapBuilder<>(
|
||||
supplier,
|
||||
keyClass, ConfigDataFunction.castFromString(keyClass),
|
||||
valueClass, ConfigDataFunction.required(),
|
||||
ConfigDataFunction.castToString(), ConfigDataFunction.required());
|
||||
}
|
||||
|
||||
public SourceMapBuilder<M, Object, K, V> fromObject(@NotNull ConfigDataFunction<Object, V> valueParser) {
|
||||
return from(Object.class, valueParser, ConfigDataFunction.toObject());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package cc.carm.lib.configuration.core.builder.map;
|
||||
|
||||
import cc.carm.lib.configuration.core.builder.CommonConfigBuilder;
|
||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
||||
import cc.carm.lib.configuration.core.value.ValueManifest;
|
||||
import cc.carm.lib.configuration.core.value.type.ConfiguredSectionMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SectionMapBuilder<M extends Map<K, V>, K, V> extends CommonConfigBuilder<M, SectionMapBuilder<M, K, V>> {
|
||||
|
||||
protected final @NotNull Supplier<@NotNull M> supplier;
|
||||
|
||||
protected final @NotNull Class<K> keyClass;
|
||||
protected @NotNull ConfigDataFunction<String, K> keyParser;
|
||||
|
||||
protected final @NotNull Class<V> valueClass;
|
||||
protected @NotNull ConfigDataFunction<ConfigurationWrapper<?>, V> valueParser;
|
||||
|
||||
protected @NotNull ConfigDataFunction<K, String> keySerializer;
|
||||
protected @NotNull ConfigDataFunction<V, ? extends Map<String, Object>> valueSerializer;
|
||||
|
||||
public SectionMapBuilder(@NotNull Supplier<@NotNull M> supplier,
|
||||
@NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<ConfigurationWrapper<?>, V> valueParser,
|
||||
@NotNull ConfigDataFunction<K, String> keySerializer,
|
||||
@NotNull ConfigDataFunction<V, ? extends Map<String, Object>> valueSerializer) {
|
||||
this.supplier = supplier;
|
||||
this.keyClass = keyClass;
|
||||
this.keyParser = keyParser;
|
||||
this.valueClass = valueClass;
|
||||
this.valueParser = valueParser;
|
||||
this.keySerializer = keySerializer;
|
||||
this.valueSerializer = valueSerializer;
|
||||
}
|
||||
|
||||
public <MAP extends Map<K, V>> SectionMapBuilder<MAP, K, V> supplier(@NotNull Supplier<MAP> supplier) {
|
||||
return new SectionMapBuilder<>(supplier,
|
||||
keyClass, keyParser, valueClass, valueParser, keySerializer, valueSerializer
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> defaults(@NotNull Consumer<M> factory) {
|
||||
M map = supplier.get();
|
||||
factory.accept(map);
|
||||
return defaults(map);
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> parseKey(@NotNull ConfigDataFunction<String, K> parser) {
|
||||
this.keyParser = parser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> parseValue(@NotNull ConfigDataFunction<ConfigurationWrapper<?>, V> parser) {
|
||||
this.valueParser = parser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> serializeKey(@NotNull ConfigDataFunction<K, String> serializer) {
|
||||
this.keySerializer = serializer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> serializeValue(@NotNull ConfigDataFunction<V, ? extends Map<String, Object>> serializer) {
|
||||
this.valueSerializer = serializer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> serializeValue(@NotNull BiConsumer<V, Map<String, Object>> serializer) {
|
||||
return serializeValue(v -> {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
serializer.accept(v, map);
|
||||
return map;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull SectionMapBuilder<M, K, V> getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfiguredSectionMap<K, V> build() {
|
||||
return new ConfiguredSectionMap<>(
|
||||
new ValueManifest<>(provider, path, headerComments, inlineComment, defaultValue),
|
||||
this.supplier, this.keyClass, this.keyParser,
|
||||
this.valueClass, this.valueParser,
|
||||
this.keySerializer, this.valueSerializer
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
+4
-1
@@ -46,7 +46,10 @@ public class ConfigValueBuilder<V> {
|
||||
return from(
|
||||
Object.class, ConfigDataFunction.identity(),
|
||||
ConfigValueParser.castObject(valueClass),
|
||||
ConfigDataFunction.toObject(), ConfigDataFunction.toObject()
|
||||
s -> {
|
||||
if (s instanceof Enum<?>) return ((Enum<?>) s).name();
|
||||
else return s;
|
||||
}, ConfigDataFunction.toObject()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -32,6 +32,10 @@ public class SectionValueBuilder<V>
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SectionValueBuilder<V> parseValue(ConfigDataFunction<ConfigurationWrapper<?>, V> valueParser) {
|
||||
return parseValue((section, path) -> valueParser.parse(section));
|
||||
}
|
||||
|
||||
public @NotNull SectionValueBuilder<V> parseValue(ConfigValueParser<ConfigurationWrapper<?>, V> valueParser) {
|
||||
this.parser = valueParser;
|
||||
return this;
|
||||
|
||||
+4
@@ -39,6 +39,10 @@ public class SourceValueBuilder<S, V> extends CommonConfigBuilder<V, SourceValue
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SourceValueBuilder<S, V> parseValue(ConfigDataFunction<S, V> valueParser) {
|
||||
return parseValue((section, path) -> valueParser.parse(section));
|
||||
}
|
||||
|
||||
public @NotNull SourceValueBuilder<S, V> parseValue(@NotNull ConfigValueParser<S, V> valueParser) {
|
||||
this.valueParser = valueParser;
|
||||
return this;
|
||||
|
||||
+18
-17
@@ -13,34 +13,34 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
default <V> @NotNull ConfigDataFunction<T, V> andThen(@NotNull ConfigDataFunction<? super R, V> after) {
|
||||
Objects.requireNonNull(after);
|
||||
return ((data) -> after.parse(parse(data)));
|
||||
return data -> after.parse(parse(data));
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T> @NotNull ConfigDataFunction<T, T> identity() {
|
||||
return (input) -> input;
|
||||
return input -> input;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T> @NotNull ConfigDataFunction<T, T> identity(Class<T> type) {
|
||||
return (input) -> input;
|
||||
return input -> input;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T, V> @NotNull ConfigDataFunction<T, V> required() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
throw new IllegalArgumentException("Please specify the value parser.");
|
||||
};
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T> @NotNull ConfigDataFunction<T, Object> toObject() {
|
||||
return (input) -> input;
|
||||
return input -> input;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <V> @NotNull ConfigDataFunction<Object, V> castObject(Class<V> valueClass) {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (valueClass.isInstance(input)) return valueClass.cast(input);
|
||||
else throw new IllegalArgumentException("Cannot cast value to " + valueClass.getName());
|
||||
};
|
||||
@@ -48,7 +48,7 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static <V> @NotNull ConfigDataFunction<String, V> castFromString(Class<V> valueClass) {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (valueClass.isInstance(input)) return valueClass.cast(input);
|
||||
else throw new IllegalArgumentException("Cannot cast string to " + valueClass.getName());
|
||||
};
|
||||
@@ -56,15 +56,16 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T> @NotNull ConfigDataFunction<T, String> castToString() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof String) return (String) input;
|
||||
else if (input instanceof Enum<?>) return ((Enum<?>) input).name();
|
||||
else return input.toString();
|
||||
};
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <V> @NotNull ConfigDataFunction<String, V> parseString(Class<V> valueClass) {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (valueClass.isInstance(input)) return valueClass.cast(input);
|
||||
else throw new IllegalArgumentException("Cannot cast string to " + valueClass.getName());
|
||||
};
|
||||
@@ -72,7 +73,7 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static @NotNull ConfigDataFunction<Object, Integer> intValue() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof Integer) {
|
||||
return (Integer) input;
|
||||
} else if (input instanceof Number) {
|
||||
@@ -83,7 +84,7 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static @NotNull ConfigDataFunction<Object, Short> shortValue() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof Short) {
|
||||
return (Short) input;
|
||||
} else if (input instanceof Number) {
|
||||
@@ -94,7 +95,7 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static @NotNull ConfigDataFunction<Object, Double> doubleValue() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof Double) {
|
||||
return (Double) input;
|
||||
} else if (input instanceof Number) {
|
||||
@@ -105,7 +106,7 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static @NotNull ConfigDataFunction<Object, Byte> byteValue() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof Byte) {
|
||||
return (Byte) input;
|
||||
} else if (input instanceof Number) {
|
||||
@@ -116,7 +117,7 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static @NotNull ConfigDataFunction<Object, Float> floatValue() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof Float) {
|
||||
return (Float) input;
|
||||
} else if (input instanceof Number) {
|
||||
@@ -127,7 +128,7 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static @NotNull ConfigDataFunction<Object, Long> longValue() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof Long) {
|
||||
return (Long) input;
|
||||
} else if (input instanceof Number) {
|
||||
@@ -138,14 +139,14 @@ public interface ConfigDataFunction<T, R> {
|
||||
|
||||
@Contract(pure = true)
|
||||
static @NotNull ConfigDataFunction<Object, Boolean> booleanValue() {
|
||||
return (input) -> {
|
||||
return input -> {
|
||||
if (input instanceof Boolean) {
|
||||
return (Boolean) input;
|
||||
} else if (input instanceof String) {
|
||||
String s = (String) input;
|
||||
return Boolean.parseBoolean(s) || "yes".equalsIgnoreCase(s);
|
||||
} else if (input instanceof Integer) {
|
||||
return ((Integer) input) == 1;
|
||||
return (Integer) input == 1;
|
||||
} else throw new IllegalArgumentException("Cannot cast value to " + Boolean.class.getName());
|
||||
};
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ public interface ConfigValueParser<T, R> {
|
||||
}
|
||||
} else if (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);
|
||||
}
|
||||
|
||||
if (valueClass.isInstance(input)) return valueClass.cast(input);
|
||||
@@ -125,6 +128,21 @@ public interface ConfigValueParser<T, R> {
|
||||
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());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+16
-16
@@ -5,9 +5,13 @@ import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
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> {
|
||||
@@ -37,39 +41,35 @@ public abstract class FileConfigProvider<W extends ConfigurationWrapper<?>> exte
|
||||
if (sourcePath != null) {
|
||||
try {
|
||||
saveResource(sourcePath, true);
|
||||
} catch (Exception ignored) {
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveResource(@NotNull String resourcePath, boolean replace)
|
||||
throws NullPointerException, IOException, IllegalArgumentException {
|
||||
throws IOException, IllegalArgumentException {
|
||||
Objects.requireNonNull(resourcePath, "ResourcePath cannot be null");
|
||||
if (resourcePath.equals("")) throw new IllegalArgumentException("ResourcePath cannot be empty");
|
||||
if (resourcePath.isEmpty()) throw new IllegalArgumentException("ResourcePath cannot be empty");
|
||||
|
||||
resourcePath = resourcePath.replace('\\', '/');
|
||||
InputStream in = getResource(resourcePath);
|
||||
if (in == null) throw new IllegalArgumentException("The resource '" + resourcePath + "' not exists");
|
||||
|
||||
URL url = this.getClass().getClassLoader().getResource(resourcePath);
|
||||
if (url == null) throw new IllegalArgumentException("The resource '" + resourcePath + "' not exists");
|
||||
|
||||
int lastIndex = resourcePath.lastIndexOf('/');
|
||||
File outDir = new File(file, resourcePath.substring(0, Math.max(lastIndex, 0)));
|
||||
File outDir = file.getParentFile();
|
||||
|
||||
if (!outDir.exists() && !outDir.mkdirs()) throw new IOException("Failed to create directory " + outDir);
|
||||
if (!file.exists() || replace) {
|
||||
try {
|
||||
|
||||
OutputStream out = new FileOutputStream(file);
|
||||
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);
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
package cc.carm.lib.configuration.core.value.impl;
|
||||
|
||||
import cc.carm.lib.configuration.core.builder.map.ConfigMapCreator;
|
||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
||||
import cc.carm.lib.configuration.core.value.ValueManifest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
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,
|
||||
@NotNull Class<V> valueClass) {
|
||||
return builder().asMap(keyClass, valueClass);
|
||||
}
|
||||
|
||||
protected final @NotNull Supplier<? extends Map<K, V>> supplier;
|
||||
|
||||
protected final @NotNull Class<? super S> sourceClass;
|
||||
protected final @NotNull Class<K> keyClass;
|
||||
protected final @NotNull Class<V> valueClass;
|
||||
|
||||
protected final @NotNull ConfigDataFunction<String, K> keyParser;
|
||||
protected final @NotNull ConfigDataFunction<S, V> valueParser;
|
||||
|
||||
protected final @NotNull ConfigDataFunction<K, String> keySerializer;
|
||||
protected final @NotNull ConfigDataFunction<V, Object> valueSerializer;
|
||||
|
||||
|
||||
protected ConfigValueMap(@NotNull ValueManifest<Map<K, V>> manifest, @NotNull Class<? super S> sourceClass,
|
||||
@NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
||||
@NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<S, V> valueParser,
|
||||
@NotNull ConfigDataFunction<K, String> keySerializer,
|
||||
@NotNull ConfigDataFunction<V, Object> valueSerializer) {
|
||||
super(manifest);
|
||||
this.supplier = mapObjSupplier;
|
||||
this.sourceClass = sourceClass;
|
||||
this.keyClass = keyClass;
|
||||
this.valueClass = valueClass;
|
||||
this.keyParser = keyParser;
|
||||
this.valueParser = valueParser;
|
||||
this.keySerializer = keySerializer;
|
||||
this.valueSerializer = valueSerializer;
|
||||
}
|
||||
|
||||
public @NotNull Class<? super S> getSourceClass() {
|
||||
return sourceClass;
|
||||
}
|
||||
|
||||
public @NotNull Class<K> getKeyClass() {
|
||||
return keyClass;
|
||||
}
|
||||
|
||||
public @NotNull Class<V> getValueClass() {
|
||||
return valueClass;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<String, K> getKeyParser() {
|
||||
return keyParser;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<S, V> getValueParser() {
|
||||
return valueParser;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<K, String> getKeySerializer() {
|
||||
return keySerializer;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<V, Object> getValueSerializer() {
|
||||
return valueSerializer;
|
||||
}
|
||||
|
||||
public abstract S getSource(ConfigurationWrapper<?> section, String dataKey);
|
||||
|
||||
@Override
|
||||
public @NotNull Map<K, V> get() {
|
||||
if (!isExpired()) return getCachedOrDefault(supplier.get());
|
||||
|
||||
// 已过时的数据,需要重新解析一次。
|
||||
Map<K, V> map = supplier.get();
|
||||
|
||||
ConfigurationWrapper<?> section = getConfiguration().getConfigurationSection(getConfigPath());
|
||||
if (section == null) return getDefaultFirst(map);
|
||||
|
||||
Set<String> keys = section.getKeys(false);
|
||||
if (keys.isEmpty()) return getDefaultFirst(map);
|
||||
|
||||
for (String dataKey : keys) {
|
||||
S dataVal = getSource(section, dataKey);
|
||||
if (dataVal == null) continue;
|
||||
try {
|
||||
K key = keyParser.parse(dataKey);
|
||||
V value = valueParser.parse(dataVal);
|
||||
map.put(key, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return updateCache(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
return get().get(key);
|
||||
}
|
||||
|
||||
public V getNotNull(Object key) {
|
||||
return Objects.requireNonNull(get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@Nullable Map<K, V> value) {
|
||||
updateCache(value);
|
||||
if (value == null) setValue(null);
|
||||
else {
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
for (Map.Entry<K, V> entry : value.entrySet()) {
|
||||
try {
|
||||
data.put(
|
||||
keySerializer.parse(entry.getKey()),
|
||||
valueSerializer.parse(entry.getValue())
|
||||
);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
setValue(data);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> @NotNull T modifyValue(Function<Map<K, V>, T> function) {
|
||||
Map<K, V> m = get();
|
||||
T result = function.apply(m);
|
||||
set(m);
|
||||
return result;
|
||||
}
|
||||
|
||||
public @NotNull Map<K, V> modifyMap(Consumer<Map<K, V>> consumer) {
|
||||
Map<K, V> m = get();
|
||||
consumer.accept(m);
|
||||
set(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return get().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return get().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return get().containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return get().containsValue(value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
return modifyValue(m -> m.put(key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
return modifyValue(m -> m.remove(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(@NotNull Map<? extends K, ? extends V> m) {
|
||||
modifyMap(map -> map.putAll(m));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
modifyMap(Map::clear);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
return get().keySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
return get().values();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@Unmodifiable
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
return get().entrySet();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -65,6 +65,10 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements Lis
|
||||
return get().get(index);
|
||||
}
|
||||
|
||||
public @NotNull List<V> copy() {
|
||||
return new ArrayList<>(get());
|
||||
}
|
||||
|
||||
public <T> @NotNull T handle(Function<List<V>, T> function) {
|
||||
List<V> list = get();
|
||||
T result = function.apply(list);
|
||||
|
||||
@@ -1,40 +1,15 @@
|
||||
package cc.carm.lib.configuration.core.value.type;
|
||||
|
||||
import cc.carm.lib.configuration.core.builder.map.ConfigMapCreator;
|
||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
||||
import cc.carm.lib.configuration.core.value.ValueManifest;
|
||||
import cc.carm.lib.configuration.core.value.impl.CachedConfigValue;
|
||||
import cc.carm.lib.configuration.core.value.impl.ConfigValueMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements Map<K, V> {
|
||||
|
||||
public static <K, V> @NotNull ConfigMapCreator<K, V> builderOf(@NotNull Class<K> keyClass,
|
||||
@NotNull Class<V> valueClass) {
|
||||
return builder().asMap(keyClass, valueClass);
|
||||
}
|
||||
|
||||
protected final @NotNull Supplier<? extends Map<K, V>> supplier;
|
||||
|
||||
protected final @NotNull Class<K> keyClass;
|
||||
protected final @NotNull Class<V> valueClass;
|
||||
|
||||
protected final @NotNull ConfigDataFunction<String, K> keyParser;
|
||||
protected final @NotNull ConfigDataFunction<Object, V> valueParser;
|
||||
|
||||
protected final @NotNull ConfigDataFunction<K, String> keySerializer;
|
||||
protected final @NotNull ConfigDataFunction<V, Object> valueSerializer;
|
||||
|
||||
public class ConfiguredMap<K, V> extends ConfigValueMap<K, V, Object> {
|
||||
|
||||
public ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
||||
@NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
||||
@@ -42,165 +17,12 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
|
||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<Object, V> valueParser,
|
||||
@NotNull ConfigDataFunction<K, String> keySerializer,
|
||||
@NotNull ConfigDataFunction<V, Object> valueSerializer) {
|
||||
super(manifest);
|
||||
this.supplier = mapObjSupplier;
|
||||
this.keyClass = keyClass;
|
||||
this.valueClass = valueClass;
|
||||
this.keyParser = keyParser;
|
||||
this.valueParser = valueParser;
|
||||
this.keySerializer = keySerializer;
|
||||
this.valueSerializer = valueSerializer;
|
||||
}
|
||||
|
||||
public @NotNull Class<K> getKeyClass() {
|
||||
return keyClass;
|
||||
}
|
||||
|
||||
public @NotNull Class<V> getValueClass() {
|
||||
return valueClass;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<String, K> getKeyParser() {
|
||||
return keyParser;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<Object, V> getValueParser() {
|
||||
return valueParser;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<K, String> getKeySerializer() {
|
||||
return keySerializer;
|
||||
}
|
||||
|
||||
public @NotNull ConfigDataFunction<V, Object> getValueSerializer() {
|
||||
return valueSerializer;
|
||||
super(manifest, Object.class, mapObjSupplier, keyClass, keyParser, valueClass, valueParser, keySerializer, valueSerializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<K, V> get() {
|
||||
if (!isExpired()) return getCachedOrDefault(supplier.get());
|
||||
|
||||
// 已过时的数据,需要重新解析一次。
|
||||
Map<K, V> map = supplier.get();
|
||||
|
||||
ConfigurationWrapper<?> section = getConfiguration().getConfigurationSection(getConfigPath());
|
||||
if (section == null) return getDefaultFirst(map);
|
||||
|
||||
Set<String> keys = section.getKeys(false);
|
||||
if (keys.isEmpty()) return getDefaultFirst(map);
|
||||
|
||||
for (String dataKey : keys) {
|
||||
Object dataVal = section.get(dataKey);
|
||||
if (dataVal == null) continue;
|
||||
try {
|
||||
K key = keyParser.parse(dataKey);
|
||||
V value = valueParser.parse(dataVal);
|
||||
map.put(key, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return updateCache(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
return get().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@Nullable Map<K, V> value) {
|
||||
updateCache(value);
|
||||
if (value == null) setValue(null);
|
||||
else {
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
for (Map.Entry<K, V> entry : value.entrySet()) {
|
||||
try {
|
||||
data.put(
|
||||
keySerializer.parse(entry.getKey()),
|
||||
valueSerializer.parse(entry.getValue())
|
||||
);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
setValue(data);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> @NotNull T modifyValue(Function<Map<K, V>, T> function) {
|
||||
Map<K, V> m = get();
|
||||
T result = function.apply(m);
|
||||
set(m);
|
||||
return result;
|
||||
}
|
||||
|
||||
public @NotNull Map<K, V> modifyMap(Consumer<Map<K, V>> consumer) {
|
||||
Map<K, V> m = get();
|
||||
consumer.accept(m);
|
||||
set(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return get().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return get().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return get().containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return get().containsValue(value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
return modifyValue(m -> m.put(key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
return modifyValue(m -> m.remove(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(@NotNull Map<? extends K, ? extends V> m) {
|
||||
modifyMap(map -> map.putAll(m));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
modifyMap(Map::clear);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
return get().keySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
return get().values();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@Unmodifiable
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
return get().entrySet();
|
||||
public Object getSource(ConfigurationWrapper<?> section, String dataKey) {
|
||||
return section.get(dataKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package cc.carm.lib.configuration.core.value.type;
|
||||
|
||||
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
|
||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
||||
import cc.carm.lib.configuration.core.value.ValueManifest;
|
||||
import cc.carm.lib.configuration.core.value.impl.ConfigValueMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ConfiguredSectionMap<K, V> extends ConfigValueMap<K, V, ConfigurationWrapper<?>> {
|
||||
|
||||
public ConfiguredSectionMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
||||
@NotNull Supplier<? extends Map<K, V>> mapObjSupplier,
|
||||
@NotNull Class<K> keyClass, @NotNull ConfigDataFunction<String, K> keyParser,
|
||||
@NotNull Class<V> valueClass, @NotNull ConfigDataFunction<ConfigurationWrapper<?>, V> valueParser,
|
||||
@NotNull ConfigDataFunction<K, String> keySerializer,
|
||||
@NotNull ConfigDataFunction<V, ? extends Map<String, Object>> valueSerializer) {
|
||||
super(
|
||||
manifest, ConfigurationWrapper.class, mapObjSupplier,
|
||||
keyClass, keyParser, valueClass, valueParser,
|
||||
keySerializer, valueSerializer.andThen(s -> (Object) s)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationWrapper<?> getSource(ConfigurationWrapper<?> section, String dataKey) {
|
||||
return section.getConfigurationSection(dataKey);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
|
||||
@@ -12,6 +12,7 @@ import cc.carm.lib.configuration.core.value.type.ConfiguredSection;
|
||||
import cc.carm.lib.configuration.core.value.type.ConfiguredValue;
|
||||
import cc.carm.lib.configuration.demo.tests.model.TestModel;
|
||||
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -25,6 +26,8 @@ public class DemoConfiguration extends ConfigurationRoot {
|
||||
@ConfigPath(root = true)
|
||||
public static final ConfigValue<Long> TEST_NUMBER = ConfiguredValue.of(Long.class, 1000000L);
|
||||
|
||||
public static final ConfigValue<ChronoUnit> TEST_ENUM = ConfiguredValue.of(ChronoUnit.class, ChronoUnit.DAYS);
|
||||
|
||||
// 支持通过 Class<?> 变量标注子配置,一并注册。
|
||||
// 注意: 若对应类也有注解,则优先使用类的注解。
|
||||
@ConfigPath("other-class-config") //支持通过注解修改子配置的主路径,若不修改则以变量名自动生成。
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<?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.8.0</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-hocon</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>easyconfiguration-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>easyconfiguration-demo</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.typesafe</groupId>
|
||||
<artifactId>config</artifactId>
|
||||
<version>1.4.2</version>
|
||||
<scope>compile</scope>
|
||||
</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,36 @@
|
||||
package cc.carm.lib.configuration;
|
||||
|
||||
import cc.carm.lib.configuration.hocon.HOCONFileConfigProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EasyConfiguration {
|
||||
|
||||
private EasyConfiguration() {
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(File file, String source) {
|
||||
HOCONFileConfigProvider provider = new HOCONFileConfigProvider(file);
|
||||
try {
|
||||
provider.initializeFile(source);
|
||||
provider.initializeConfig();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(File file) {
|
||||
return from(file, file.getName());
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(String fileName) {
|
||||
return from(fileName, fileName);
|
||||
}
|
||||
|
||||
public static HOCONFileConfigProvider from(String fileName, String source) {
|
||||
return from(new File(fileName), source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package cc.carm.lib.configuration.hocon;
|
||||
|
||||
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
|
||||
import cc.carm.lib.configuration.hocon.util.HOCONUtils;
|
||||
import com.typesafe.config.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class HOCONConfigWrapper implements ConfigurationWrapper<Map<String, Object>> {
|
||||
private static final char SEPARATOR = '.';
|
||||
protected final Map<String, Object> data;
|
||||
|
||||
public HOCONConfigWrapper(ConfigObject config) {
|
||||
this.data = new LinkedHashMap<>();
|
||||
|
||||
config.forEach((key, value) -> {
|
||||
Config cfg = config.toConfig();
|
||||
ConfigValue cv = cfg.getValue(key);
|
||||
if (cv.valueType() == ConfigValueType.OBJECT) {
|
||||
HOCONConfigWrapper.this.data.put(key, new HOCONConfigWrapper((ConfigObject) cv));
|
||||
} else {
|
||||
HOCONConfigWrapper.this.data.put(key, value.unwrapped());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getSource() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<String> getKeys(boolean deep) {
|
||||
return this.getValues(deep).keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> getValues(boolean deep) {
|
||||
return HOCONUtils.getKeysFromObject(this, deep, "").stream().collect(
|
||||
LinkedHashMap::new,
|
||||
(map, key) -> map.put(key, get(key)),
|
||||
LinkedHashMap::putAll
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
value = new HOCONConfigWrapper(ConfigFactory.parseMap((Map<String, ?>) value).root());
|
||||
}
|
||||
|
||||
HOCONConfigWrapper section = HOCONUtils.getObjectOn(this, path, SEPARATOR);
|
||||
String simplePath = HOCONUtils.getSimplePath(path, SEPARATOR);
|
||||
|
||||
if (value == null) {
|
||||
section.data.remove(simplePath);
|
||||
} else {
|
||||
section.setDirect(simplePath, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能设置当前路径下的内容
|
||||
* 避免环回
|
||||
*
|
||||
* @param path 路径
|
||||
*/
|
||||
public void setDirect(@NotNull String path, @Nullable Object value) {
|
||||
this.data.put(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull String path) {
|
||||
return this.get(path) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull String path) {
|
||||
HOCONConfigWrapper section = HOCONUtils.getObjectOn(this, path, SEPARATOR);
|
||||
return section.getDirect(HOCONUtils.getSimplePath(path, SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能获取当前路径下的内容
|
||||
* 避免环回
|
||||
*
|
||||
* @param path 路径
|
||||
*/
|
||||
public Object getDirect(@NotNull String path) {
|
||||
return this.data.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList(@NotNull String path) {
|
||||
return this.get(path) instanceof List<?>;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<?> getList(@NotNull String path) {
|
||||
Object val = this.get(path);
|
||||
return (val instanceof List<?>) ? (List<?>) val : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigurationSection(@NotNull String path) {
|
||||
return this.get(path) instanceof HOCONConfigWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigurationWrapper<Map<String, Object>> getConfigurationSection(@NotNull String path) {
|
||||
Object val = get(path);
|
||||
return (val instanceof HOCONConfigWrapper) ? (HOCONConfigWrapper) val : null;
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package cc.carm.lib.configuration.hocon;
|
||||
|
||||
import cc.carm.lib.configuration.core.ConfigInitializer;
|
||||
import cc.carm.lib.configuration.core.source.ConfigurationComments;
|
||||
import cc.carm.lib.configuration.core.source.impl.FileConfigProvider;
|
||||
import cc.carm.lib.configuration.hocon.exception.HOCONGetValueException;
|
||||
import cc.carm.lib.configuration.hocon.util.HOCONUtils;
|
||||
import com.typesafe.config.*;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class HOCONFileConfigProvider extends FileConfigProvider<HOCONConfigWrapper> {
|
||||
protected final @NotNull ConfigurationComments comments = new ConfigurationComments();
|
||||
protected HOCONConfigWrapper configuration;
|
||||
protected ConfigInitializer<HOCONFileConfigProvider> initializer;
|
||||
|
||||
public HOCONFileConfigProvider(@NotNull File file) {
|
||||
super(file);
|
||||
this.initializer = new ConfigInitializer<>(this);
|
||||
}
|
||||
|
||||
public void initializeConfig() {
|
||||
try {
|
||||
this.configuration = new HOCONConfigWrapper(ConfigFactory.parseFile(this.file, ConfigParseOptions.defaults()
|
||||
.setSyntax(ConfigSyntax.CONF)
|
||||
.setAllowMissing(false)).root());
|
||||
} catch (ConfigException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HOCONConfigWrapper getConfiguration() {
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
Files.write(this.file.toPath(), HOCONUtils.renderWithComment(configuration, comments::getHeaderComment).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReload() throws ConfigException {
|
||||
ConfigObject conf = ConfigFactory.parseFile(this.file, ConfigParseOptions.defaults()
|
||||
.setSyntax(ConfigSyntax.CONF)
|
||||
.setAllowMissing(false)).root();
|
||||
this.configuration = new HOCONConfigWrapper(conf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigurationComments getComments() {
|
||||
return this.comments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigInitializer<HOCONFileConfigProvider> getInitializer() {
|
||||
return this.initializer;
|
||||
}
|
||||
|
||||
public String serializeValue(@NotNull String key, @NotNull Object value) {
|
||||
// 带有 key=value 的新空对象
|
||||
return ConfigFactory.empty()
|
||||
.withValue(key, ConfigValueFactory.fromAnyRef(value))
|
||||
.root().render();
|
||||
}
|
||||
|
||||
public @NotNull Set<String> getKeys() {
|
||||
return getKeys(null, true);
|
||||
}
|
||||
|
||||
@Contract("null,_->!null")
|
||||
public @Nullable Set<String> getKeys(@Nullable String sectionKey, boolean deep) {
|
||||
if (sectionKey == null) { // 当前路径
|
||||
return HOCONUtils.getKeysFromObject(this.configuration, deep, "");
|
||||
}
|
||||
|
||||
HOCONConfigWrapper section;
|
||||
try {
|
||||
// 获取目标字段所在路径
|
||||
section = (HOCONConfigWrapper) this.configuration.get(sectionKey);
|
||||
} catch (ClassCastException e) {
|
||||
// 值和类型不匹配
|
||||
throw new HOCONGetValueException(e);
|
||||
}
|
||||
if (section == null) {
|
||||
return null;
|
||||
}
|
||||
return HOCONUtils.getKeysFromObject(section, deep, "");
|
||||
}
|
||||
|
||||
public @Nullable Object getValue(@NotNull String key) {
|
||||
return this.configuration.get(key);
|
||||
}
|
||||
|
||||
public @Nullable List<String> getHeaderComments(@Nullable String key) {
|
||||
return this.comments.getHeaderComment(key);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cc.carm.lib.configuration.hocon.exception;
|
||||
|
||||
public class HOCONGetValueException extends RuntimeException {
|
||||
public HOCONGetValueException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HOCONGetValueException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public HOCONGetValueException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public HOCONGetValueException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package cc.carm.lib.configuration.hocon.util;
|
||||
|
||||
import cc.carm.lib.configuration.hocon.HOCONConfigWrapper;
|
||||
import cc.carm.lib.configuration.hocon.exception.HOCONGetValueException;
|
||||
import com.typesafe.config.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class HOCONUtils {
|
||||
|
||||
private HOCONUtils() {
|
||||
}
|
||||
|
||||
public static String getSimplePath(String path, char separator) {
|
||||
int index = path.lastIndexOf(separator);
|
||||
return (index == -1) ? path : path.substring(index + 1);
|
||||
}
|
||||
|
||||
public static HOCONConfigWrapper getObjectOn(@NotNull HOCONConfigWrapper parent, @NotNull String path, char separator) {
|
||||
String currentPath = path;
|
||||
HOCONConfigWrapper currentObject = parent;
|
||||
int index;
|
||||
while ((index = currentPath.indexOf(separator)) != -1) {
|
||||
HOCONConfigWrapper previousObject = currentObject;
|
||||
String pathName = currentPath.substring(0, index);
|
||||
try {
|
||||
currentObject = (HOCONConfigWrapper) previousObject.getDirect(pathName);
|
||||
} catch (ClassCastException e) {
|
||||
throw new HOCONGetValueException(e);
|
||||
}
|
||||
if (currentObject == null) {
|
||||
currentObject = new HOCONConfigWrapper(ConfigFactory.empty().root());
|
||||
previousObject.setDirect(pathName, currentObject);
|
||||
}
|
||||
currentPath = currentPath.substring(index + 1);
|
||||
}
|
||||
|
||||
return currentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 Object 中获取所有键
|
||||
* 思路:在第一次执行时 prefix 应该是 ""
|
||||
* 后续找到了更深层的键,将会变为 "deep."
|
||||
* 下一次键名就是 "deep.key"
|
||||
*
|
||||
* @param parent Object
|
||||
* @param deep 是否更深层获取
|
||||
* @param prefix 当前 Object 键名前缀
|
||||
* @return Object 中的所有键
|
||||
*/
|
||||
public static Set<String> getKeysFromObject(HOCONConfigWrapper parent, boolean deep, String prefix) {
|
||||
return parent.getSource().entrySet().stream().collect(
|
||||
LinkedHashSet::new,
|
||||
(set, entry) -> {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof HOCONConfigWrapper && deep) {
|
||||
set.addAll(HOCONUtils.getKeysFromObject((HOCONConfigWrapper) value, true, prefix + entry.getKey() + "."));
|
||||
} else {
|
||||
set.add(prefix + entry.getKey());
|
||||
}
|
||||
},
|
||||
LinkedHashSet::addAll
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Object 保存为字符串
|
||||
* 并使用注释器打上注释
|
||||
*
|
||||
* @param object Object
|
||||
* @param commenter 注释器
|
||||
* @return 保存的字符串
|
||||
*/
|
||||
public static @NotNull String renderWithComment(@NotNull HOCONConfigWrapper object, @NotNull Function<String, List<String>> commenter) {
|
||||
return HOCONUtils.makeConfigWithComment(object, "", commenter).root().render(
|
||||
ConfigRenderOptions.defaults()
|
||||
.setJson(false)
|
||||
.setOriginComments(false)
|
||||
);
|
||||
}
|
||||
|
||||
public static @NotNull Config makeConfigWithComment(@NotNull HOCONConfigWrapper object, @NotNull String prefix, @NotNull Function<String, List<String>> commenter) {
|
||||
Config config = ConfigFactory.empty();
|
||||
for (Map.Entry<String, Object> entry : object.getSource().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String fullKey = prefix + key;
|
||||
Object value = entry.getValue();
|
||||
ConfigValue result;
|
||||
if (value instanceof Iterable) {
|
||||
result = ConfigValueFactory.fromIterable((Iterable<?>) value);
|
||||
} else if (value instanceof HOCONConfigWrapper) {
|
||||
result = makeConfigWithComment((HOCONConfigWrapper) value, fullKey + ".", commenter).root();
|
||||
} else {
|
||||
result = ConfigValueFactory.fromAnyRef(value);
|
||||
}
|
||||
result = result.withOrigin(
|
||||
ConfigOriginFactory.newSimple()
|
||||
.withComments(commenter.apply(fullKey))
|
||||
);
|
||||
config = config.withValue(key, result);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package online.flowerinsnow.test.easyconfiguration;
|
||||
|
||||
import cc.carm.lib.configuration.EasyConfiguration;
|
||||
//import cc.carm.lib.configuration.demo.DatabaseConfiguration;
|
||||
//import cc.carm.lib.configuration.demo.tests.conf.DemoConfiguration;
|
||||
import cc.carm.lib.configuration.hocon.HOCONFileConfigProvider;
|
||||
import online.flowerinsnow.test.easyconfiguration.config.Config;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class HOCONTest {
|
||||
@Test
|
||||
public void onTest() {
|
||||
HOCONFileConfigProvider provider = EasyConfiguration.from(new File("target/hocon.conf"));
|
||||
provider.initialize(Config.class);
|
||||
// provider.initialize(DatabaseConfiguration.class);
|
||||
try {
|
||||
provider.reload();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package online.flowerinsnow.test.easyconfiguration.config;
|
||||
|
||||
import cc.carm.lib.configuration.core.ConfigurationRoot;
|
||||
import cc.carm.lib.configuration.core.annotation.HeaderComment;
|
||||
import cc.carm.lib.configuration.core.value.type.ConfiguredList;
|
||||
import cc.carm.lib.configuration.core.value.type.ConfiguredValue;
|
||||
|
||||
public class Config extends ConfigurationRoot {
|
||||
@HeaderComment("测试字段 int")
|
||||
public static final ConfiguredValue<Integer> TEST_INT = ConfiguredValue.of(Integer.class, 15);
|
||||
|
||||
@HeaderComment("测试字段 List<String>")
|
||||
public static final ConfiguredList<String> TEST_LIST_STRING = ConfiguredList.of(String.class, "li", "li", "li1");
|
||||
|
||||
@HeaderComment("测试对象")
|
||||
public static class TestObject extends ConfigurationRoot {
|
||||
@HeaderComment("测试字段 Boolean")
|
||||
public static final ConfiguredValue<Boolean> TEST_BOOLEAN = ConfiguredValue.of(Boolean.class, true);
|
||||
@HeaderComment("inner")
|
||||
public static class InnerObject extends ConfigurationRoot {
|
||||
@HeaderComment("测试字段")
|
||||
public static final ConfiguredValue<Boolean> TEST_BOOLEAN_1 = ConfiguredValue.of(Boolean.class, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.8.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -7,6 +7,9 @@ import java.io.IOException;
|
||||
|
||||
public class EasyConfiguration {
|
||||
|
||||
private EasyConfiguration() {
|
||||
}
|
||||
|
||||
public static JSONConfigProvider from(File file, String source) {
|
||||
JSONConfigProvider provider = new JSONConfigProvider(file);
|
||||
try {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.8.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,5 +2,7 @@ package cc.carm.lib.configuration;
|
||||
|
||||
public class EasyConfiguration {
|
||||
|
||||
private EasyConfiguration() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
CREATE TABLE IF NOT EXISTS conf
|
||||
(
|
||||
`namespace` VARCHAR(255) NOT NULL, # 命名空间
|
||||
`section` VARCHAR(255) NOT NULL, # 配置路径 (ConfigPath)
|
||||
`type` VARCHAR(255) NOT NULL, # 数据类型 (Integer/Byte/List/Map/...)
|
||||
`path` VARCHAR(255) NOT NULL, # 配置路径 (ConfigPath)
|
||||
`type` TINYINT UNSIGNED NOT NULL DEFAULT 0, # 数据类型 (Integer/Byte/List/Map/...)
|
||||
`value` MEDIUMTEXT, # 配置项的值 (可能为JSON格式)
|
||||
`inline_comments` TINYTEXT, # 行内注释
|
||||
`header_comments` TEXT, # 顶部注释
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`namespace`, `section`)
|
||||
`inline_comments` TEXT, # 行内注释
|
||||
`header_comments` MEDIUMTEXT, # 顶部注释
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, # 创建时间
|
||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`namespace`, `path`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4;
|
||||
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.8.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -44,7 +44,7 @@
|
||||
<dependency>
|
||||
<groupId>org.bspfsystems</groupId>
|
||||
<artifactId>yamlconfiguration</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ import java.io.IOException;
|
||||
|
||||
public class EasyConfiguration {
|
||||
|
||||
private EasyConfiguration() {
|
||||
}
|
||||
|
||||
public static YAMLConfigProvider from(File file, String source) {
|
||||
YAMLConfigProvider provider = new YAMLConfigProvider(file);
|
||||
try {
|
||||
|
||||
@@ -10,6 +10,8 @@ import config.source.ModelConfiguration;
|
||||
import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerialization;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DemoConfigTest {
|
||||
|
||||
static {
|
||||
@@ -17,7 +19,7 @@ public class DemoConfigTest {
|
||||
ConfigurationSerialization.registerClass(AnyModel.class);
|
||||
}
|
||||
|
||||
protected final YAMLConfigProvider provider = EasyConfiguration.from("target/config.yml", "config.yml");
|
||||
protected final YAMLConfigProvider provider = EasyConfiguration.from("target/config.yml", "test/test2/config.yml");
|
||||
|
||||
@Test
|
||||
public void onTest() {
|
||||
@@ -42,6 +44,8 @@ public class DemoConfigTest {
|
||||
if (anyModel != null) System.out.println(anyModel.getName());
|
||||
|
||||
ModelConfiguration.MODELS.forEach(System.out::println);
|
||||
ModelConfiguration.MODEL_MAP.forEach((v, anyModel1) -> System.out.println(v + " -> " + anyModel1.toString()));
|
||||
|
||||
|
||||
System.out.println("----------------------------------------------------");
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@ import cc.carm.lib.configuration.core.annotation.ConfigPath;
|
||||
import cc.carm.lib.configuration.core.annotation.HeaderComment;
|
||||
import cc.carm.lib.configuration.core.value.ConfigValue;
|
||||
import cc.carm.lib.configuration.core.value.type.ConfiguredList;
|
||||
import cc.carm.lib.configuration.core.value.type.ConfiguredMap;
|
||||
import cc.carm.lib.configuration.core.value.type.ConfiguredSectionMap;
|
||||
import cc.carm.lib.configuration.demo.tests.model.AbstractModel;
|
||||
import cc.carm.lib.configuration.yaml.value.ConfiguredSerializable;
|
||||
import config.model.AnyModel;
|
||||
import config.model.SomeModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@HeaderComment("以下内容用于测试序列化")
|
||||
@ConfigPath("model-test")
|
||||
public class ModelConfiguration extends ConfigurationRoot {
|
||||
@@ -25,10 +25,19 @@ public class ModelConfiguration extends ConfigurationRoot {
|
||||
);
|
||||
|
||||
public static final ConfiguredList<AnyModel> MODELS = ConfiguredList.builderOf(AnyModel.class)
|
||||
.fromObject()
|
||||
.parseValue((section) -> AnyModel.deserialize((Map<String, ?>) section))
|
||||
.serializeValue(AnyModel::serialize)
|
||||
.fromMap()
|
||||
.parseValue(AnyModel::deserialize).serializeValue(AnyModel::serialize)
|
||||
.defaults(AnyModel.random(), AnyModel.random(), AnyModel.random())
|
||||
.build();
|
||||
|
||||
public static final ConfiguredSectionMap<String, AnyModel> MODEL_MAP = ConfiguredMap.builderOf(String.class, AnyModel.class)
|
||||
.asLinkedMap().fromSection()
|
||||
.parseValue(v -> new AnyModel(v.getString("name", "EMPTY"), v.getBoolean("state", false)))
|
||||
.serializeValue(AnyModel::serialize)
|
||||
.defaults(m -> {
|
||||
m.put("a", AnyModel.random());
|
||||
m.put("b", AnyModel.random());
|
||||
})
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
version: 1.0
|
||||
@@ -0,0 +1,2 @@
|
||||
version: 1.0
|
||||
test-save: false
|
||||
@@ -15,13 +15,14 @@
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easyconfiguration-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>3.6.0</version>
|
||||
<version>3.8.0</version>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>demo</module>
|
||||
<module>impl/yaml</module>
|
||||
<module>impl/json</module>
|
||||
<module>impl/sql</module>
|
||||
<module>impl/hocon</module>
|
||||
</modules>
|
||||
|
||||
<name>EasyConfiguration</name>
|
||||
@@ -122,7 +123,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.1.2</version>
|
||||
<configuration>
|
||||
<useSystemClassLoader>false</useSystemClassLoader>
|
||||
</configuration>
|
||||
@@ -150,7 +151,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.1</version>
|
||||
<configuration>
|
||||
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||
<useReleaseProfile>false</useReleaseProfile>
|
||||
@@ -211,7 +212,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@@ -225,7 +226,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<version>3.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
||||
Reference in New Issue
Block a user