diff --git a/core/src/main/java/cc/carm/lib/configuration/core/ConfigInitializer.java b/core/src/main/java/cc/carm/lib/configuration/core/ConfigInitializer.java index 0638a65..3918dc7 100644 --- a/core/src/main/java/cc/carm/lib/configuration/core/ConfigInitializer.java +++ b/core/src/main/java/cc/carm/lib/configuration/core/ConfigInitializer.java @@ -8,8 +8,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Optional; public class ConfigInitializer> { @@ -19,94 +17,116 @@ public class ConfigInitializer> { this.provider = provider; } - public void initialize(Class rootClazz) { - initialize(rootClazz, true); + public void initialize(@NotNull Class clazz, boolean saveDefaults) { + initializeClass(clazz, null, null, null, null, saveDefaults); } - public void initialize(Class rootClazz, boolean saveDefault) { - String rootSection = null; - - ConfigPath sectionAnnotation = rootClazz.getAnnotation(ConfigPath.class); - if (sectionAnnotation != null && sectionAnnotation.value().length() > 1) { - rootSection = sectionAnnotation.value(); + protected void initializeClass(@NotNull Class clazz, + @Nullable String parentPath, @Nullable String fieldName, + @Nullable ConfigPath fieldPath, @Nullable ConfigComment filedComments, + boolean saveDefaults) { + if (!ConfigurationRoot.class.isAssignableFrom(clazz)) return; + String path = getClassPath(clazz, parentPath, fieldName, fieldPath); + if (path != null) setComments(path, getClassComments(clazz, filedComments)); + for (Field field : clazz.getDeclaredFields()) { + initializeField(clazz, field, path, saveDefaults); } - - if (rootSection != null) { - //Not usable for null section. - ConfigComment comments = rootClazz.getAnnotation(ConfigComment.class); - if (comments != null && comments.value().length > 0) { - provider.setComments(rootSection, comments.value()); - } - } - - for (Class innerClass : rootClazz.getDeclaredClasses()) { - initSection(rootSection, innerClass, saveDefault); - } - - for (Field field : rootClazz.getDeclaredFields()) { - initValue(rootSection, rootClazz, field, saveDefault); - } - - if (saveDefault) { - try { - provider.save(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - private void initSection(String parentSection, Class clazz, boolean saveDefault) { - if (!Modifier.isStatic(clazz.getModifiers()) || !Modifier.isPublic(clazz.getModifiers())) return; - - String section = getSectionPath(clazz.getSimpleName(), parentSection, clazz.getAnnotation(ConfigPath.class)); - ConfigComment comments = clazz.getAnnotation(ConfigComment.class); - if (comments != null && comments.value().length > 0) { - provider.setComments(parentSection, comments.value()); - } - - for (Field field : clazz.getDeclaredFields()) initValue(section, clazz, field, saveDefault); - for (Class innerClass : clazz.getDeclaredClasses()) initSection(section, innerClass, saveDefault); + protected void initializeValue(@NotNull ConfigValue value, @NotNull String path, + @NotNull String[] comments, boolean saveDefaults) { + value.initialize(provider, saveDefaults, path, comments); } - private void initValue(String parentSection, Class clazz, Field field, boolean saveDefault) { + private void initializeField(@NotNull Class source, @NotNull Field field, + @Nullable String parent, boolean saveDefaults) { + try { field.setAccessible(true); - Object object = field.get(clazz); + Object object = field.get(source); if (object instanceof ConfigValue) { - initializeValue( - (ConfigValue) object, saveDefault, - getSectionPath(field.getName(), parentSection, field.getAnnotation(ConfigPath.class)), - Optional.ofNullable(field.getAnnotation(ConfigComment.class)) - .map(ConfigComment::value).orElse(new String[0]) + String path = getFieldPath(field, parent); + String[] comments = readComments(field.getAnnotation(ConfigComment.class)); + initializeValue((ConfigValue) object, path, comments, saveDefaults); + setComments(path, comments); + } else if (object instanceof Class) { + initializeClass( + (Class) object, parent, field.getName(), + field.getAnnotation(ConfigPath.class), + field.getAnnotation(ConfigComment.class), + saveDefaults ); } } catch (IllegalAccessException ignored) { } } - - public void initializeValue(@NotNull ConfigValue value, boolean saveDefault, - @NotNull String path, @NotNull String[] comments) { - value.initialize(provider, path, comments); - if (saveDefault && value.getDefaultValue() != null && !provider.getConfiguration().contains(path)) { - value.setDefault(); - } + protected void setComments(@NotNull String path, @Nullable ConfigComment filedComments) { + setComments(path, readComments(filedComments)); } - public static String getSectionPath(@NotNull String name, - @Nullable String parentSection, - @Nullable ConfigPath pathAnnotation) { - @NotNull String parent = parentSection != null ? parentSection + "." : ""; - @NotNull String path = getSectionName(name); - boolean root = false; - if (pathAnnotation != null) { - if (pathAnnotation.value().length() > 0) path = pathAnnotation.value(); - root = pathAnnotation.root(); + protected void setComments(@NotNull String path, @NotNull String[] comments) { + if (comments.length <= 0) return; + this.provider.setComments(path, comments); + } + + protected static @NotNull String[] readComments(@Nullable ConfigComment filedComments) { + if (filedComments == null) return new String[0]; + if (String.join("", filedComments.value()).length() <= 0) return new String[0]; + return filedComments.value(); + } + + protected static @NotNull String[] getClassComments(@NotNull Class clazz, + @Nullable ConfigComment fieldAnnotation) { + String[] clazzComments = readComments(clazz.getAnnotation(ConfigComment.class)); + if (clazzComments.length > 0) return clazzComments; + else return readComments(fieldAnnotation); + } + + protected static @Nullable String getClassPath(@NotNull Class clazz, + @Nullable String parentPath, + @Nullable String filedName, + @Nullable ConfigPath fieldAnnotation) { + @NotNull String parent = parentPath != null ? parentPath + "." : ""; + boolean fromRoot = false; + + // 先获取 Class 对应的路径注解 其优先度最高。 + ConfigPath clazzAnnotation = clazz.getAnnotation(ConfigPath.class); + if (clazzAnnotation != null) { + fromRoot = clazzAnnotation.root(); + if (clazzAnnotation.value().length() > 0) { + return (fromRoot ? "" : parent) + clazzAnnotation.value(); + } } - return (root ? "" : parent) + path; + + if (fieldAnnotation != null) { + fromRoot = fromRoot || fieldAnnotation.root(); + if (fieldAnnotation.value().length() > 0) { + return (fromRoot ? "" : parent) + fieldAnnotation.value(); + } + } + + // 再由 fieldName 获取路径 + if (filedName != null) return (fromRoot ? "" : parent) + getPathFromName(filedName); + else return null; // 不满足上述条件 且 无 fieldName,则说明是根路径。 + } + + protected static @NotNull String getFieldPath(@NotNull Field field, @Nullable String parentPath) { + @NotNull String parent = parentPath != null ? parentPath + "." : ""; + boolean fromRoot = false; + + // 先获取 Field 对应的路径注解 其优先度最高。 + ConfigPath pathAnnotation = field.getAnnotation(ConfigPath.class); + if (pathAnnotation != null) { + fromRoot = pathAnnotation.root(); + if (pathAnnotation.value().length() > 0) { + return (fromRoot ? "" : parent) + pathAnnotation.value(); + } + } + + // 最后再通过 fieldName 自动生成路径 + return (fromRoot ? "" : parent) + getPathFromName(field.getName()); } /** @@ -116,7 +136,7 @@ public class ConfigInitializer> { * @param name 源名称 * @return 全小写,以“-”链接 的 路径名称 */ - public static String getSectionName(String name) { + public static String getPathFromName(String name) { return name.replaceAll("[A-Z]", "-$0") // 将驼峰转换为蛇形; .replaceAll("-(.*)", "$1") // 若首字母也为大写,则也会被转换,需要去掉第一个横线 .replaceAll("_-([A-Z])", "_$1") // 因为命名中可能包含 _,因此需要被特殊处理一下 diff --git a/core/src/main/java/cc/carm/lib/configuration/core/annotation/ConfigPath.java b/core/src/main/java/cc/carm/lib/configuration/core/annotation/ConfigPath.java index 5fb2b52..fa48e9b 100644 --- a/core/src/main/java/cc/carm/lib/configuration/core/annotation/ConfigPath.java +++ b/core/src/main/java/cc/carm/lib/configuration/core/annotation/ConfigPath.java @@ -16,7 +16,7 @@ public @interface ConfigPath { /** * 指定路径的值。 - * 若不指定,则会通过 {@link ConfigInitializer#getSectionName(String)}自动生成当前路径的值。 + * 若不指定,则会通过 {@link ConfigInitializer#getPathFromName(String)} 自动生成当前路径的值。 * * @return 路径的值 */ diff --git a/core/src/main/java/cc/carm/lib/configuration/core/source/ConfigurationProvider.java b/core/src/main/java/cc/carm/lib/configuration/core/source/ConfigurationProvider.java index 05b3fed..c0d786d 100644 --- a/core/src/main/java/cc/carm/lib/configuration/core/source/ConfigurationProvider.java +++ b/core/src/main/java/cc/carm/lib/configuration/core/source/ConfigurationProvider.java @@ -34,7 +34,11 @@ public abstract class ConfigurationProvider { public abstract @NotNull ConfigInitializer> getInitializer(); public void initialize(Class configClazz) { - getInitializer().initialize(configClazz, true); + initialize(configClazz, true); + } + + public void initialize(Class configClazz, boolean saveDefaults) { + getInitializer().initialize(configClazz, saveDefaults); } } diff --git a/core/src/main/java/cc/carm/lib/configuration/core/value/ConfigValue.java b/core/src/main/java/cc/carm/lib/configuration/core/value/ConfigValue.java index a082257..7bd8928 100644 --- a/core/src/main/java/cc/carm/lib/configuration/core/value/ConfigValue.java +++ b/core/src/main/java/cc/carm/lib/configuration/core/value/ConfigValue.java @@ -29,13 +29,12 @@ public abstract class ConfigValue { this.defaultValue = defaultValue; } - public void initialize(@NotNull ConfigurationProvider provider, @NotNull String configPath, @NotNull String... comments) { + public void initialize(@NotNull ConfigurationProvider provider, boolean saveDefault, + @NotNull String configPath, @NotNull String... comments) { if (this.provider == null) this.provider = provider; if (this.configPath == null) this.configPath = configPath; if (this.comments.length == 0) this.comments = comments; - - this.provider.setComments(this.configPath, this.comments); - get(); + if (saveDefault) setDefault(); } public @Nullable T getDefaultValue() { @@ -63,6 +62,11 @@ public abstract class ConfigValue { public abstract void set(@Nullable T value); public void setDefault() { + setDefault(false); + } + + public void setDefault(boolean override) { + if (!override && getConfiguration().contains(getConfigPath())) return; Optional.ofNullable(getDefaultValue()).ifPresent(this::set); } diff --git a/core/src/test/java/NameTest.java b/core/src/test/java/NameTest.java index b1d935e..e3eaab8 100644 --- a/core/src/test/java/NameTest.java +++ b/core/src/test/java/NameTest.java @@ -7,10 +7,10 @@ public class NameTest { @Test public void onTest() { - System.out.println(ConfigInitializer.getSectionName("LoveGames")); // -> love-games - System.out.println(ConfigInitializer.getSectionName("EASY_GAME")); // -> easy-game - System.out.println(ConfigInitializer.getSectionName("F")); //-? f - System.out.println(ConfigInitializer.getSectionName("Test123123")); // -? test123123123 + System.out.println(ConfigInitializer.getPathFromName("LoveGames")); // -> love-games + System.out.println(ConfigInitializer.getPathFromName("EASY_GAME")); // -> easy-game + System.out.println(ConfigInitializer.getPathFromName("F")); //-? f + System.out.println(ConfigInitializer.getPathFromName("Test123123")); // -? test123123123 } diff --git a/impl/yaml/src/main/java/cc/carm/lib/configuration/yaml/value/ConfiguredSerializable.java b/impl/yaml/src/main/java/cc/carm/lib/configuration/yaml/value/ConfiguredSerializable.java index f3a20c4..9891f12 100644 --- a/impl/yaml/src/main/java/cc/carm/lib/configuration/yaml/value/ConfiguredSerializable.java +++ b/impl/yaml/src/main/java/cc/carm/lib/configuration/yaml/value/ConfiguredSerializable.java @@ -15,7 +15,7 @@ public class ConfiguredSerializable extends } public static ConfiguredSerializable of(@NotNull Class valueClass, - @Nullable V defaultValue) { + @Nullable V defaultValue) { return builder().ofSerializable(valueClass).defaults(defaultValue).build(); } diff --git a/impl/yaml/src/test/java/config/ConfigTester.java b/impl/yaml/src/test/java/config/ConfigTester.java index 002de10..25253af 100644 --- a/impl/yaml/src/test/java/config/ConfigTester.java +++ b/impl/yaml/src/test/java/config/ConfigTester.java @@ -5,7 +5,6 @@ import cc.carm.lib.configuration.yaml.YamlConfigProvider; import config.model.AbstractModel; import config.model.SomeModel; import config.model.TestModel; -import config.source.ComplexConfiguration; import config.source.DemoConfiguration; import config.source.ImplConfiguration; import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerialization; @@ -13,24 +12,25 @@ import org.junit.Test; import java.util.LinkedHashMap; import java.util.List; -import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.IntStream; public class ConfigTester { + static { + ConfigurationSerialization.registerClass(TestModel.class); + ConfigurationSerialization.registerClass(SomeModel.class); + } + + protected final YamlConfigProvider provider = EasyConfiguration.from("target/config.yml", "config.yml"); @Test public void onTest() { - ConfigurationSerialization.registerClass(TestModel.class); - ConfigurationSerialization.registerClass(SomeModel.class); + provider.initialize(DemoConfiguration.class); - YamlConfigProvider provider = EasyConfiguration.from("target/config.yml", "config.yml"); - - testDemo(provider); - testComplex(provider); - testSerialization(provider); + testDemo(); + testSerialization(); try { provider.save(); @@ -40,53 +40,40 @@ public class ConfigTester { } - public static void testSerialization(YamlConfigProvider provider) { + + public static void testDemo() { System.out.println("----------------------------------------------------"); - provider.initialize(ImplConfiguration.class); - System.out.println(ImplConfiguration.TEST.get()); - ImplConfiguration.TEST.set(TestModel.random()); - - AbstractModel model = provider.getConfiguration().getSerializable("ImplConfiguration.test", TestModel.class); - - provider.getConfiguration().set("ImplConfiguration.some", new SomeModel("lover", 123)); - AbstractModel model2 = provider.getConfiguration().getSerializable("ImplConfiguration.some", SomeModel.class); - - System.out.println("model1: " + Optional.ofNullable(model).map(AbstractModel::getName).orElse(null)); - System.out.println("model1: " + Optional.ofNullable(model2).map(AbstractModel::getName).orElse(null)); - - - System.out.println("----------------------------------------------------"); - } - - public static void testDemo(YamlConfigProvider provider) { - provider.initialize(DemoConfiguration.class); - } - - public static void testComplex(YamlConfigProvider provider) { - System.out.println("----------------------------------------------------"); - provider.initialize(ComplexConfiguration.class); System.out.println("> Test Value:"); - System.out.println("before: " + ComplexConfiguration.Sub.UUID_CONFIG_VALUE.get()); - ComplexConfiguration.Sub.UUID_CONFIG_VALUE.set(UUID.randomUUID()); - System.out.println("after: " + ComplexConfiguration.Sub.UUID_CONFIG_VALUE.get()); + System.out.println("before: " + DemoConfiguration.Sub.UUID_CONFIG_VALUE.get()); + DemoConfiguration.Sub.UUID_CONFIG_VALUE.set(UUID.randomUUID()); + System.out.println("after: " + DemoConfiguration.Sub.UUID_CONFIG_VALUE.get()); System.out.println("> Test List:"); - ComplexConfiguration.Sub.That.Operators.getNotNull().forEach(System.out::println); + DemoConfiguration.Sub.That.OPERATORS.getNotNull().forEach(System.out::println); List operators = IntStream.range(0, 5).mapToObj(i -> UUID.randomUUID()).collect(Collectors.toList()); - ComplexConfiguration.Sub.That.Operators.set(operators); + DemoConfiguration.Sub.That.OPERATORS.set(operators); System.out.println("> Test Section:"); - System.out.println(ComplexConfiguration.USER.get()); - ComplexConfiguration.USER.set(TestModel.random()); + System.out.println(DemoConfiguration.MODEL_TEST.get()); + DemoConfiguration.MODEL_TEST.set(TestModel.random()); System.out.println("> Test Maps:"); - ComplexConfiguration.USERS.getNotNull().forEach((k, v) -> System.out.println(k + ": " + v)); + DemoConfiguration.USERS.getNotNull().forEach((k, v) -> System.out.println(k + ": " + v)); LinkedHashMap data = new LinkedHashMap<>(); - for (int i = 0; i < 5; i++) { - data.put((int) (1000 * Math.random()), UUID.randomUUID()); + for (int i = 1; i <= 5; i++) { + data.put(i, UUID.randomUUID()); + } + DemoConfiguration.USERS.set(data); + System.out.println("----------------------------------------------------"); + } + + public static void testSerialization() { + System.out.println("----------------------------------------------------"); + AbstractModel model = ImplConfiguration.TEST.get(); + if (model != null) { + System.out.println(model.getName()); } - ComplexConfiguration.USERS.set(data); System.out.println("----------------------------------------------------"); } diff --git a/impl/yaml/src/test/java/config/OffsetTest.java b/impl/yaml/src/test/java/config/OffsetTest.java index 297c8d1..3d0d3df 100644 --- a/impl/yaml/src/test/java/config/OffsetTest.java +++ b/impl/yaml/src/test/java/config/OffsetTest.java @@ -1,18 +1,21 @@ package config; import config.offset.FieldOffset; +import config.offset.OffsetUtil; +import config.source.DemoConfiguration; +import org.junit.Test; import java.util.List; public class OffsetTest { -// @Test -// public void test() { + @Test + public void test() { // -// output(OffsetUtil.getClassMemberOffset(ComplexConfiguration.class)); -// output(OffsetUtil.getClassMemberOffset(ComplexConfiguration.Sub.class)); -// -// } +// output(OffsetUtil.getClassMemberOffset(DemoConfiguration.class)); +// output(OffsetUtil.getClassMemberOffset(DemoConfiguration.Sub.class)); + + } protected static void output(List fieldOffsets) { for (FieldOffset fieldOffset : fieldOffsets) { diff --git a/impl/yaml/src/test/java/config/model/AbstractModel.java b/impl/yaml/src/test/java/config/model/AbstractModel.java index ab5fdcd..19943e4 100644 --- a/impl/yaml/src/test/java/config/model/AbstractModel.java +++ b/impl/yaml/src/test/java/config/model/AbstractModel.java @@ -1,8 +1,9 @@ package config.model; +import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerializable; import org.jetbrains.annotations.NotNull; -public abstract class AbstractModel { +public abstract class AbstractModel implements ConfigurationSerializable { protected final @NotNull String name; diff --git a/impl/yaml/src/test/java/config/source/ComplexConfiguration.java b/impl/yaml/src/test/java/config/source/ComplexConfiguration.java deleted file mode 100644 index ee80738..0000000 --- a/impl/yaml/src/test/java/config/source/ComplexConfiguration.java +++ /dev/null @@ -1,56 +0,0 @@ -package config.source; - -import cc.carm.lib.configuration.core.ConfigurationRoot; -import cc.carm.lib.configuration.core.annotation.ConfigComment; -import cc.carm.lib.configuration.core.annotation.ConfigPath; -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.ConfiguredSection; -import cc.carm.lib.configuration.core.value.type.ConfiguredValue; -import config.model.TestModel; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; - -public class ComplexConfiguration extends ConfigurationRoot { - - @ConfigComment({"User测试"}) - public static final ConfigValue USER = ConfiguredSection - .builder(TestModel.class) - .defaults(new TestModel("Carm", UUID.randomUUID())) - .parseValue((section, defaultValue) -> TestModel.deserialize(section)) - .serializeValue(TestModel::serialize).build(); - - @ConfigComment({"[ID-UUID] 对照表", "", "用于测试Map类型的解析与序列化保存"}) - public static final ConfigValue> USERS = ConfiguredMap - .builder(Integer.class, UUID.class).fromString() - .parseKey(Integer::parseInt) - .parseValue(v -> Objects.requireNonNull(UUID.fromString(v))) - .build(); - - public static class Sub { - - @ConfigPath(value = "uuid", root = true) - public static final ConfigValue UUID_CONFIG_VALUE = ConfiguredValue - .builder(UUID.class).fromString() - .parseValue((data, defaultValue) -> UUID.fromString(data)) - .build(); - - @ConfigPath("nothing") - public static class That { - - public static final ConfigValue> Operators = ConfiguredList - .builder(UUID.class).fromString() - .parseValue(s -> Objects.requireNonNull(UUID.fromString(s))) - .build(); - - } - - - } - - -} diff --git a/impl/yaml/src/test/java/config/source/DatabaseConfiguration.java b/impl/yaml/src/test/java/config/source/DatabaseConfiguration.java new file mode 100644 index 0000000..298886f --- /dev/null +++ b/impl/yaml/src/test/java/config/source/DatabaseConfiguration.java @@ -0,0 +1,35 @@ +package config.source; + +import cc.carm.lib.configuration.core.ConfigurationRoot; +import cc.carm.lib.configuration.core.annotation.ConfigComment; +import cc.carm.lib.configuration.core.annotation.ConfigPath; +import cc.carm.lib.configuration.core.value.ConfigValue; +import cc.carm.lib.configuration.core.value.type.ConfiguredValue; + +@ConfigComment({"数据库配置", " 用于提供数据库连接,进行数据库操作。"}) +public class DatabaseConfiguration extends ConfigurationRoot { + + @ConfigPath("driver") + @ConfigComment({ + "数据库驱动配置,请根据数据库类型设置。", + "- MySQL: com.mysql.cj.jdbc.Driver", + "- MariaDB(推荐): org.mariadb.jdbc.Driver", + }) + protected static final ConfigValue DRIVER_NAME = ConfiguredValue.of( + String.class, "com.mysql.cj.jdbc.Driver" + ); + + protected static final ConfigValue HOST = ConfiguredValue.of(String.class, "127.0.0.1"); + protected static final ConfigValue PORT = ConfiguredValue.of(Integer.class, 3306); + + protected static final ConfigValue DATABASE = ConfiguredValue.of(String.class, "minecraft"); + protected static final ConfigValue USERNAME = ConfiguredValue.of(String.class, "root"); + protected static final ConfigValue PASSWORD = ConfiguredValue.of(String.class, "password"); + + protected static final ConfigValue EXTRA = ConfiguredValue.of(String.class, "?useSSL=false"); + + protected static String buildJDBC() { + return String.format("jdbc:mysql://%s:%s/%s%s", HOST.get(), PORT.get(), DATABASE.get(), EXTRA.get()); + } + +} diff --git a/impl/yaml/src/test/java/config/source/DemoConfiguration.java b/impl/yaml/src/test/java/config/source/DemoConfiguration.java index 51b117d..4efe0c3 100644 --- a/impl/yaml/src/test/java/config/source/DemoConfiguration.java +++ b/impl/yaml/src/test/java/config/source/DemoConfiguration.java @@ -4,10 +4,17 @@ import cc.carm.lib.configuration.core.ConfigurationRoot; import cc.carm.lib.configuration.core.annotation.ConfigComment; import cc.carm.lib.configuration.core.annotation.ConfigPath; 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.ConfiguredSection; import cc.carm.lib.configuration.core.value.type.ConfiguredValue; +import config.model.TestModel; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; -@ConfigPath("database") -@ConfigComment({"数据库配置", " 用于提供数据库连接,进行数据库操作。"}) public class DemoConfiguration extends ConfigurationRoot { @ConfigPath(root = true) @@ -19,29 +26,53 @@ public class DemoConfiguration extends ConfigurationRoot { protected static final ConfigValue VERSION = ConfiguredValue.of(Double.class, 1.0D); - @ConfigPath("driver") - @ConfigComment({ - "数据库驱动配置,请根据数据库类型设置。", - "- MySQL: com.mysql.cj.jdbc.Driver", - "- MariaDB(推荐): org.mariadb.jdbc.Driver", - }) - protected static final ConfigValue DRIVER_NAME = ConfiguredValue.of( - String.class, "com.mysql.cj.jdbc.Driver" - ); + // 注意: 若对应类也有注解,则优先使用类的注解。 + @ConfigPath("impl-test") //支持通过注解修改子配置的主路径,若不修改则以变量名自动生成。 + @ConfigComment("Something...") // 支持给子路径直接打注释 + public static final Class IMPL = ImplConfiguration.class; - protected static final ConfigValue HOST = ConfiguredValue.of(String.class, "127.0.0.1"); - protected static final ConfigValue PORT = ConfiguredValue.of(Integer.class, 3306); + // 可以直接写静态内部类,并通过 Class 声明。 + public static final Class SUB_TEST = Sub.class; - protected static final ConfigValue DATABASE = ConfiguredValue.of(String.class, "minecraft"); - protected static final ConfigValue USERNAME = ConfiguredValue.of(String.class, "root"); - protected static final ConfigValue PASSWORD = ConfiguredValue.of(String.class, "password"); + @ConfigPath("user") // 通过注解规定配置文件中的路径,若不进行注解则以变量名自动生成。 + @ConfigComment({"Section类型数据测试"}) // 通过注解给配置添加注释。 + public static final ConfigValue MODEL_TEST = ConfiguredSection + .builder(TestModel.class) + .defaults(new TestModel("Carm", UUID.randomUUID())) + .parseValue((section, defaultValue) -> TestModel.deserialize(section)) + .serializeValue(TestModel::serialize).build(); - protected static final ConfigValue EXTRA = ConfiguredValue.of(String.class, "?useSSL=false"); + // 子配置文件 + @ConfigPath("database") + public static final Class DB_CONFIG = DatabaseConfiguration.class; + + @ConfigComment({"[ID-UUID] 对照表", "", "用于测试Map类型的解析与序列化保存"}) + public static final ConfigValue> USERS = ConfiguredMap + .builder(Integer.class, UUID.class).fromString() + .parseKey(Integer::parseInt) + .parseValue(v -> Objects.requireNonNull(UUID.fromString(v))) + .build(); + + + public static class Sub extends ConfigurationRoot { + + @ConfigPath(value = "uuid-value", root = true) + public static final ConfigValue UUID_CONFIG_VALUE = ConfiguredValue + .builder(UUID.class).fromString() + .parseValue((data, defaultValue) -> UUID.fromString(data)) + .build(); + + public static final Class NOTHING = Sub.That.class; + + public static class That extends ConfigurationRoot { + + public static final ConfigValue> OPERATORS = ConfiguredList + .builder(UUID.class).fromString() + .parseValue(s -> Objects.requireNonNull(UUID.fromString(s))) + .build(); + + } - protected static String buildJDBC() { - return String.format("jdbc:mysql://%s:%s/%s%s", - HOST.get(), PORT.get(), DATABASE.get(), EXTRA.get() - ); } diff --git a/impl/yaml/src/test/java/config/source/ImplConfiguration.java b/impl/yaml/src/test/java/config/source/ImplConfiguration.java index 0ae1287..0acdcf8 100644 --- a/impl/yaml/src/test/java/config/source/ImplConfiguration.java +++ b/impl/yaml/src/test/java/config/source/ImplConfiguration.java @@ -4,12 +4,13 @@ import cc.carm.lib.configuration.core.ConfigurationRoot; import cc.carm.lib.configuration.core.annotation.ConfigPath; import cc.carm.lib.configuration.core.value.ConfigValue; import cc.carm.lib.configuration.yaml.value.ConfiguredSerializable; +import config.model.AbstractModel; import config.model.TestModel; -@ConfigPath("ImplConfiguration") +@ConfigPath(root = true) public class ImplConfiguration extends ConfigurationRoot { - public static final ConfigValue TEST = ConfiguredSerializable.of(TestModel.class); + public static final ConfigValue TEST = ConfiguredSerializable.of(TestModel.class, TestModel.random()); }