1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2026-06-04 18:48:20 +08:00

refactor(builder): Refactor builder functions to support custom adapters.

This commit is contained in:
2025-09-27 00:55:38 +08:00
parent cb7562cd8c
commit c86985017f
25 changed files with 116 additions and 37 deletions
+1 -1
Submodule .wiki updated: 66ace40bbc...7314c2134f
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.7</version> <version>4.1.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<properties> <properties>
@@ -20,6 +20,7 @@ import java.util.Objects;
*/ */
public abstract class ValueType<T> { public abstract class ValueType<T> {
public static final ValueType<Object> OBJECT = ofPrimitiveType(Object.class);
public static final ValueType<String> STRING = ofPrimitiveType(String.class); public static final ValueType<String> STRING = ofPrimitiveType(String.class);
public static final ValueType<Integer> INTEGER = ofPrimitiveType(Integer.class); public static final ValueType<Integer> INTEGER = ofPrimitiveType(Integer.class);
public static final ValueType<Integer> INTEGER_TYPE = ofPrimitiveType(int.class); public static final ValueType<Integer> INTEGER_TYPE = ofPrimitiveType(int.class);
@@ -1,6 +1,8 @@
package cc.carm.lib.configuration.builder.impl; package cc.carm.lib.configuration.builder.impl;
import cc.carm.lib.configuration.adapter.ValueAdapter; 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.adapter.ValueType;
import cc.carm.lib.configuration.builder.CommonConfigBuilder; import cc.carm.lib.configuration.builder.CommonConfigBuilder;
import cc.carm.lib.configuration.function.DataFunction; import cc.carm.lib.configuration.function.DataFunction;
@@ -15,8 +17,11 @@ public abstract class AbstractSourceBuilder<
protected final @NotNull ValueType<SOURCE> sourceType; protected final @NotNull ValueType<SOURCE> sourceType;
protected final @NotNull ValueType<UNIT> paramType; protected final @NotNull ValueType<UNIT> paramType;
protected @NotNull ValueHandler<SOURCE, UNIT> valueParser;
protected @NotNull ValueHandler<UNIT, SOURCE> valueSerializer; @SuppressWarnings("NotNullFieldNotInitialized") // Already initialized in constructor
protected @NotNull ValueParser<UNIT> valueParser;
@SuppressWarnings("NotNullFieldNotInitialized") // Already initialized in constructor
protected @NotNull ValueSerializer<UNIT> valueSerializer;
protected AbstractSourceBuilder(@NotNull ValueType<V> type, protected AbstractSourceBuilder(@NotNull ValueType<V> type,
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<UNIT> paramType, @NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<UNIT> paramType,
@@ -25,8 +30,8 @@ public abstract class AbstractSourceBuilder<
super(type); super(type);
this.sourceType = sourceType; this.sourceType = sourceType;
this.paramType = paramType; this.paramType = paramType;
this.valueParser = parser; parse(parser);
this.valueSerializer = serializer; serialize(serializer);
} }
public @NotNull SELF parse(@NotNull DataFunction<SOURCE, UNIT> parser) { public @NotNull SELF parse(@NotNull DataFunction<SOURCE, UNIT> parser) {
@@ -34,29 +39,35 @@ public abstract class AbstractSourceBuilder<
} }
public @NotNull SELF parse(@NotNull ValueHandler<SOURCE, UNIT> parser) { public @NotNull SELF parse(@NotNull ValueHandler<SOURCE, UNIT> parser) {
return parser((holder, type, data) -> {
SOURCE source = holder.deserialize(this.sourceType, data);
return parser.handle(holder, source);
});
}
public @NotNull SELF parser(@NotNull ValueParser<UNIT> parser) {
this.valueParser = parser; this.valueParser = parser;
return self(); return self();
} }
public @NotNull SELF serialize(@NotNull ValueHandler<UNIT, SOURCE> serializer) { public @NotNull SELF serialize(@NotNull ValueHandler<UNIT, SOURCE> serializer) {
this.valueSerializer = serializer; return serializer((holder, type, data) -> {
return self(); SOURCE source = serializer.handle(holder, data);
return holder.serialize(source);
});
} }
public @NotNull SELF serialize(@NotNull DataFunction<UNIT, SOURCE> serializer) { public @NotNull SELF serialize(@NotNull DataFunction<UNIT, SOURCE> serializer) {
return serialize((p, value) -> serializer.handle(value)); return serialize((p, value) -> serializer.handle(value));
} }
public @NotNull SELF serializer(@NotNull ValueSerializer<UNIT> serializer) {
this.valueSerializer = serializer;
return self();
}
protected ValueAdapter<UNIT> buildAdapter() { protected ValueAdapter<UNIT> buildAdapter() {
return new ValueAdapter<>(this.paramType) return new ValueAdapter<>(this.paramType, this.valueSerializer, this.valueParser);
.parser((holder, type, data) -> {
SOURCE source = holder.deserialize(this.sourceType, data);
return this.valueParser.handle(holder, source);
})
.serializer((holder, type, data) -> {
SOURCE source = this.valueSerializer.handle(holder, data);
return holder.serialize(source);
});
} }
@@ -26,6 +26,13 @@ public class ConfigListBuilder<V> {
); );
} }
public @NotNull SourceListBuilder<Object, V> fromObject() {
return new SourceListBuilder<>(
ArrayList::new, ValueType.OBJECT, type,
ValueHandler.deserialize(type), ValueHandler.toObject()
);
}
public @NotNull SourceListBuilder<String, V> fromString() { public @NotNull SourceListBuilder<String, V> fromString() {
return new SourceListBuilder<>( return new SourceListBuilder<>(
ArrayList::new, ValueType.STRING, type, ArrayList::new, ValueType.STRING, type,
@@ -49,6 +49,15 @@ public class ConfigMapBuilder<M extends Map<K, V>, K, V> {
); );
} }
public @NotNull <S> SourceMapBuilder<M, Object, K, V> fromObject() {
return from(
ValueType.OBJECT,
ValueHandler.deserialize(keyType), ValueHandler.stringValue(),
ValueHandler.deserialize(valueType), ValueHandler.toObject()
);
}
public @NotNull SourceMapBuilder<M, String, K, V> fromString() { public @NotNull SourceMapBuilder<M, String, K, V> fromString() {
return from( return from(
ValueType.STRING, ValueType.STRING,
@@ -26,12 +26,12 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
return new ConfigListBuilder<>(type); return new ConfigListBuilder<>(type);
} }
public static <T> @NotNull SourceListBuilder<T, T> with(@NotNull Class<T> registeredType) { public static <T> @NotNull SourceListBuilder<Object, T> with(@NotNull Class<T> registeredType) {
return with(ValueType.of(registeredType)); return with(ValueType.of(registeredType));
} }
public static <T> @NotNull SourceListBuilder<T, T> with(@NotNull ValueType<T> registeredType) { public static <T> @NotNull SourceListBuilder<Object, T> with(@NotNull ValueType<T> registeredType) {
return new ConfigListBuilder<>(registeredType).from(registeredType); return new ConfigListBuilder<>(registeredType).fromObject();
} }
@SafeVarargs @SafeVarargs
@@ -5,6 +5,7 @@ import cc.carm.lib.configuration.adapter.ValueParser;
import cc.carm.lib.configuration.adapter.ValueSerializer; import cc.carm.lib.configuration.adapter.ValueSerializer;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.map.ConfigMapCreator; import cc.carm.lib.configuration.builder.map.ConfigMapCreator;
import cc.carm.lib.configuration.builder.map.SourceMapBuilder;
import cc.carm.lib.configuration.source.section.ConfigureSection; import cc.carm.lib.configuration.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.ValueManifest; import cc.carm.lib.configuration.value.ValueManifest;
import cc.carm.lib.configuration.value.impl.CachedConfigValue; import cc.carm.lib.configuration.value.impl.CachedConfigValue;
@@ -31,6 +32,16 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> impleme
return new ConfigMapCreator<>(ValueType.of(keyType), ValueType.of(valueType)); return new ConfigMapCreator<>(ValueType.of(keyType), ValueType.of(valueType));
} }
public static @NotNull <K, V>
SourceMapBuilder<LinkedHashMap<K, V>, Object, K, V> with(@NotNull Class<K> keyType, @NotNull Class<V> valueType) {
return with(ValueType.of(keyType), ValueType.of(valueType));
}
public static @NotNull <K, V>
SourceMapBuilder<LinkedHashMap<K, V>, Object, K, V> with(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
return new ConfigMapCreator<>(keyType, valueType).asLinkedMap().fromObject();
}
public static <K, V> ConfiguredMap<K, V> of(@NotNull Supplier<? extends Map<K, V>> constructor, public static <K, V> ConfiguredMap<K, V> of(@NotNull Supplier<? extends Map<K, V>> constructor,
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) { @NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
return new ConfiguredMap<>(new ValueManifest<>(new ValueType<Map<K, V>>() { return new ConfiguredMap<>(new ValueManifest<>(new ValueType<Map<K, V>>() {
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.7</version> <version>4.1.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
@@ -2,6 +2,8 @@ import cc.carm.lib.configuration.Configuration;
import cc.carm.lib.configuration.annotation.ConfigPath; import cc.carm.lib.configuration.annotation.ConfigPath;
import cc.carm.lib.configuration.source.ConfigurationHolder; import cc.carm.lib.configuration.source.ConfigurationHolder;
import cc.carm.lib.configuration.source.temp.TempConfigFactory; import cc.carm.lib.configuration.source.temp.TempConfigFactory;
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 cc.carm.lib.configuration.value.standard.ConfiguredValue;
import cc.carm.lib.configured.adapter.record.RecordAdapter; import cc.carm.lib.configured.adapter.record.RecordAdapter;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -32,6 +34,18 @@ public class RecordTest {
) )
)); ));
ConfiguredMap<String, Device> DEVICES = ConfiguredMap.builderOf(Device.class)
.asHashMap().fromObject()
.defaults(m -> {
Device d = randomDevice();
m.put(d.id, d);
})
.build();
ConfiguredList<Device> DEVICE_LIST = ConfiguredList.with(Device.class)
.defaults(Arrays.asList(randomDevice(), randomDevice()))
.build();
} }
@ConfigPath(root = true) @ConfigPath(root = true)
@@ -58,6 +72,15 @@ public class RecordTest {
printMap(holder.config().asMap(), 0); printMap(holder.config().asMap(), 0);
ConfigA.DEVICES.forEach((k, v) -> {
System.out.println("Device Key: " + k + ", ID: " + v.id + ", Name: " + v.name);
});
ConfigA.DEVICE_LIST.forEach((v) -> {
System.out.println("Device ID: " + v.id + ", Name: " + v.name);
});
// try { // try {
// List<User> parsed = holder.deserialize(ValueType.ofList(User.class), holder.config().getList("val.users")); // List<User> parsed = holder.deserialize(ValueType.ofList(User.class), holder.config().getList("val.users"));
// System.out.println("Parsed Users: " + parsed); // System.out.println("Parsed Users: " + parsed);
@@ -101,6 +124,23 @@ public class RecordTest {
record Chip(String id, @Nullable String serialNumber) { record Chip(String id, @Nullable String serialNumber) {
} }
public static Device randomDevice() {
return new Device(
"device-" + UUID.randomUUID(),
"Device " + (int) (Math.random() * 100),
UUID.randomUUID(),
new Chip("chip-" + UUID.randomUUID(), "SN" + (int) (Math.random() * 10000)),
Arrays.asList(
new User("User" + (int) (Math.random() * 100), (int) (Math.random() * 50 + 10)),
new User("User" + (int) (Math.random() * 100), (int) (Math.random() * 50 + 10))
),
Map.of(
"Cloud", new Connection("cloud.example.com", 443),
"Local", new Connection("192.168.1." + (int) (Math.random() * 255), 8080)
)
);
}
static void printMap(Map<String, Object> map, int indent) { static void printMap(Map<String, Object> map, int indent) {
String indentStr = " ".repeat(indent); String indentStr = " ".repeat(indent);
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -16,7 +16,7 @@
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>4.1.7</version> <version>4.1.8</version>
<modules> <modules>
<module>core</module> <module>core</module>
<module>features/section</module> <module>features/section</module>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.7</version> <version>4.1.8</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>