mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 10:38:19 +08:00
feat(map): Finished Map value builders.
This commit is contained in:
@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,21 +14,21 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class AbstractConfigBuilder<
|
||||
TYPE, RESULT extends ConfigValue<TYPE>, PROVIDER extends ConfigurationHolder<?>,
|
||||
SELF extends AbstractConfigBuilder<TYPE, RESULT, PROVIDER, SELF>
|
||||
TYPE, RESULT extends ConfigValue<TYPE>, HOLDER extends ConfigurationHolder<?>,
|
||||
SELF extends AbstractConfigBuilder<TYPE, RESULT, HOLDER, SELF>
|
||||
> {
|
||||
|
||||
protected final Class<? super PROVIDER> providerClass;
|
||||
protected final Class<? super HOLDER> providerClass;
|
||||
protected final ValueType<TYPE> type;
|
||||
|
||||
protected @Nullable PROVIDER provider;
|
||||
protected @Nullable HOLDER holder;
|
||||
protected @Nullable String path;
|
||||
|
||||
protected @NotNull Supplier<TYPE> defaultValueSupplier = () -> null;
|
||||
protected @NotNull BiConsumer<ConfigurationHolder<?>, String> initializer = (provider, path) -> {
|
||||
protected @NotNull Supplier<@Nullable TYPE> defaultValueSupplier = () -> null;
|
||||
protected @NotNull BiConsumer<ConfigurationHolder<?>, String> initializer = (h, p) -> {
|
||||
};
|
||||
|
||||
protected AbstractConfigBuilder(Class<? super PROVIDER> providerClass, ValueType<TYPE> type) {
|
||||
protected AbstractConfigBuilder(Class<? super HOLDER> providerClass, ValueType<TYPE> type) {
|
||||
this.providerClass = providerClass;
|
||||
this.type = type;
|
||||
}
|
||||
@@ -41,8 +41,8 @@ public abstract class AbstractConfigBuilder<
|
||||
|
||||
public abstract @NotNull RESULT build();
|
||||
|
||||
public @NotNull SELF holder(@Nullable PROVIDER provider) {
|
||||
this.provider = provider;
|
||||
public @NotNull SELF holder(@Nullable HOLDER holder) {
|
||||
this.holder = holder;
|
||||
return self();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public abstract class AbstractConfigBuilder<
|
||||
}
|
||||
|
||||
public @NotNull SELF append(@NotNull Consumer<ConfigurationHolder<?>> initializer) {
|
||||
return append((provider, path) -> initializer.accept(provider));
|
||||
return append((provider, valuePath) -> initializer.accept(provider));
|
||||
}
|
||||
|
||||
public @NotNull SELF defaults(@Nullable TYPE defaultValue) {
|
||||
@@ -74,17 +74,17 @@ public abstract class AbstractConfigBuilder<
|
||||
}
|
||||
|
||||
public <M> @NotNull SELF meta(@NotNull Consumer<@NotNull ConfigurationMetaHolder> metaConsumer) {
|
||||
return append((provider, path) -> metaConsumer.accept(provider.metadata(path)));
|
||||
return append((h, p) -> metaConsumer.accept(h.metadata(p)));
|
||||
}
|
||||
|
||||
public <M> @NotNull SELF meta(@NotNull ConfigurationMetadata<M> type, @Nullable M value) {
|
||||
return meta(holder -> holder.set(type, value));
|
||||
return meta(h -> h.set(type, value));
|
||||
}
|
||||
|
||||
protected @NotNull ValueManifest<TYPE> buildManifest() {
|
||||
return new ValueManifest<>(
|
||||
type(), this.defaultValueSupplier, this.initializer,
|
||||
this.provider, this.path
|
||||
this.holder, this.path
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -3,6 +3,7 @@ package cc.carm.lib.configuration.builder.impl;
|
||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||
import cc.carm.lib.configuration.function.DataConsumer;
|
||||
import cc.carm.lib.configuration.function.DataFunction;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
@@ -11,7 +12,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class AbstractSectionBuilder<
|
||||
TYPE, PARAM,
|
||||
@@ -19,12 +19,13 @@ public abstract class AbstractSectionBuilder<
|
||||
SELF extends AbstractSectionBuilder<TYPE, PARAM, RESULT, SELF>
|
||||
> extends CommonConfigBuilder<TYPE, RESULT, SELF> {
|
||||
|
||||
|
||||
protected final @NotNull ValueType<PARAM> paramType;
|
||||
|
||||
protected @NotNull ValueHandler<ConfigureSection, PARAM> parser;
|
||||
protected @NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer;
|
||||
|
||||
public AbstractSectionBuilder(@NotNull ValueType<TYPE> type, @NotNull ValueType<PARAM> paramType,
|
||||
protected AbstractSectionBuilder(@NotNull ValueType<TYPE> type, @NotNull ValueType<PARAM> paramType,
|
||||
@NotNull ValueHandler<ConfigureSection, PARAM> parser,
|
||||
@NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer) {
|
||||
super(type);
|
||||
@@ -51,7 +52,7 @@ public abstract class AbstractSectionBuilder<
|
||||
return self();
|
||||
}
|
||||
|
||||
public @NotNull SELF serialize(Consumer<Map<String, Object>> serializer) {
|
||||
public @NotNull SELF serialize(DataConsumer<Map<String, Object>> serializer) {
|
||||
return serialize((p, value) -> {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
serializer.accept(map);
|
||||
@@ -71,4 +72,5 @@ public abstract class AbstractSectionBuilder<
|
||||
return map == null || map.isEmpty() ? null : map;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ public abstract class AbstractSourceBuilder<
|
||||
protected @NotNull ValueHandler<SOURCE, PARAM> valueParser;
|
||||
protected @NotNull ValueHandler<PARAM, SOURCE> valueSerializer;
|
||||
|
||||
public AbstractSourceBuilder(@NotNull ValueType<V> type,
|
||||
protected AbstractSourceBuilder(@NotNull ValueType<V> type,
|
||||
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<PARAM> paramType,
|
||||
@NotNull ValueHandler<SOURCE, PARAM> parser,
|
||||
@NotNull ValueHandler<PARAM, SOURCE> serializer) {
|
||||
|
||||
@@ -19,15 +19,25 @@ public class ConfigListBuilder<V> {
|
||||
}
|
||||
|
||||
public <S> @NotNull SourceListBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
|
||||
return new SourceListBuilder<>(sourceType, type, ValueHandler.required(), ValueHandler.required(), ArrayList::new);
|
||||
return new SourceListBuilder<>(
|
||||
ArrayList::new, sourceType, type,
|
||||
ValueHandler.required(type),
|
||||
ValueHandler.required(sourceType)
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SourceListBuilder<String, V> fromString() {
|
||||
return new SourceListBuilder<>(ValueType.STRING, type, ValueHandler.required(), ValueHandler.stringValue(), ArrayList::new);
|
||||
return new SourceListBuilder<>(
|
||||
ArrayList::new, ValueType.STRING, type,
|
||||
ValueHandler.required(type), ValueHandler.stringValue()
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SectionListBuilder<V> fromSection() {
|
||||
return new SectionListBuilder<>(type, ValueHandler.required(), ValueHandler.required(), ArrayList::new);
|
||||
return new SectionListBuilder<>(
|
||||
ArrayList::new, type,
|
||||
ValueHandler.required(type), ValueHandler.required()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ public class SectionListBuilder<V> extends AbstractSectionBuilder<List<V>, V, Co
|
||||
|
||||
protected @NotNull Supplier<? extends List<V>> constructor;
|
||||
|
||||
public SectionListBuilder(@NotNull ValueType<V> paramType,
|
||||
public SectionListBuilder(@NotNull Supplier<? extends List<V>> constructor,
|
||||
@NotNull ValueType<V> paramType,
|
||||
@NotNull ValueHandler<ConfigureSection, V> parser,
|
||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer,
|
||||
@NotNull Supplier<? extends List<V>> constructor) {
|
||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
|
||||
super(new ValueType<List<V>>() {
|
||||
}, paramType, parser, serializer);
|
||||
this.constructor = constructor;
|
||||
|
||||
@@ -17,9 +17,9 @@ public class SourceListBuilder<SOURCE, V>
|
||||
|
||||
protected @NotNull Supplier<? extends List<V>> constructor;
|
||||
|
||||
public SourceListBuilder(@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType,
|
||||
@NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer,
|
||||
@NotNull Supplier<? extends List<V>> constructor) {
|
||||
public SourceListBuilder(@NotNull Supplier<? extends List<V>> constructor,
|
||||
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType,
|
||||
@NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer) {
|
||||
super(new ValueType<List<V>>() {
|
||||
}, sourceType, paramType, parser, serializer);
|
||||
this.constructor = constructor;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package cc.carm.lib.configuration.builder.map;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ConfigMapBuilder<M extends Map<K, V>, K, V> {
|
||||
|
||||
|
||||
protected final @NotNull Supplier<@NotNull M> constructor;
|
||||
protected final @NotNull ValueType<K> keyType;
|
||||
protected final @NotNull ValueType<V> valueType;
|
||||
|
||||
public ConfigMapBuilder(@NotNull Supplier<@NotNull M> constructor,
|
||||
@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
|
||||
this.constructor = constructor;
|
||||
this.keyType = keyType;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public <W extends Map<K, V>> ConfigMapBuilder<W, K, V> constructor(@NotNull Supplier<W> supplier) {
|
||||
return new ConfigMapBuilder<>(supplier, keyType, valueType);
|
||||
}
|
||||
|
||||
public @NotNull <S> SourceMapBuilder<M, S, K, V> from(@NotNull Class<S> clazz) {
|
||||
return from(ValueType.of(clazz));
|
||||
}
|
||||
|
||||
public @NotNull <S> SourceMapBuilder<M, S, K, V> from(@NotNull ValueType<S> sourceType) {
|
||||
return from(
|
||||
sourceType,
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.required()
|
||||
);
|
||||
}
|
||||
|
||||
public <S> @NotNull SourceMapBuilder<M, S, K, V> from(@NotNull ValueType<S> sourceType,
|
||||
@NotNull ValueHandler<String, K> keyParser,
|
||||
@NotNull ValueHandler<K, String> keySerializer,
|
||||
@NotNull ValueHandler<S, V> valueParser,
|
||||
@NotNull ValueHandler<V, S> valueSerializer) {
|
||||
return new SourceMapBuilder<>(
|
||||
this.constructor, sourceType, keyType, valueType,
|
||||
keyParser, keySerializer, valueParser, valueSerializer
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<M, String, K, V> fromString() {
|
||||
return from(
|
||||
ValueType.STRING,
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.stringValue()
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> fromSection() {
|
||||
return fromSection(
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.required()
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> fromSection(
|
||||
@NotNull ValueHandler<String, K> keyParser,
|
||||
@NotNull ValueHandler<K, String> keySerializer,
|
||||
@NotNull ValueHandler<ConfigureSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, Map<String, Object>> valueSerializer
|
||||
) {
|
||||
return new SectionMapBuilder<>(
|
||||
this.constructor, keyType, valueType,
|
||||
keyParser, keySerializer, valueParser, valueSerializer
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cc.carm.lib.configuration.builder.map;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ConfigMapCreator<K, V> {
|
||||
|
||||
protected final @NotNull ValueType<K> keyType;
|
||||
protected final @NotNull ValueType<V> valueType;
|
||||
|
||||
public ConfigMapCreator(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
|
||||
this.keyType = keyType;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public <M extends Map<K, V>> @NotNull ConfigMapBuilder<M, K, V> constructor(@NotNull Supplier<@NotNull M> mapSuppler) {
|
||||
return new ConfigMapBuilder<>(mapSuppler, keyType, valueType);
|
||||
}
|
||||
|
||||
public <W extends Map<K, V>> @NotNull ConfigMapBuilder<W, K, V> constructor(@NotNull Class<W> type) {
|
||||
return constructor(() -> {
|
||||
try {
|
||||
return type.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public @NotNull ConfigMapBuilder<HashMap<K, V>, K, V> asHashMap() {
|
||||
return constructor(HashMap::new);
|
||||
}
|
||||
|
||||
public @NotNull ConfigMapBuilder<LinkedHashMap<K, V>, K, V> asLinkedMap() {
|
||||
return constructor(LinkedHashMap::new);
|
||||
}
|
||||
|
||||
public @NotNull ConfigMapBuilder<TreeMap<K, V>, K, V> asTreeMap() {
|
||||
return constructor(TreeMap::new);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package cc.carm.lib.configuration.builder.map;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
|
||||
import cc.carm.lib.configuration.function.DataFunction;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SectionMapBuilder<MAP extends Map<K, V>, K, V>
|
||||
extends AbstractSectionBuilder<
|
||||
Map<K, V>, V, ConfiguredMap<K, V>,
|
||||
SectionMapBuilder<MAP, K, V>
|
||||
> {
|
||||
|
||||
protected final @NotNull ValueType<K> keyType;
|
||||
|
||||
protected @NotNull Supplier<? extends MAP> constructor;
|
||||
protected @NotNull ValueHandler<String, K> keyParser;
|
||||
protected @NotNull ValueHandler<K, String> keySerializer;
|
||||
|
||||
public SectionMapBuilder(@NotNull Supplier<? extends MAP> constructor,
|
||||
@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType,
|
||||
@NotNull ValueHandler<String, K> keyParser,
|
||||
@NotNull ValueHandler<K, String> keySerializer,
|
||||
@NotNull ValueHandler<ConfigureSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, Map<String, Object>> valueSerializer) {
|
||||
super(new ValueType<Map<K, V>>() {
|
||||
}, valueType, valueParser, valueSerializer);
|
||||
this.keyType = keyType;
|
||||
this.constructor = constructor;
|
||||
this.keyParser = keyParser;
|
||||
this.keySerializer = keySerializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull SectionMapBuilder<MAP, K, V> self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public @NotNull SectionMapBuilder<MAP, K, V> parseKey(@NotNull DataFunction<String, K> keyParser) {
|
||||
return parseKey((holder, data) -> keyParser.handle(data));
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<MAP, K, V> parseKey(@NotNull ValueHandler<String, K> keyParser) {
|
||||
this.keyParser = keyParser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<MAP, K, V> serializeKey(@NotNull DataFunction<K, String> keySerializer) {
|
||||
return serializeKey((holder, data) -> keySerializer.handle(data));
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<MAP, K, V> serializeKey(@NotNull ValueHandler<K, String> keySerializer) {
|
||||
this.keySerializer = keySerializer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<MAP, K, V> defaults(@NotNull MAP defaults) {
|
||||
return defaults(() -> defaults);
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<MAP, K, V> defaults(@NotNull Consumer<MAP> defaults) {
|
||||
return defaults(() -> {
|
||||
MAP map = this.constructor.get();
|
||||
defaults.accept(map);
|
||||
return map;
|
||||
});
|
||||
}
|
||||
|
||||
public @NotNull ValueAdapter<K> buildKeyAdapter() {
|
||||
return new ValueAdapter<>(this.keyType)
|
||||
.parser((holder, type, data) -> {
|
||||
String source = holder.deserialize(String.class, data);
|
||||
return this.keyParser.handle(holder, source);
|
||||
})
|
||||
.serializer((holder, type, data) -> {
|
||||
String source = this.keySerializer.handle(holder, data);
|
||||
return holder.serialize(source);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfiguredMap<K, V> build() {
|
||||
return new ConfiguredMap<>(buildManifest(), this.constructor, buildKeyAdapter(), this.buildAdapter());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package cc.carm.lib.configuration.builder.map;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.impl.AbstractSourceBuilder;
|
||||
import cc.carm.lib.configuration.function.DataFunction;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SourceMapBuilder<MAP extends Map<K, V>, SOURCE, K, V>
|
||||
extends AbstractSourceBuilder<
|
||||
Map<K, V>, SOURCE, V, ConfiguredMap<K, V>,
|
||||
SourceMapBuilder<MAP, SOURCE, K, V>
|
||||
> {
|
||||
|
||||
protected final @NotNull ValueType<K> keyType;
|
||||
|
||||
protected @NotNull Supplier<? extends MAP> constructor;
|
||||
protected @NotNull ValueHandler<String, K> keyParser;
|
||||
protected @NotNull ValueHandler<K, String> keySerializer;
|
||||
|
||||
public SourceMapBuilder(@NotNull Supplier<? extends MAP> constructor, @NotNull ValueType<SOURCE> sourceType,
|
||||
@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType,
|
||||
@NotNull ValueHandler<String, K> keyParser, @NotNull ValueHandler<K, String> keySerializer,
|
||||
@NotNull ValueHandler<SOURCE, V> valueParser, @NotNull ValueHandler<V, SOURCE> valueSerializer) {
|
||||
super(new ValueType<Map<K, V>>() {
|
||||
}, sourceType, valueType, valueParser, valueSerializer);
|
||||
this.keyType = keyType;
|
||||
this.constructor = constructor;
|
||||
this.keyParser = keyParser;
|
||||
this.keySerializer = keySerializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull SourceMapBuilder<MAP, SOURCE, K, V> self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> defaults(@NotNull MAP defaults) {
|
||||
return defaults(() -> defaults);
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> defaults(@NotNull Consumer<MAP> defaults) {
|
||||
return defaults(() -> {
|
||||
MAP map = this.constructor.get();
|
||||
defaults.accept(map);
|
||||
return map;
|
||||
});
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> parseKey(@NotNull DataFunction<String, K> keyParser) {
|
||||
return parseKey((holder, data) -> keyParser.handle(data));
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> parseKey(@NotNull ValueHandler<String, K> keyParser) {
|
||||
this.keyParser = keyParser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> serializeKey(@NotNull DataFunction<K, String> keySerializer) {
|
||||
return serializeKey((holder, data) -> keySerializer.handle(data));
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> serializeKey(@NotNull ValueHandler<K, String> keySerializer) {
|
||||
this.keySerializer = keySerializer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NotNull ValueAdapter<K> buildKeyAdapter() {
|
||||
return new ValueAdapter<>(this.keyType)
|
||||
.parser((holder, type, data) -> {
|
||||
String source = holder.deserialize(String.class, data);
|
||||
return this.keyParser.handle(holder, source);
|
||||
})
|
||||
.serializer((holder, type, data) -> {
|
||||
String source = this.keySerializer.handle(holder, data);
|
||||
return holder.serialize(source);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfiguredMap<K, V> build() {
|
||||
return new ConfiguredMap<>(buildManifest(), this.constructor, buildKeyAdapter(), this.buildAdapter());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package cc.carm.lib.configuration.builder.value;
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
|
||||
import cc.carm.lib.configuration.function.ValueHandler;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -20,7 +21,7 @@ public class ConfigValueBuilder<V> {
|
||||
}
|
||||
|
||||
public @NotNull <S> SourceValueBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
|
||||
return from(sourceType, ValueHandler.required(), ValueHandler.required());
|
||||
return from(sourceType, ValueHandler.required(type), ValueHandler.required(sourceType));
|
||||
}
|
||||
|
||||
public @NotNull <S> SourceValueBuilder<S, V> from(@NotNull ValueType<S> sourceType,
|
||||
@@ -30,11 +31,11 @@ public class ConfigValueBuilder<V> {
|
||||
}
|
||||
|
||||
public @NotNull SourceValueBuilder<String, V> fromString() {
|
||||
return from(ValueType.STRING, ValueHandler.required(), ValueHandler.stringValue());
|
||||
return from(ValueType.STRING, ValueHandler.required(type), ValueHandler.stringValue());
|
||||
}
|
||||
|
||||
public @NotNull SectionValueBuilder<V> fromSection() {
|
||||
return fromSection(ValueHandler.required(), ValueHandler.required());
|
||||
return fromSection(ValueHandler.required(type), ValueHandler.required());
|
||||
}
|
||||
|
||||
public @NotNull SectionValueBuilder<V> fromSection(
|
||||
|
||||
@@ -56,17 +56,24 @@ public interface ValueHandler<T, R> {
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T> @NotNull ValueHandler<Object, T> fromObject(ValueType<T> type) {
|
||||
return (provider, input) -> provider.deserialize(type, input);
|
||||
static <O, T> @NotNull ValueHandler<O, T> deserialize(ValueType<T> to) {
|
||||
return (provider, input) -> provider.deserialize(to, input);
|
||||
}
|
||||
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T, V> @NotNull ValueHandler<T, V> required() {
|
||||
return (provider, input) -> {
|
||||
throw new IllegalArgumentException("Please specify the value parser.");
|
||||
};
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
static <T, V> @NotNull ValueHandler<T, V> required(ValueType<V> type) {
|
||||
return (provider, input) -> {
|
||||
if (type.isInstance(input)) return type.cast(input); // Simple cast
|
||||
throw new IllegalArgumentException("Please specify the value parser.");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||
import cc.carm.lib.configuration.adapter.ValueParser;
|
||||
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
||||
import cc.carm.lib.configuration.adapter.ValueType;
|
||||
import cc.carm.lib.configuration.builder.map.ConfigMapCreator;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import cc.carm.lib.configuration.value.ValueManifest;
|
||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
||||
@@ -18,12 +19,26 @@ import java.util.function.Supplier;
|
||||
|
||||
public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements Map<K, V> {
|
||||
|
||||
public static <K, V> ConfigMapCreator<K, V> builderOf(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
|
||||
return new ConfigMapCreator<>(keyType, valueType);
|
||||
}
|
||||
|
||||
public static <K, V> ConfigMapCreator<K, V> builderOf(@NotNull Class<K> keyType, @NotNull Class<V> valueType) {
|
||||
return new ConfigMapCreator<>(ValueType.of(keyType), ValueType.of(valueType));
|
||||
}
|
||||
|
||||
public static <K, V> ConfiguredMap<K, V> of(@NotNull Supplier<? extends Map<K, V>> constructor,
|
||||
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
|
||||
return new ConfiguredMap<>(new ValueManifest<>(new ValueType<Map<K, V>>() {
|
||||
}, constructor::get), constructor, keyAdapter, valueAdapter);
|
||||
}
|
||||
|
||||
protected final @NotNull Supplier<? extends Map<K, V>> constructor;
|
||||
|
||||
protected final @NotNull ValueAdapter<K> keyAdapter;
|
||||
protected final @NotNull ValueAdapter<V> valueAdapter;
|
||||
|
||||
protected ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
||||
public ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest,
|
||||
@NotNull Supplier<? extends Map<K, V>> constructor,
|
||||
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
|
||||
super(manifest);
|
||||
@@ -88,7 +103,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
|
||||
return get().get(key);
|
||||
}
|
||||
|
||||
public V getNotNull(Object key) {
|
||||
public V getNotNull(@Nullable K key) {
|
||||
return Objects.requireNonNull(get(key));
|
||||
}
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ public class ConfigurationTest {
|
||||
System.out.println(" After size :" + DemoConfiguration.SUB.That.OPERATORS.size());
|
||||
|
||||
System.out.println("> Test Section:");
|
||||
System.out.println(DemoConfiguration.USERS.get());
|
||||
DemoConfiguration.USERS.add(UserRecord.random());
|
||||
System.out.println(DemoConfiguration.ALLOWLISTS.get());
|
||||
DemoConfiguration.ALLOWLISTS.add(UserRecord.random());
|
||||
|
||||
// System.out.println("> Test Maps:");
|
||||
// DemoConfiguration.USERS.forEach((k, v) -> System.out.println(k + ": " + v));
|
||||
|
||||
+24
-8
@@ -6,18 +6,26 @@ import cc.carm.lib.configuration.annotation.FooterComments;
|
||||
import cc.carm.lib.configuration.annotation.HeaderComments;
|
||||
import cc.carm.lib.configuration.annotation.InlineComment;
|
||||
import cc.carm.lib.configuration.demo.DatabaseConfiguration;
|
||||
import cc.carm.lib.configuration.demo.tests.model.ItemStack;
|
||||
import cc.carm.lib.configuration.demo.tests.model.UserRecord;
|
||||
import cc.carm.lib.configuration.value.ConfigValue;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@ConfigPath(root = true)
|
||||
@HeaderComments({"此处内容将显示在配置文件的最上方"})
|
||||
@FooterComments({"此处内容将显示在配置文件的最下方", "可用于显示版权信息等"})
|
||||
@FooterComments({
|
||||
"------------------------------------------------",
|
||||
"此处内容将显示在配置文件的最下方",
|
||||
"可用于显示版权信息等",
|
||||
"感谢您使用 https://github.com/CarmJos/EasyConfiguration !"
|
||||
})
|
||||
public interface DemoConfiguration extends Configuration {
|
||||
|
||||
@ConfigPath(root = true)
|
||||
@@ -40,16 +48,24 @@ public interface DemoConfiguration extends Configuration {
|
||||
@InlineComment("默认地注释会加到Section的首行末尾") // 通过注解给配置添加注释。
|
||||
@InlineComment(value = "用户名(匹配注释)", regex = "name") // 通过注解给配置添加注释。
|
||||
@InlineComment(value = "信息", regex = "info.*") // 通过注解给配置添加注释。
|
||||
ConfiguredList<UserRecord> USERS = ConfiguredList.builderOf(UserRecord.class).fromSection()
|
||||
ConfiguredList<UserRecord> ALLOWLISTS = ConfiguredList.builderOf(UserRecord.class).fromSection()
|
||||
.parse(UserRecord::deserialize).serialize(UserRecord::serialize)
|
||||
.defaults(UserRecord.CARM).build();
|
||||
|
||||
// @HeaderComment({"[ID - UUID]对照表", "", "用于测试Map类型的解析与序列化保存"})
|
||||
// ConfiguredMap<Integer, UUID> USERS = ConfiguredMap.builderOf(Integer.class, UUID.class)
|
||||
// .asLinkedMap().fromString()
|
||||
// .parseKey(Integer::parseInt)
|
||||
// .parseValue(v -> Objects.requireNonNull(UUID.fromString(v)))
|
||||
// .build();
|
||||
@HeaderComments({
|
||||
"------------------------------------------------",
|
||||
"[ID - ItemStack]对照表", "", "用于测试Map类型的解析与序列化保存"
|
||||
})
|
||||
@FooterComments("------------------------------------------------")
|
||||
ConfiguredMap<Integer, ItemStack> ITEMS = ConfiguredMap.builderOf(Integer.class, ItemStack.class)
|
||||
.asLinkedMap().fromSection()
|
||||
.parseKey(data -> Integer.parseInt(data))
|
||||
.parse(ItemStack::deserialize).serialize(ItemStack::serialize)
|
||||
.defaults(m -> {
|
||||
m.put(1, new ItemStack("stone", 64));
|
||||
m.put(2, new ItemStack("iron", 64, "铁锭", Arrays.asList("一些铁锭", "可以制造东西")));
|
||||
})
|
||||
.build();
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package cc.carm.lib.configuration.demo.tests.model;
|
||||
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ItemStack {
|
||||
|
||||
protected String material;
|
||||
protected int amount;
|
||||
protected @Nullable String name;
|
||||
protected @Nullable List<String> lore;
|
||||
|
||||
public ItemStack(String material, int amount) {
|
||||
this(material, amount, null, null);
|
||||
}
|
||||
|
||||
public ItemStack(String material, int amount, @Nullable String name, @Nullable List<String> lore) {
|
||||
this.material = material;
|
||||
this.amount = amount;
|
||||
this.name = name;
|
||||
this.lore = lore;
|
||||
}
|
||||
|
||||
public String getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<String> getLore() {
|
||||
return lore;
|
||||
}
|
||||
|
||||
public void setMaterial(String material) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public void setAmount(int amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setLore(List<String> lore) {
|
||||
this.lore = lore;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("material", material);
|
||||
if (amount != 1) map.put("amount", amount);
|
||||
if (name != null) map.put("name", name);
|
||||
if (lore != null) map.put("lore", lore);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static ItemStack deserialize(ConfigureSection section) {
|
||||
return new ItemStack(
|
||||
section.getString("material"),
|
||||
section.getInt("amount", 1),
|
||||
section.getString("name"),
|
||||
section.getStringList("lore")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user