1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2026-06-04 10:38:19 +08:00

feat(adapter): Support complex ParameterizedType's serialize & deserialize.

This commit is contained in:
2025-06-25 09:31:07 +08:00
parent 608d92f834
commit 8c1214612a
23 changed files with 213 additions and 57 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
@@ -38,10 +38,14 @@ public class RecordAdapter<T extends Record> extends ValueAdapter<T> {
return (holder, type1, r) -> toMap(holder, r);
}
@SuppressWarnings("unchecked")
public static <R extends Record> ValueParser<R> parser(@NotNull ValueType<R> type) {
return (holder, valueType, value) -> {
if (!(value instanceof ConfigureSection section)) return null;
return fromMap(holder, type.getRawType(), section.asMap());
if (value instanceof ConfigureSection section) {
return fromMap(holder, (Class<R>) valueType.getRawType(), section.asMap());
} else if (value instanceof Map<?, ?> map) {
return fromMap(holder, (Class<R>) valueType.getRawType(), (Map<String, Object>) map);
} else return null;
};
}
@@ -57,6 +61,7 @@ public class RecordAdapter<T extends Record> extends ValueAdapter<T> {
for (RecordComponent component : recordClass.getRecordComponents()) {
String name = component.getName();
Method accessor = component.getAccessor();
accessor.setAccessible(true);
Object value = accessor.invoke(record);
map.put(name, serializeValue(holder, value));
}
@@ -74,18 +79,19 @@ public class RecordAdapter<T extends Record> extends ValueAdapter<T> {
Object[] args = new Object[components.length];
for (int i = 0; i < components.length; i++) {
RecordComponent component = components[i];
args[i] = parseValue(holder, component.getType(), data.get(component.getName()));
args[i] = parseValue(holder, component, data.get(component.getName()));
}
return createInstance(type, args);
}
@SuppressWarnings("unchecked")
private static Object parseValue(ConfigurationHolder<?> holder, Class<?> targetType, Object value) throws Exception {
private static Object parseValue(ConfigurationHolder<?> holder, RecordComponent component, Object value) throws Exception {
if (value == null) return null;
if (targetType.isRecord()) {
return fromMap(holder, targetType.asSubclass(Record.class), (Map<String, Object>) value);
if (component.getType().isRecord()) {
return fromMap(holder, component.getType().asSubclass(Record.class), (Map<String, Object>) value);
}
return holder.deserialize(targetType, value);
ValueType<?> valueType = ValueType.of(component.getGenericType());
return holder.deserialize(valueType, value);
}
private static Object serializeValue(ConfigurationHolder<?> holder, Object value) throws Exception {
+55 -17
View File
@@ -1,57 +1,94 @@
import cc.carm.lib.configuration.Configuration;
import cc.carm.lib.configuration.annotation.ConfigPath;
import cc.carm.lib.configuration.source.ConfigurationHolder;
import cc.carm.lib.configuration.source.temp.TempConfigFactory;
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
import cc.carm.lib.configured.adapter.record.RecordAdapter;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class RecordTest {
interface Config extends Configuration {
@ConfigPath(root = true)
interface ConfigA extends Configuration {
ConfiguredValue<Device> VAL = ConfiguredValue.of(new Device(
"device1",
"My Device",
UUID.fromString("123e4567-e89b-12d3-a456-426614174000"),
new Chip("chip1", "SN123456")
new Chip("chip1", "SN123456"),
Arrays.asList(
new User("Alice", 30),
new User("Bob", 25)
)
));
}
@ConfigPath(root = true)
interface ConfigB extends Configuration {
ConfiguredValue<Device> VAL = ConfiguredValue.of(Device.class);
}
@Test
public void test() {
ConfigurationHolder<?> holder = TempConfigFactory.create().build();
RecordAdapter.register(holder);
holder.initialize(Config.class);
holder.initialize(ConfigA.class);
System.out.println("Device ID: " + Config.VAL.resolve().id());
System.out.println("Device Name: " + Config.VAL.resolve().name());
System.out.println("Device Serial: " + Config.VAL.resolve().serial());
System.out.println("Chip ID: " + Config.VAL.resolve().chip().id());
System.out.println("Chip Serial: " + Config.VAL.resolve().chip().serialNumber());
try {
holder.save();
} catch (Exception e) {
throw new RuntimeException(e);
System.out.println("Device ID: " + ConfigA.VAL.resolve().id());
System.out.println("Device Name: " + ConfigA.VAL.resolve().name());
System.out.println("Device Serial: " + ConfigA.VAL.resolve().serial());
System.out.println("Chip ID: " + ConfigA.VAL.resolve().chip().id());
System.out.println("Chip Serial: " + ConfigA.VAL.resolve().chip().serialNumber());
for (User user : ConfigA.VAL.resolve().users()) {
System.out.println("Another Users: " + user.name() + ", Age: " + user.age());
}
// printMap(holder.config().asMap(), 0);
// try {
// List<User> parsed = holder.deserialize(ValueType.ofList(User.class), holder.config().getList("val.users"));
// System.out.println("Parsed Users: " + parsed);
// } catch (Exception e) {
// e.printStackTrace();
// }
ConfigurationHolder<?> anotherHolder = TempConfigFactory.create().defaults(() -> holder.config().asMap()).build();
RecordAdapter.register(anotherHolder);
anotherHolder.initialize(ConfigB.class);
System.out.println("Another Device ID: " + ConfigB.VAL.resolve().id());
System.out.println("Another Device Name: " + ConfigB.VAL.resolve().name());
System.out.println("Another Device Serial: " + ConfigB.VAL.resolve().serial());
System.out.println("Another Chip ID: " + ConfigB.VAL.resolve().chip().id());
System.out.println("Another Chip Serial: " + ConfigB.VAL.resolve().chip().serialNumber());
System.out.println("users: " + ConfigB.VAL.resolve().users().size());
for (User user : ConfigB.VAL.resolve().users()) {
System.out.println("Another Users: " + user.name() + ", Age: " + user.age());
}
printMap(holder.config().asMap(), 0);
}
public record Device(String id, String name, UUID serial, Chip chip) {
record User(String name, int age) {
}
public record Chip(String id, String serialNumber) {
record Device(String id, String name, UUID serial, Chip chip, List<User> users) {
}
record Chip(String id, String serialNumber) {
}
static void printMap(Map<String, Object> map, int indent) {
String indentStr = " ".repeat(indent);
for (Map.Entry<String, Object> entry : map.entrySet()) {
@@ -62,6 +99,7 @@ public class RecordTest {
System.out.println(indentStr + entry.getKey() + ":");
for (Object item : subList) {
if (item instanceof Map<?, ?> itemMap) {
System.out.println(indentStr + " - ");
printMap((Map<String, Object>) itemMap, indent + 2);
} else {
System.out.println(indentStr + " - " + item);
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.6</version>
<version>4.1.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>