mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
feat(json): Finished json version's provider
This commit is contained in:
@@ -14,7 +14,7 @@ public @interface ConfigPath {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The path value of the current configuration.
|
* The path value of the current configuration.
|
||||||
* If not set,will generate the path by {@link PathGenerator}.
|
* If not set,will generate the path by {@link cc.carm.lib.configuration.source.loader.PathGenerator}.
|
||||||
*
|
*
|
||||||
* @return The path value of the current configuration
|
* @return The path value of the current configuration
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public abstract class AbstractConfigBuilder<
|
|||||||
|
|
||||||
public abstract @NotNull RESULT build();
|
public abstract @NotNull RESULT build();
|
||||||
|
|
||||||
public @NotNull SELF provider(@Nullable PROVIDER provider) {
|
public @NotNull SELF holder(@Nullable PROVIDER provider) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-8
@@ -83,29 +83,31 @@ public class ConfigurationInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public @Nullable String getFieldPath(ConfigurationHolder<?> holder, @Nullable String parentPath, @NotNull Field field) {
|
public @Nullable String getFieldPath(@NotNull ConfigurationHolder<?> holder, @Nullable String parentPath, @NotNull Field field) {
|
||||||
return pathGenerator.getFieldPath(holder, parentPath, field);
|
return pathGenerator.getFieldPath(holder, parentPath, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String getClassPath(ConfigurationHolder<?> holder, @Nullable String parentPath,
|
public @Nullable String getClassPath(@NotNull ConfigurationHolder<?> holder, @Nullable String parentPath,
|
||||||
@NotNull Class<?> clazz, @Nullable Field clazzField) {
|
@NotNull Class<?> clazz, @Nullable Field clazzField) {
|
||||||
return pathGenerator.getClassPath(holder, parentPath, clazz, clazzField);
|
return pathGenerator.getClassPath(holder, parentPath, clazz, clazzField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(ConfigurationHolder<?> holder, @NotNull Configuration config) throws Exception {
|
public void initialize(@NotNull ConfigurationHolder<?> holder,
|
||||||
|
@NotNull Configuration config) throws Exception {
|
||||||
initializeInstance(holder, config, null, null);
|
initializeInstance(holder, config, null, null);
|
||||||
if (holder.options().get(StandardOptions.SET_DEFAULTS)) holder.save();
|
if (holder.options().get(StandardOptions.SET_DEFAULTS)) holder.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(ConfigurationHolder<?> holder, @NotNull Class<? extends Configuration> clazz) throws Exception {
|
public void initialize(@NotNull ConfigurationHolder<?> holder,
|
||||||
|
@NotNull Class<? extends Configuration> clazz) throws Exception {
|
||||||
initializeStaticClass(holder, clazz, null, null);
|
initializeStaticClass(holder, clazz, null, null);
|
||||||
if (holder.options().get(StandardOptions.SET_DEFAULTS)) holder.save();
|
if (holder.options().get(StandardOptions.SET_DEFAULTS)) holder.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 针对实例类的初始化方法
|
// 针对实例类的初始化方法
|
||||||
protected void initializeInstance(@NotNull ConfigurationHolder<?> holder,
|
protected void initializeInstance(@NotNull ConfigurationHolder<?> holder, @NotNull Configuration root,
|
||||||
@NotNull Configuration root, @Nullable String parentPath, @Nullable Field configField) {
|
@Nullable String parentPath, @Nullable Field configField) {
|
||||||
String path = getClassPath(holder, parentPath, root.getClass(), configField);
|
String path = getClassPath(holder, parentPath, root.getClass(), configField);
|
||||||
try {
|
try {
|
||||||
this.classInitializer.whenInitialize(holder, path, root.getClass());
|
this.classInitializer.whenInitialize(holder, path, root.getClass());
|
||||||
@@ -118,8 +120,9 @@ public class ConfigurationInitializer {
|
|||||||
// 针对静态类的初始化方法
|
// 针对静态类的初始化方法
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected void initializeStaticClass(@NotNull ConfigurationHolder<?> holder,
|
protected void initializeStaticClass(@NotNull ConfigurationHolder<?> holder,
|
||||||
@NotNull Class<?> clazz, @Nullable String parentPath, @Nullable Field configField) {
|
@NotNull Class<?> clazz,
|
||||||
if (!Configuration.class.isAssignableFrom(clazz)) return; // 只解析继承了 ConfigurationRoot 的类
|
@Nullable String parentPath, @Nullable Field configField) {
|
||||||
|
if (!Configuration.class.isAssignableFrom(clazz)) return; // Only Configuration class can be initialized.
|
||||||
|
|
||||||
String path = getClassPath(holder, parentPath, clazz, configField);
|
String path = getClassPath(holder, parentPath, clazz, configField);
|
||||||
|
|
||||||
@@ -158,6 +161,9 @@ public class ConfigurationInitializer {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
if (holder.options().get(StandardOptions.SET_DEFAULTS)) {
|
||||||
|
value.setDefault();
|
||||||
|
}
|
||||||
} else if (source instanceof Configuration && object instanceof Configuration) {
|
} else if (source instanceof Configuration && object instanceof Configuration) {
|
||||||
// 当且仅当 源字段与字段 均为Configuration实例时,才对目标字段进行下一步初始化加载。
|
// 当且仅当 源字段与字段 均为Configuration实例时,才对目标字段进行下一步初始化加载。
|
||||||
initializeInstance(holder, (Configuration) object, parent, field);
|
initializeInstance(holder, (Configuration) object, parent, field);
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ public class PathGenerator {
|
|||||||
public @Nullable String getFieldPath(@NotNull ConfigurationHolder<?> holder,
|
public @Nullable String getFieldPath(@NotNull ConfigurationHolder<?> holder,
|
||||||
@Nullable String parentPath, @NotNull Field field) {
|
@Nullable String parentPath, @NotNull Field field) {
|
||||||
ConfigPath path = field.getAnnotation(ConfigPath.class);
|
ConfigPath path = field.getAnnotation(ConfigPath.class);
|
||||||
if (path == null) return link(holder, parentPath, false, field.getName()); // No annotation, use field name.
|
if (path == null)
|
||||||
else return link(holder, parentPath, path.root(), select(path.value(), field.getName()));
|
return link(holder, parentPath, false, covertPath(field.getName())); // No annotation, use field name.
|
||||||
|
else return link(holder, parentPath, path.root(), select(path.value(), covertPath(field.getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String getClassPath(@NotNull ConfigurationHolder<?> holder,
|
public @Nullable String getClassPath(@NotNull ConfigurationHolder<?> holder,
|
||||||
@@ -51,14 +52,14 @@ public class PathGenerator {
|
|||||||
// 2. If the class defined as a field, check if the field has a ConfigPath annotation,
|
// 2. If the class defined as a field, check if the field has a ConfigPath annotation,
|
||||||
// and use filed information.
|
// and use filed information.
|
||||||
ConfigPath clazzPath = clazz.getAnnotation(ConfigPath.class);
|
ConfigPath clazzPath = clazz.getAnnotation(ConfigPath.class);
|
||||||
|
|
||||||
if (clazzPath != null) return link(holder, parentPath, clazzPath.root(), clazzPath.value());
|
if (clazzPath != null) return link(holder, parentPath, clazzPath.root(), clazzPath.value());
|
||||||
|
|
||||||
if (clazzField == null) {
|
if (clazzField == null) {
|
||||||
return link(holder, parentPath, false, clazz.getSimpleName()); // No field, use class name.
|
return link(holder, parentPath, false, parentPath == null ? null : covertPath(clazz.getSimpleName())); // No field, use class name.
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigPath fieldPath = clazzField.getAnnotation(ConfigPath.class);
|
ConfigPath fieldPath = clazzField.getAnnotation(ConfigPath.class);
|
||||||
if (fieldPath == null) return link(holder, parentPath, false, clazzField.getName());
|
if (fieldPath == null) return link(holder, parentPath, false, covertPath(clazzField.getName()));
|
||||||
else return getFieldPath(holder, parentPath, clazzField);
|
else return getFieldPath(holder, parentPath, clazzField);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ public class PathGenerator {
|
|||||||
protected @Nullable String link(@NotNull ConfigurationHolder<?> holder,
|
protected @Nullable String link(@NotNull ConfigurationHolder<?> holder,
|
||||||
@Nullable String parent, boolean root, @Nullable String path) {
|
@Nullable String parent, boolean root, @Nullable String path) {
|
||||||
if (path == null || path.isEmpty()) return root ? null : parent;
|
if (path == null || path.isEmpty()) return root ? null : parent;
|
||||||
return root || parent == null ? covertPath(path) : parent + pathSeparator(holder) + covertPath(path);
|
return root || parent == null ? path : parent + pathSeparator(holder) + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isBlank(String path) {
|
public static boolean isBlank(String path) {
|
||||||
@@ -93,16 +94,16 @@ public class PathGenerator {
|
|||||||
public static String covertPathName(String name) {
|
public static String covertPathName(String name) {
|
||||||
return name
|
return name
|
||||||
// Replace all uppercase letters with dashes
|
// Replace all uppercase letters with dashes
|
||||||
.replaceAll("[A-Z]", "-$0")
|
.replaceAll("[A-Z]", "=$0")
|
||||||
// If the first letter is also capitalized,
|
// If the first letter is also capitalized,
|
||||||
// it will also be converted and the first dash will need to be removed
|
// it will also be converted and the first dash will need to be removed
|
||||||
.replaceAll("-(.*)", "$1")
|
.replaceAll("^=(.*)$", "$1")
|
||||||
// Because the name may contain _, it needs to be treated a little differently
|
// Because the name may contain _, it needs to be treated a little differently
|
||||||
.replaceAll("_-([A-Z])", "_$1")
|
.replaceAll("_=([A-Z])", "_$1")
|
||||||
// The content that is not named in all caps is then converted
|
// The content that is not named in all caps is then converted
|
||||||
.replaceAll("([a-z])-([A-Z])", "$1_$2")
|
.replaceAll("([a-z])=([A-Z])", "$1_$2")
|
||||||
// Remove any extra horizontal lines
|
// Remove any extra horizontal lines
|
||||||
.replace("-", "")
|
.replaceAll("=", "")
|
||||||
// Replace the underscore with a dash
|
// Replace the underscore with a dash
|
||||||
.replace("_", "-")
|
.replace("_", "-")
|
||||||
// Finally, convert it to all lowercase
|
// Finally, convert it to all lowercase
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package cc.carm.lib.configuration.demo.tests;
|
package cc.carm.lib.configuration.demo.tests;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.demo.tests.conf.DemoConfiguration;
|
import cc.carm.lib.configuration.demo.tests.conf.DemoConfiguration;
|
||||||
import cc.carm.lib.configuration.demo.tests.conf.TestConfiguration;
|
import cc.carm.lib.configuration.demo.tests.conf.RegistryConfig;
|
||||||
import cc.carm.lib.configuration.demo.tests.model.TestModel;
|
import cc.carm.lib.configuration.demo.tests.model.UserRecord;
|
||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
import org.jetbrains.annotations.TestOnly;
|
import org.jetbrains.annotations.TestOnly;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ public class ConfigurationTest {
|
|||||||
@TestOnly
|
@TestOnly
|
||||||
public static void testDemo(ConfigurationHolder<?> holder) {
|
public static void testDemo(ConfigurationHolder<?> holder) {
|
||||||
try {
|
try {
|
||||||
holder.initializer().initialize(holder, DemoConfiguration.class);
|
holder.initialize(DemoConfiguration.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -30,27 +30,27 @@ public class ConfigurationTest {
|
|||||||
System.out.println("after: " + DemoConfiguration.TEST_NUMBER.get());
|
System.out.println("after: " + DemoConfiguration.TEST_NUMBER.get());
|
||||||
|
|
||||||
System.out.println("> Test Value:");
|
System.out.println("> Test Value:");
|
||||||
System.out.println("before: " + DemoConfiguration.Sub.UUID_CONFIG_VALUE.get());
|
System.out.println("before: " + DemoConfiguration.SUB.UUID_CONFIG_VALUE.get());
|
||||||
DemoConfiguration.Sub.UUID_CONFIG_VALUE.set(UUID.randomUUID());
|
DemoConfiguration.SUB.UUID_CONFIG_VALUE.set(UUID.randomUUID());
|
||||||
System.out.println("after: " + DemoConfiguration.Sub.UUID_CONFIG_VALUE.get());
|
System.out.println("after: " + DemoConfiguration.SUB.UUID_CONFIG_VALUE.get());
|
||||||
|
|
||||||
System.out.println("> Test List:");
|
System.out.println("> Test List:");
|
||||||
|
|
||||||
System.out.println(" Before:");
|
System.out.println(" Before:");
|
||||||
DemoConfiguration.Sub.That.OPERATORS.forEach(System.out::println);
|
DemoConfiguration.SUB.That.OPERATORS.forEach(System.out::println);
|
||||||
List<UUID> operators = IntStream.range(0, 5).mapToObj(i -> UUID.randomUUID()).collect(Collectors.toList());
|
List<UUID> operators = IntStream.range(0, 5).mapToObj(i -> UUID.randomUUID()).collect(Collectors.toList());
|
||||||
DemoConfiguration.Sub.That.OPERATORS.set(operators);
|
DemoConfiguration.SUB.That.OPERATORS.set(operators);
|
||||||
System.out.println(" After:");
|
System.out.println(" After:");
|
||||||
DemoConfiguration.Sub.That.OPERATORS.forEach(System.out::println);
|
DemoConfiguration.SUB.That.OPERATORS.forEach(System.out::println);
|
||||||
|
|
||||||
System.out.println("> Clear List:");
|
System.out.println("> Clear List:");
|
||||||
System.out.println(" Before: size :" + DemoConfiguration.Sub.That.OPERATORS.size());
|
System.out.println(" Before: size :" + DemoConfiguration.SUB.That.OPERATORS.size());
|
||||||
DemoConfiguration.Sub.That.OPERATORS.modify(List::clear);
|
DemoConfiguration.SUB.That.OPERATORS.modify(List::clear);
|
||||||
System.out.println(" After size :" + DemoConfiguration.Sub.That.OPERATORS.size());
|
System.out.println(" After size :" + DemoConfiguration.SUB.That.OPERATORS.size());
|
||||||
|
|
||||||
System.out.println("> Test Section:");
|
System.out.println("> Test Section:");
|
||||||
System.out.println(DemoConfiguration.MODEL_TEST.get());
|
System.out.println(DemoConfiguration.USERS.get());
|
||||||
DemoConfiguration.MODEL_TEST.set(TestModel.random());
|
DemoConfiguration.USERS.add(UserRecord.random());
|
||||||
|
|
||||||
// System.out.println("> Test Maps:");
|
// System.out.println("> Test Maps:");
|
||||||
// DemoConfiguration.USERS.forEach((k, v) -> System.out.println(k + ": " + v));
|
// DemoConfiguration.USERS.forEach((k, v) -> System.out.println(k + ": " + v));
|
||||||
@@ -64,19 +64,19 @@ public class ConfigurationTest {
|
|||||||
|
|
||||||
public static void testInner(ConfigurationHolder<?> provider) {
|
public static void testInner(ConfigurationHolder<?> provider) {
|
||||||
|
|
||||||
TestConfiguration TEST = new TestConfiguration();
|
RegistryConfig TEST = new RegistryConfig();
|
||||||
|
|
||||||
provider.initialize(TEST);
|
provider.initialize(TEST);
|
||||||
|
|
||||||
System.out.println("> Test Inner value before:");
|
System.out.println("> Test Inner value before:");
|
||||||
System.out.println(TEST.INNER.INNER_VALUE.getNotNull());
|
System.out.println(TEST.INSTANCE.INNER_VALUE.getNotNull());
|
||||||
|
|
||||||
double after = Math.random() * 200D;
|
double after = Math.random() * 200D;
|
||||||
System.out.println("> Test Inner value -> " + after);
|
System.out.println("> Test Inner value -> " + after);
|
||||||
TEST.INNER.INNER_VALUE.set(after);
|
TEST.INSTANCE.INNER_VALUE.set(after);
|
||||||
|
|
||||||
System.out.println("> Test Inner value after:");
|
System.out.println("> Test Inner value after:");
|
||||||
System.out.println(TEST.INNER.INNER_VALUE.getNotNull());
|
System.out.println(TEST.INSTANCE.INNER_VALUE.getNotNull());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-11
@@ -4,7 +4,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.annotation.HeaderComment;
|
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||||
import cc.carm.lib.configuration.annotation.InlineComment;
|
import cc.carm.lib.configuration.annotation.InlineComment;
|
||||||
import cc.carm.lib.configuration.demo.tests.model.TestModel;
|
import cc.carm.lib.configuration.demo.DatabaseConfiguration;
|
||||||
|
import cc.carm.lib.configuration.demo.tests.model.UserRecord;
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
import cc.carm.lib.configuration.value.ConfigValue;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
@@ -27,18 +28,14 @@ public interface DemoConfiguration extends Configuration {
|
|||||||
|
|
||||||
// 支持通过 Class<?> 变量标注子配置,一并注册。
|
// 支持通过 Class<?> 变量标注子配置,一并注册。
|
||||||
// 注意: 若对应类也有注解,则优先使用类的注解。
|
// 注意: 若对应类也有注解,则优先使用类的注解。
|
||||||
@ConfigPath("other-class-config") //支持通过注解修改子配置的主路径,若不修改则以变量名自动生成。
|
Class<?> DATABASE = DatabaseConfiguration.class;
|
||||||
@HeaderComment({"", "Something..."}) // 支持给子路径直接打注释
|
|
||||||
@InlineComment("InlineComments for class path")
|
|
||||||
Class<?> OTHER = OtherConfiguration.class;
|
|
||||||
|
|
||||||
@ConfigPath("user") // 通过注解规定配置文件中的路径,若不进行注解则以变量名自动生成。
|
@ConfigPath("registered_users") // 通过注解规定配置文件中的路径,若不进行注解则以变量名自动生成。
|
||||||
@HeaderComment({"Section类型数据测试"}) // 通过注解给配置添加注释。
|
@HeaderComment({"Section类型数据测试"}) // 通过注解给配置添加注释。
|
||||||
@InlineComment("Section数据也支持InlineComment注释")
|
@InlineComment("Section数据也支持InlineComment注释")
|
||||||
ConfigValue<TestModel> MODEL_TEST = ConfiguredValue.builderOf(TestModel.class).fromSection()
|
ConfiguredList<UserRecord> USERS = ConfiguredList.builderOf(UserRecord.class).fromSection()
|
||||||
.defaults(new TestModel("Carm", UUID.randomUUID()))
|
.parse(UserRecord::deserialize).serialize(UserRecord::serialize)
|
||||||
.parse((holder, section) -> TestModel.deserialize(section))
|
.defaults(UserRecord.CARM).build();
|
||||||
.serialize(TestModel::serialize).build();
|
|
||||||
|
|
||||||
// @HeaderComment({"[ID - UUID]对照表", "", "用于测试Map类型的解析与序列化保存"})
|
// @HeaderComment({"[ID - UUID]对照表", "", "用于测试Map类型的解析与序列化保存"})
|
||||||
// ConfiguredMap<Integer, UUID> USERS = ConfiguredMap.builderOf(Integer.class, UUID.class)
|
// ConfiguredMap<Integer, UUID> USERS = ConfiguredMap.builderOf(Integer.class, UUID.class)
|
||||||
@@ -52,7 +49,7 @@ public interface DemoConfiguration extends Configuration {
|
|||||||
* 支持内部类的直接注册。
|
* 支持内部类的直接注册。
|
||||||
* 注意,需要启用 {@link cc.carm.lib.configuration.source.option.StandardOptions#LOAD_SUB_CLASSES}
|
* 注意,需要启用 {@link cc.carm.lib.configuration.source.option.StandardOptions#LOAD_SUB_CLASSES}
|
||||||
*/
|
*/
|
||||||
class Sub implements Configuration {
|
class SUB implements Configuration {
|
||||||
|
|
||||||
@ConfigPath(value = "uuid-value", root = true)
|
@ConfigPath(value = "uuid-value", root = true)
|
||||||
@InlineComment("This is an inline comment")
|
@InlineComment("This is an inline comment")
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import cc.carm.lib.configuration.value.ConfigValue;
|
|||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
|
|
||||||
@HeaderComment("Inner Test")
|
@HeaderComment("Inner Test")
|
||||||
public class TestInnerConfiguration implements Configuration {
|
public class InstanceConfig implements Configuration {
|
||||||
|
|
||||||
public final ConfigValue<Double> INNER_VALUE = ConfiguredValue.of(1.0D);
|
public final ConfigValue<Double> INNER_VALUE = ConfiguredValue.of(1.0D);
|
||||||
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.demo.tests.conf;
|
|
||||||
|
|
||||||
public class OtherConfiguration {
|
|
||||||
}
|
|
||||||
+7
-8
@@ -4,24 +4,23 @@ 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.annotation.HeaderComment;
|
import cc.carm.lib.configuration.annotation.HeaderComment;
|
||||||
import cc.carm.lib.configuration.annotation.InlineComment;
|
import cc.carm.lib.configuration.annotation.InlineComment;
|
||||||
import cc.carm.lib.configuration.demo.tests.model.TestModel;
|
import cc.carm.lib.configuration.demo.tests.model.UserRecord;
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
import cc.carm.lib.configuration.value.ConfigValue;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TestConfiguration implements Configuration {
|
public class RegistryConfig implements Configuration {
|
||||||
|
|
||||||
public final TestInnerConfiguration INNER = new TestInnerConfiguration();
|
@HeaderComment("Support for configurations as instances")
|
||||||
|
public final InstanceConfig INSTANCE = new InstanceConfig();
|
||||||
public final ConfigValue<Double> CLASS_VALUE = ConfiguredValue.of(1.0D);
|
|
||||||
|
|
||||||
@ConfigPath("test.user") // 通过注解规定配置文件中的路径,若不进行注解则以变量名自动生成。
|
@ConfigPath("test.user") // 通过注解规定配置文件中的路径,若不进行注解则以变量名自动生成。
|
||||||
@HeaderComment({"Section类型数据测试"}) // 通过注解给配置添加注释。
|
@HeaderComment({"Section类型数据测试"}) // 通过注解给配置添加注释。
|
||||||
@InlineComment("Section数据也支持InlineComment注释")
|
@InlineComment("Section数据也支持InlineComment注释")
|
||||||
public final ConfigValue<TestModel> TEST_MODEL = ConfiguredValue.builderOf(TestModel.class).fromSection()
|
public final ConfigValue<UserRecord> TEST_MODEL = ConfiguredValue.builderOf(UserRecord.class).fromSection()
|
||||||
.defaults(new TestModel("Carm", UUID.randomUUID()))
|
.defaults(new UserRecord("Carm", UUID.randomUUID()))
|
||||||
.parse((holder, section) -> TestModel.deserialize(section))
|
.parse((holder, section) -> UserRecord.deserialize(section))
|
||||||
.serialize((holder, data) -> data.serialize()).build();
|
.serialize((holder, data) -> data.serialize()).build();
|
||||||
|
|
||||||
|
|
||||||
+2
-2
@@ -2,11 +2,11 @@ package cc.carm.lib.configuration.demo.tests.model;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class AbstractModel {
|
public abstract class AbstractRecord {
|
||||||
|
|
||||||
protected final @NotNull String name;
|
protected final @NotNull String name;
|
||||||
|
|
||||||
public AbstractModel(@NotNull String name) {
|
public AbstractRecord(@NotNull String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
+11
-9
@@ -7,20 +7,22 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TestModel extends AbstractModel {
|
public class UserRecord extends AbstractRecord {
|
||||||
|
|
||||||
public UUID uuid;
|
public static final UserRecord CARM = new UserRecord("Carm", UUID.fromString("f7b3b3b3-3b3b-3b3b-3b3b-3b3b3b3b3b3b"));
|
||||||
|
|
||||||
public TestModel(String name, UUID uuid) {
|
protected UUID uuid;
|
||||||
|
|
||||||
|
public UserRecord(String name, UUID uuid) {
|
||||||
super(name);
|
super(name);
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUuid(UUID uuid) {
|
public void uuid(UUID uuid) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getUuid() {
|
public UUID uuid() {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,16 +35,16 @@ public class TestModel extends AbstractModel {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TestModel deserialize(ConfigureSection section) {
|
public static UserRecord deserialize(ConfigureSection section) {
|
||||||
String name = section.getString("name");
|
String name = section.getString("name");
|
||||||
if (name == null) throw new NullPointerException("name is null");
|
if (name == null) throw new NullPointerException("name is null");
|
||||||
String uuidString = section.getString("info.uuid");
|
String uuidString = section.getString("info.uuid");
|
||||||
if (uuidString == null) throw new NullPointerException("uuid is null");
|
if (uuidString == null) throw new NullPointerException("uuid is null");
|
||||||
return new TestModel(name, UUID.fromString(uuidString));
|
return new UserRecord(name, UUID.fromString(uuidString));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TestModel random() {
|
public static UserRecord random() {
|
||||||
return new TestModel(UUID.randomUUID().toString().substring(0, 5), UUID.randomUUID());
|
return new UserRecord(UUID.randomUUID().toString().substring(0, 5), UUID.randomUUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -46,16 +46,17 @@ public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINA
|
|||||||
throw new IOException("Failed to create directory " + file.getParentFile().getAbsolutePath());
|
throw new IOException("Failed to create directory " + file.getParentFile().getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.file.createNewFile()) {
|
|
||||||
throw new IOException("Failed to create file " + file.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resourcePath != null && copyDefaults()) {
|
if (resourcePath != null && copyDefaults()) {
|
||||||
try {
|
try {
|
||||||
saveResource(resourcePath, false);
|
saveResource(resourcePath, false);
|
||||||
} catch (IllegalArgumentException ignored) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.file.exists() && !this.file.createNewFile()) {
|
||||||
|
throw new IOException("Failed to create file " + file.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <R> R fileInputStream(@NotNull DataFunction<InputStream, R> loader) throws Exception {
|
protected <R> R fileInputStream(@NotNull DataFunction<InputStream, R> loader) throws Exception {
|
||||||
@@ -65,7 +66,11 @@ public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINA
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected <R> R fileReader(@NotNull DataFunction<Reader, R> loader) throws Exception {
|
protected <R> R fileReader(@NotNull DataFunction<Reader, R> loader) throws Exception {
|
||||||
return fileInputStream(is -> loader.handle(new InputStreamReader(is, charset())));
|
try (InputStream is = Files.newInputStream(file.toPath())) {
|
||||||
|
try (Reader r = new InputStreamReader(is, charset())) {
|
||||||
|
return loader.handle(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void fileOutputStream(@NotNull Consumer<OutputStream> stream) throws Exception {
|
protected void fileOutputStream(@NotNull Consumer<OutputStream> stream) throws Exception {
|
||||||
@@ -75,7 +80,11 @@ public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINA
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void fileWriter(@NotNull Consumer<Writer> writer) throws Exception {
|
protected void fileWriter(@NotNull Consumer<Writer> writer) throws Exception {
|
||||||
fileOutputStream(os -> writer.accept(new OutputStreamWriter(os, charset())));
|
try (OutputStream os = Files.newOutputStream(file.toPath())) {
|
||||||
|
try (Writer w = new OutputStreamWriter(os, charset())) {
|
||||||
|
writer.accept(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void saveResource(@NotNull String resourcePath, boolean replace)
|
protected void saveResource(@NotNull String resourcePath, boolean replace)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<module>features/commentable</module>
|
<module>features/commentable</module>
|
||||||
<module>features/file</module>
|
<module>features/file</module>
|
||||||
|
|
||||||
<!-- <module>providers/yaml</module>-->
|
<module>providers/yaml</module>
|
||||||
<module>providers/gson</module>
|
<module>providers/gson</module>
|
||||||
<!-- <module>providers/sql</module>-->
|
<!-- <module>providers/sql</module>-->
|
||||||
<!-- <module>providers/hocon</module>-->
|
<!-- <module>providers/hocon</module>-->
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ public class JSONSection implements ConfigureSection {
|
|||||||
|
|
||||||
if (entry.getValue() instanceof Map) {
|
if (entry.getValue() instanceof Map) {
|
||||||
this.data.put(key, new JSONSection(source, (Map<?, ?>) entry.getValue()));
|
this.data.put(key, new JSONSection(source, (Map<?, ?>) entry.getValue()));
|
||||||
|
} else if (entry.getValue() instanceof List) {
|
||||||
|
List<Object> list = new ArrayList<>();
|
||||||
|
for (Object obj : (List<?>) entry.getValue()) {
|
||||||
|
if (obj instanceof Map) {
|
||||||
|
list.add(new JSONSection(source, (Map<?, ?>) obj));
|
||||||
|
} else {
|
||||||
|
list.add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.data.put(key, list);
|
||||||
} else {
|
} else {
|
||||||
this.data.put(key, entry.getValue());
|
this.data.put(key, entry.getValue());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ package config;
|
|||||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||||
import cc.carm.lib.configuration.json.JSONConfigFactory;
|
import cc.carm.lib.configuration.json.JSONConfigFactory;
|
||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import cc.carm.lib.configuration.source.loader.PathGenerator;
|
||||||
import cc.carm.lib.configuration.source.option.StandardOptions;
|
import cc.carm.lib.configuration.source.option.StandardOptions;
|
||||||
|
import cc.carm.lib.configuration.value.ConfigValue;
|
||||||
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -12,11 +15,17 @@ public class JSONConfigTest {
|
|||||||
|
|
||||||
protected final ConfigurationHolder<?> holder = JSONConfigFactory
|
protected final ConfigurationHolder<?> holder = JSONConfigFactory
|
||||||
.from(new File("target"), "config.json")
|
.from(new File("target"), "config.json")
|
||||||
.option(StandardOptions.PATH_SEPARATOR, '-')
|
.resourcePath("example.json")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onTest() {
|
public void onTest() {
|
||||||
|
|
||||||
|
ConfigValue<Boolean> EXAMPLE = ConfiguredValue.of(false);
|
||||||
|
EXAMPLE.initialize(this.holder, "example");
|
||||||
|
|
||||||
|
System.out.println("Example: " + EXAMPLE.get());
|
||||||
|
|
||||||
ConfigurationTest.testDemo(this.holder);
|
ConfigurationTest.testDemo(this.holder);
|
||||||
ConfigurationTest.testInner(this.holder);
|
ConfigurationTest.testInner(this.holder);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"example": "true"
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package config;
|
|||||||
|
|
||||||
import cc.carm.lib.configuration.EasyConfiguration;
|
import cc.carm.lib.configuration.EasyConfiguration;
|
||||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||||
import cc.carm.lib.configuration.demo.tests.model.AbstractModel;
|
import cc.carm.lib.configuration.demo.tests.model.AbstractRecord;
|
||||||
import cc.carm.lib.configuration.yaml.YAMLConfigProvider;
|
import cc.carm.lib.configuration.yaml.YAMLConfigProvider;
|
||||||
import config.model.AnyModel;
|
import config.model.AnyModel;
|
||||||
import config.model.SomeModel;
|
import config.model.SomeModel;
|
||||||
@@ -10,8 +10,6 @@ import config.source.ModelConfiguration;
|
|||||||
import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerialization;
|
import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerialization;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class DemoConfigTest {
|
public class DemoConfigTest {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -37,10 +35,10 @@ public class DemoConfigTest {
|
|||||||
provider.initialize(ModelConfiguration.class);
|
provider.initialize(ModelConfiguration.class);
|
||||||
System.out.println("----------------------------------------------------");
|
System.out.println("----------------------------------------------------");
|
||||||
|
|
||||||
AbstractModel someModel = ModelConfiguration.SOME_MODEL.get();
|
AbstractRecord someModel = ModelConfiguration.SOME_MODEL.get();
|
||||||
if (someModel != null) System.out.println(someModel.getName());
|
if (someModel != null) System.out.println(someModel.getName());
|
||||||
|
|
||||||
AbstractModel anyModel = ModelConfiguration.ANY_MODEL.get();
|
AbstractRecord anyModel = ModelConfiguration.ANY_MODEL.get();
|
||||||
if (anyModel != null) System.out.println(anyModel.getName());
|
if (anyModel != null) System.out.println(anyModel.getName());
|
||||||
|
|
||||||
ModelConfiguration.MODELS.forEach(System.out::println);
|
ModelConfiguration.MODELS.forEach(System.out::println);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package config.model;
|
package config.model;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.demo.tests.model.AbstractModel;
|
import cc.carm.lib.configuration.demo.tests.model.AbstractRecord;
|
||||||
import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerializable;
|
import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerializable;
|
||||||
import org.bspfsystems.yamlconfiguration.serialization.SerializableAs;
|
import org.bspfsystems.yamlconfiguration.serialization.SerializableAs;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@SerializableAs("AnyModel")
|
@SerializableAs("AnyModel")
|
||||||
public class AnyModel extends AbstractModel implements ConfigurationSerializable {
|
public class AnyModel extends AbstractRecord implements ConfigurationSerializable {
|
||||||
|
|
||||||
public final boolean bool;
|
public final boolean bool;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package config.model;
|
package config.model;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.demo.tests.model.AbstractModel;
|
import cc.carm.lib.configuration.demo.tests.model.AbstractRecord;
|
||||||
import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerializable;
|
import org.bspfsystems.yamlconfiguration.serialization.ConfigurationSerializable;
|
||||||
import org.bspfsystems.yamlconfiguration.serialization.SerializableAs;
|
import org.bspfsystems.yamlconfiguration.serialization.SerializableAs;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@SerializableAs("SomeModel")
|
@SerializableAs("SomeModel")
|
||||||
public class SomeModel extends AbstractModel implements ConfigurationSerializable {
|
public class SomeModel extends AbstractRecord implements ConfigurationSerializable {
|
||||||
|
|
||||||
public final int num;
|
public final int num;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import cc.carm.lib.configuration.value.ConfigValue;
|
|||||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredSectionMap;
|
import cc.carm.lib.configuration.value.standard.ConfiguredSectionMap;
|
||||||
import cc.carm.lib.configuration.demo.tests.model.AbstractModel;
|
import cc.carm.lib.configuration.demo.tests.model.AbstractRecord;
|
||||||
import cc.carm.lib.configuration.yaml.value.ConfiguredSerializable;
|
import cc.carm.lib.configuration.yaml.value.ConfiguredSerializable;
|
||||||
import config.model.AnyModel;
|
import config.model.AnyModel;
|
||||||
import config.model.SomeModel;
|
import config.model.SomeModel;
|
||||||
@@ -16,11 +16,11 @@ import config.model.SomeModel;
|
|||||||
@ConfigPath("model-test")
|
@ConfigPath("model-test")
|
||||||
public class ModelConfiguration implements Configuration {
|
public class ModelConfiguration implements Configuration {
|
||||||
|
|
||||||
public static final ConfigValue<? extends AbstractModel> SOME_MODEL = ConfiguredSerializable.of(
|
public static final ConfigValue<? extends AbstractRecord> SOME_MODEL = ConfiguredSerializable.of(
|
||||||
SomeModel.class, SomeModel.random()
|
SomeModel.class, SomeModel.random()
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final ConfigValue<? extends AbstractModel> ANY_MODEL = ConfiguredSerializable.of(
|
public static final ConfigValue<? extends AbstractRecord> ANY_MODEL = ConfiguredSerializable.of(
|
||||||
AnyModel.class, AnyModel.random()
|
AnyModel.class, AnyModel.random()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user