mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 10:38:19 +08:00
feat(exception): Supported ConfigExceptionHandler for holders.
This commit is contained in:
@@ -1,21 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.annotation;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
|
||||||
|
|
||||||
public class Ex {
|
|
||||||
|
|
||||||
static void init(ConfigurationInitializer initializer) {
|
|
||||||
initializer.appendFieldInitializer((holder, path, field, value) -> {
|
|
||||||
ValueRange range = field.getAnnotation(ValueRange.class);
|
|
||||||
if (range == null) return;
|
|
||||||
value.validate((h, v) -> {
|
|
||||||
if (!(v instanceof Number)) return;
|
|
||||||
Number number = (Number) v;
|
|
||||||
if (number.doubleValue() >= range.min() && number.doubleValue() <= range.max()) {
|
|
||||||
throw new IllegalArgumentException(range.message());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -29,7 +29,7 @@ public abstract class AbstractConfigBuilder<
|
|||||||
protected @Nullable HOLDER holder;
|
protected @Nullable HOLDER holder;
|
||||||
protected @Nullable String path;
|
protected @Nullable String path;
|
||||||
|
|
||||||
protected @NotNull ValueValidator<? super UNIT> valueValidator = ValueValidator.none();
|
protected @NotNull ValueValidator<UNIT> valueValidator = ValueValidator.none();
|
||||||
protected @NotNull Supplier<@Nullable TYPE> defaultValueSupplier = () -> null;
|
protected @NotNull Supplier<@Nullable TYPE> defaultValueSupplier = () -> null;
|
||||||
protected @NotNull BiConsumer<ConfigurationHolder<?>, String> initializer = (h, p) -> {
|
protected @NotNull BiConsumer<ConfigurationHolder<?>, String> initializer = (h, p) -> {
|
||||||
};
|
};
|
||||||
@@ -63,7 +63,7 @@ public abstract class AbstractConfigBuilder<
|
|||||||
* @param validator The validator to set.
|
* @param validator The validator to set.
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
public SELF validator(@NotNull ValueValidator<? super UNIT> validator) {
|
public SELF validator(@NotNull ValueValidator<UNIT> validator) {
|
||||||
this.valueValidator = validator;
|
this.valueValidator = validator;
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
@@ -81,20 +81,17 @@ public abstract class AbstractConfigBuilder<
|
|||||||
/**
|
/**
|
||||||
* Validate the value with the specified condition.
|
* Validate the value with the specified condition.
|
||||||
*
|
*
|
||||||
* @param validator The validator to set.
|
* @param validator The validator to append.
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
public SELF validate(@NotNull ValueValidator<? super UNIT> validator) {
|
public SELF validate(@NotNull ValueValidator<? super UNIT> validator) {
|
||||||
return validator((h, v) -> {
|
return validator(this.valueValidator.and(validator));
|
||||||
this.valueValidator.validate(h, v);
|
|
||||||
validator.validate(h, v);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the value with the specified condition.
|
* Validate the value with the specified condition.
|
||||||
*
|
*
|
||||||
* @param validator The validator to set.
|
* @param validator The validator to append.
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
public SELF validate(@NotNull DataValidator<? super UNIT> validator) {
|
public SELF validate(@NotNull DataValidator<? super UNIT> validator) {
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package cc.carm.lib.configuration.function;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ConfigExceptionHandler {
|
||||||
|
|
||||||
|
void handle(@NotNull String path, @NotNull Throwable throwable);
|
||||||
|
|
||||||
|
static @NotNull ConfigExceptionHandler silence() {
|
||||||
|
return (path, throwable) -> {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static @NotNull ConfigExceptionHandler print() {
|
||||||
|
return (path, throwable) -> {
|
||||||
|
System.err.println("Error occurred at path: " + path);
|
||||||
|
throwable.printStackTrace();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ public interface ValueValidator<T> {
|
|||||||
|
|
||||||
void validate(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception;
|
void validate(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception;
|
||||||
|
|
||||||
default ValueValidator<T> compose(ValueValidator<? super T> other) {
|
default ValueValidator<T> and(ValueValidator<? super T> other) {
|
||||||
return (holder, value) -> {
|
return (holder, value) -> {
|
||||||
validate(holder, value);
|
validate(holder, value);
|
||||||
other.validate(holder, value);
|
other.validate(holder, value);
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package cc.carm.lib.configuration.source;
|
|||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.*;
|
import cc.carm.lib.configuration.adapter.*;
|
||||||
import cc.carm.lib.configuration.adapter.strandard.StandardAdapters;
|
import cc.carm.lib.configuration.adapter.strandard.StandardAdapters;
|
||||||
|
import cc.carm.lib.configuration.function.ConfigExceptionHandler;
|
||||||
import cc.carm.lib.configuration.function.DataFunction;
|
import cc.carm.lib.configuration.function.DataFunction;
|
||||||
|
import cc.carm.lib.configuration.function.ValueValidator;
|
||||||
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
||||||
import cc.carm.lib.configuration.source.loader.PathGenerator;
|
import cc.carm.lib.configuration.source.loader.PathGenerator;
|
||||||
import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder;
|
import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder;
|
||||||
@@ -33,10 +35,11 @@ public abstract class ConfigurationFactory<
|
|||||||
SELF
|
SELF
|
||||||
> {
|
> {
|
||||||
|
|
||||||
protected ValueAdapterRegistry adapters = new ValueAdapterRegistry();
|
protected @NotNull ValueAdapterRegistry adapters = new ValueAdapterRegistry();
|
||||||
protected ConfigurationOptionHolder options = new ConfigurationOptionHolder();
|
protected @NotNull ConfigurationOptionHolder options = new ConfigurationOptionHolder();
|
||||||
protected @NotNull Map<String, ConfigurationMetaHolder> metadata = new HashMap<>();
|
protected @NotNull Map<String, ConfigurationMetaHolder> metadata = new HashMap<>();
|
||||||
protected ConfigurationInitializer initializer = new ConfigurationInitializer();
|
protected @NotNull ConfigurationInitializer initializer = new ConfigurationInitializer();
|
||||||
|
protected @NotNull ConfigExceptionHandler exceptionHandler = ConfigExceptionHandler.print();
|
||||||
|
|
||||||
protected ConfigurationFactory() {
|
protected ConfigurationFactory() {
|
||||||
this.adapters.register(StandardAdapters.PRIMITIVES);
|
this.adapters.register(StandardAdapters.PRIMITIVES);
|
||||||
@@ -147,6 +150,11 @@ public abstract class ConfigurationFactory<
|
|||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SELF exceptionally(@NotNull ConfigExceptionHandler handler) {
|
||||||
|
this.exceptionHandler = handler;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supply the base path generator for this configuration holder
|
* Supply the base path generator for this configuration holder
|
||||||
*
|
*
|
||||||
@@ -154,9 +162,7 @@ public abstract class ConfigurationFactory<
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public SELF pathGenerator(PathGenerator generator) {
|
public SELF pathGenerator(PathGenerator generator) {
|
||||||
return initializer(loader -> {
|
return initializer(loader -> loader.pathGenerator(generator));
|
||||||
loader.pathGenerator(generator);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,6 +181,19 @@ public abstract class ConfigurationFactory<
|
|||||||
return initializer(loader -> loader.registerAnnotation(annotation, metadata, extractor));
|
return initializer(loader -> loader.registerAnnotation(annotation, metadata, extractor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new annotation for {@link ValueValidator} to the configuration loader
|
||||||
|
*
|
||||||
|
* @param annotation The {@link Annotation}
|
||||||
|
* @param builder The {@link Function} to build the {@link ValueValidator} from the annotation
|
||||||
|
* @param <A> The annotation type
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public <A extends Annotation> SELF validAnnotation(@NotNull Class<A> annotation,
|
||||||
|
@NotNull Function<A, ValueValidator<Object>> builder) {
|
||||||
|
return initializer(loader -> loader.registerValidAnnotation(annotation, builder));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the configuration holder.
|
* Build the configuration holder.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package cc.carm.lib.configuration.source;
|
|||||||
import cc.carm.lib.configuration.Configuration;
|
import cc.carm.lib.configuration.Configuration;
|
||||||
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
import cc.carm.lib.configuration.adapter.ValueAdapterRegistry;
|
||||||
import cc.carm.lib.configuration.adapter.ValueType;
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.function.ConfigExceptionHandler;
|
||||||
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
import cc.carm.lib.configuration.source.loader.ConfigurationInitializer;
|
||||||
import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder;
|
import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder;
|
||||||
import cc.carm.lib.configuration.source.meta.ConfigurationMetadata;
|
import cc.carm.lib.configuration.source.meta.ConfigurationMetadata;
|
||||||
@@ -31,14 +32,25 @@ public abstract class ConfigurationHolder<SOURCE extends ConfigureSource<?, ?, S
|
|||||||
|
|
||||||
protected final @NotNull ConfigurationInitializer initializer;
|
protected final @NotNull ConfigurationInitializer initializer;
|
||||||
|
|
||||||
|
protected @NotNull ConfigExceptionHandler exceptionHandler;
|
||||||
|
|
||||||
public ConfigurationHolder(@NotNull ValueAdapterRegistry adapters,
|
public ConfigurationHolder(@NotNull ValueAdapterRegistry adapters,
|
||||||
@NotNull ConfigurationOptionHolder options,
|
@NotNull ConfigurationOptionHolder options,
|
||||||
@NotNull Map<String, ConfigurationMetaHolder> metadata,
|
@NotNull Map<String, ConfigurationMetaHolder> metadata,
|
||||||
@NotNull ConfigurationInitializer initializer) {
|
@NotNull ConfigurationInitializer initializer) {
|
||||||
|
this(adapters, options, metadata, initializer, ConfigExceptionHandler.print());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationHolder(@NotNull ValueAdapterRegistry adapters,
|
||||||
|
@NotNull ConfigurationOptionHolder options,
|
||||||
|
@NotNull Map<String, ConfigurationMetaHolder> metadata,
|
||||||
|
@NotNull ConfigurationInitializer initializer,
|
||||||
|
@NotNull ConfigExceptionHandler exceptionHandler) {
|
||||||
this.initializer = initializer;
|
this.initializer = initializer;
|
||||||
this.adapters = adapters;
|
this.adapters = adapters;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
|
this.exceptionHandler = exceptionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract @NotNull SOURCE config();
|
public abstract @NotNull SOURCE config();
|
||||||
@@ -117,7 +129,7 @@ public abstract class ConfigurationHolder<SOURCE extends ConfigureSource<?, ?, S
|
|||||||
try {
|
try {
|
||||||
initializer.initialize(this, configClass);
|
initializer.initialize(this, configClass);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
throwing(configClass.getName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +137,7 @@ public abstract class ConfigurationHolder<SOURCE extends ConfigureSource<?, ?, S
|
|||||||
try {
|
try {
|
||||||
initializer.initialize(this, config);
|
initializer.initialize(this, config);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
throwing(config.getClass().getName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,4 +145,12 @@ public abstract class ConfigurationHolder<SOURCE extends ConfigureSource<?, ?, S
|
|||||||
value.holder(this);
|
value.holder(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void throwing(@NotNull String path, @NotNull Throwable e) {
|
||||||
|
this.exceptionHandler.handle(path, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exceptionally(@NotNull ConfigExceptionHandler handler) {
|
||||||
|
this.exceptionHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -134,7 +134,7 @@ public class ConfigurationInitializer {
|
|||||||
try {
|
try {
|
||||||
this.classInitializer.whenInitialize(holder, path, root.getClass(), root);
|
this.classInitializer.whenInitialize(holder, path, root.getClass(), root);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
holder.throwing(path, e);
|
||||||
}
|
}
|
||||||
Arrays.stream(root.getClass().getDeclaredFields()).forEach(field -> initializeField(holder, root, field, path));
|
Arrays.stream(root.getClass().getDeclaredFields()).forEach(field -> initializeField(holder, root, field, path));
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ public class ConfigurationInitializer {
|
|||||||
try {
|
try {
|
||||||
this.classInitializer.whenInitialize(holder, path, (Class<? extends Configuration>) clazz, configField);
|
this.classInitializer.whenInitialize(holder, path, (Class<? extends Configuration>) clazz, configField);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
holder.throwing(path, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
@@ -185,7 +185,7 @@ public class ConfigurationInitializer {
|
|||||||
try {
|
try {
|
||||||
this.valueInitializer.whenInitialize(holder, path, field, value);
|
this.valueInitializer.whenInitialize(holder, path, field, value);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
holder.throwing(path, e);
|
||||||
}
|
}
|
||||||
if (holder.option(StandardOptions.PRELOAD)) {
|
if (holder.option(StandardOptions.PRELOAD)) {
|
||||||
value.get(); // Preload the value by calling #get method.
|
value.get(); // Preload the value by calling #get method.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class ValueManifest<TYPE, UNIT> {
|
|||||||
protected @Nullable ConfigurationHolder<?> holder;
|
protected @Nullable ConfigurationHolder<?> holder;
|
||||||
protected @Nullable String path; // Section path
|
protected @Nullable String path; // Section path
|
||||||
|
|
||||||
protected @NotNull ValueValidator<? super UNIT> validator;
|
protected @NotNull ValueValidator<UNIT> validator;
|
||||||
protected @NotNull Supplier<@Nullable TYPE> defaultSupplier;
|
protected @NotNull Supplier<@Nullable TYPE> defaultSupplier;
|
||||||
|
|
||||||
public ValueManifest(@NotNull ValueType<TYPE> type) {
|
public ValueManifest(@NotNull ValueType<TYPE> type) {
|
||||||
@@ -37,19 +37,19 @@ public class ValueManifest<TYPE, UNIT> {
|
|||||||
|
|
||||||
public ValueManifest(@NotNull ValueType<TYPE> type,
|
public ValueManifest(@NotNull ValueType<TYPE> type,
|
||||||
@NotNull Supplier<@Nullable TYPE> defaultSupplier,
|
@NotNull Supplier<@Nullable TYPE> defaultSupplier,
|
||||||
@NotNull ValueValidator<? super UNIT> validator) {
|
@NotNull ValueValidator<UNIT> validator) {
|
||||||
this(type, defaultSupplier, validator, EMPTY_INITIALIZER, null, null);
|
this(type, defaultSupplier, validator, EMPTY_INITIALIZER, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueManifest(@NotNull ValueType<TYPE> type, @NotNull Supplier<@Nullable TYPE> defaultSupplier,
|
public ValueManifest(@NotNull ValueType<TYPE> type, @NotNull Supplier<@Nullable TYPE> defaultSupplier,
|
||||||
@NotNull ValueValidator<? super UNIT> validator,
|
@NotNull ValueValidator<UNIT> validator,
|
||||||
@NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer) {
|
@NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer) {
|
||||||
this(type, defaultSupplier, validator, initializer, null, null);
|
this(type, defaultSupplier, validator, initializer, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueManifest(@NotNull ValueType<TYPE> type,
|
public ValueManifest(@NotNull ValueType<TYPE> type,
|
||||||
@NotNull Supplier<@Nullable TYPE> defaultSupplier,
|
@NotNull Supplier<@Nullable TYPE> defaultSupplier,
|
||||||
@NotNull ValueValidator<? super UNIT> validator,
|
@NotNull ValueValidator<UNIT> validator,
|
||||||
@NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer,
|
@NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer,
|
||||||
@Nullable ConfigurationHolder<?> holder, @Nullable String path) {
|
@Nullable ConfigurationHolder<?> holder, @Nullable String path) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -103,19 +103,16 @@ public class ValueManifest<TYPE, UNIT> {
|
|||||||
return defaults() != null;
|
return defaults() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull ValueValidator<? super UNIT> validator() {
|
public @NotNull ValueValidator<UNIT> validator() {
|
||||||
return this.validator;
|
return this.validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validator(@NotNull ValueValidator<? super UNIT> validator) {
|
public void validator(@NotNull ValueValidator<UNIT> validator) {
|
||||||
this.validator = validator;
|
this.validator = validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate(@NotNull ValueValidator<? super UNIT> validator) {
|
public void validate(@NotNull ValueValidator<UNIT> validator) {
|
||||||
validator((h, v) -> {
|
validator(this.validator.and(validator));
|
||||||
this.validator.validate(h, v);
|
|
||||||
validator.validate(h, v);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UNIT withValidated(@Nullable UNIT value) throws Exception {
|
protected UNIT withValidated(@Nullable UNIT value) throws Exception {
|
||||||
@@ -151,6 +148,15 @@ public class ValueManifest<TYPE, UNIT> {
|
|||||||
config().set(path(), value);
|
config().set(path(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void throwing(@NotNull Throwable throwable) {
|
||||||
|
throwing(path, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void throwing(@NotNull String path, @NotNull Throwable throwable) {
|
||||||
|
if (holder == null) throwable.printStackTrace();
|
||||||
|
else holder.throwing(path, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
private static final @NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> EMPTY_INITIALIZER = (provider, valuePath) -> {
|
private static final @NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> EMPTY_INITIALIZER = (provider, valuePath) -> {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -87,20 +87,25 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
|
|||||||
if (!cacheExpired()) return getCachedOrDefault(createList());
|
if (!cacheExpired()) return getCachedOrDefault(createList());
|
||||||
// Data that is outdated and needs to be parsed again.
|
// Data that is outdated and needs to be parsed again.
|
||||||
List<V> list = createList();
|
List<V> list = createList();
|
||||||
|
try {
|
||||||
List<?> data = config().contains(path()) ? config().getList(path()) : null;
|
List<?> data = config().contains(path()) ? config().getList(path()) : null;
|
||||||
if (data == null) return getDefaultFirst(list);
|
if (data == null) return getDefaultFirst(list);
|
||||||
|
|
||||||
ValueParser<V> parser = parser();
|
ValueParser<V> parser = parser();
|
||||||
if (parser == null) return getDefaultFirst(list);
|
if (parser == null) return getDefaultFirst(list);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
for (Object dataVal : data) {
|
for (Object dataVal : data) {
|
||||||
if (dataVal == null) continue;
|
if (dataVal == null) continue;
|
||||||
try {
|
try {
|
||||||
list.add(withValidated(parser.parse(holder(), paramType(), dataVal)));
|
list.add(withValidated(parser.parse(holder(), paramType(), dataVal)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
throwing(path + "[" + i + "]", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throwing(ex);
|
||||||
|
}
|
||||||
return updateCache(list);
|
return updateCache(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +126,7 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
|
|||||||
try {
|
try {
|
||||||
data.add(serializer.serialize(holder(), paramType(), withValidated(val)));
|
data.add(serializer.serialize(holder(), paramType(), withValidated(val)));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
throwing(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setData(data);
|
setData(data);
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> impleme
|
|||||||
// If the value is expired, we need to update it
|
// If the value is expired, we need to update it
|
||||||
Map<K, V> map = createMap();
|
Map<K, V> map = createMap();
|
||||||
|
|
||||||
|
try {
|
||||||
ConfigureSection section = config().getSection(path());
|
ConfigureSection section = config().getSection(path());
|
||||||
if (section == null) return getDefaultFirst(map);
|
if (section == null) return getDefaultFirst(map);
|
||||||
|
|
||||||
@@ -96,9 +97,12 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> impleme
|
|||||||
V value = valueParser.parse(holder(), valueType(), dataVal);
|
V value = valueParser.parse(holder(), valueType(), dataVal);
|
||||||
map.put(key, withValidated(value));
|
map.put(key, withValidated(value));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
throwing(path + "." + dataKey, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throwing(ex);
|
||||||
|
}
|
||||||
|
|
||||||
return updateCache(map);
|
return updateCache(map);
|
||||||
}
|
}
|
||||||
@@ -120,6 +124,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> impleme
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
ValueSerializer<K> keySerializer = serializerFor(keyAdapter);
|
ValueSerializer<K> keySerializer = serializerFor(keyAdapter);
|
||||||
if (keySerializer == null) return;
|
if (keySerializer == null) return;
|
||||||
ValueSerializer<V> valueSerializer = serializerFor(valueAdapter);
|
ValueSerializer<V> valueSerializer = serializerFor(valueAdapter);
|
||||||
@@ -134,10 +139,13 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> impleme
|
|||||||
valueSerializer.serialize(holder(), valueType(), withValidated(entry.getValue()))
|
valueSerializer.serialize(holder(), valueType(), withValidated(entry.getValue()))
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
throwing(path + "." + entry.getKey(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setData(data);
|
setData(data);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throwing(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> @NotNull T handle(Function<Map<K, V>, T> function) {
|
public <T> @NotNull T handle(Function<Map<K, V>, T> function) {
|
||||||
|
|||||||
@@ -137,20 +137,19 @@ public class ConfiguredValue<V> extends CachedConfigValue<V, V> {
|
|||||||
if (!cacheExpired()) return getCachedOrDefault();
|
if (!cacheExpired()) return getCachedOrDefault();
|
||||||
// Data that is outdated and needs to be parsed again.
|
// Data that is outdated and needs to be parsed again.
|
||||||
|
|
||||||
|
try {
|
||||||
Object data = getData();
|
Object data = getData();
|
||||||
if (data == null) return defaults();
|
if (data == null) return defaults();
|
||||||
|
|
||||||
ValueParser<V> parser = parser();
|
ValueParser<V> parser = parser();
|
||||||
if (parser == null) return defaults(); // No parser, return default value.
|
if (parser == null) return defaults(); // No parser, return default value.
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
// If there are no errors, update the cache and return.
|
// If there are no errors, update the cache and return.
|
||||||
V parsed = parser.parse(holder(), type(), data);
|
V parsed = parser.parse(holder(), type(), data);
|
||||||
return updateCache(withValidated(parsed));
|
return updateCache(withValidated(parsed));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// There was a validate or parsing error, prompted and returned the default value.
|
// There was a validate or parsing error, prompted and returned the default value.
|
||||||
e.printStackTrace();
|
throwing(e);
|
||||||
return defaults();
|
return defaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,13 +169,13 @@ public class ConfiguredValue<V> extends CachedConfigValue<V, V> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
ValueSerializer<V> serializer = serializer();
|
ValueSerializer<V> serializer = serializer();
|
||||||
if (serializer == null) return; // No serializer, do nothing.
|
if (serializer == null) return; // No serializer, do nothing.
|
||||||
|
|
||||||
try {
|
|
||||||
setData(serializer.serialize(holder(), type(), withValidated(value)));
|
setData(serializer.serialize(holder(), type(), withValidated(value)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
throwing(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
<artifactId>configured-demo</artifactId>
|
<artifactId>configured-demo</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@@ -40,6 +41,13 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.parent.groupId}</groupId>
|
||||||
|
<artifactId>configured-feature-validators</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package cc.carm.lib.configuration.demo;
|
|||||||
import cc.carm.lib.configuration.Configuration;
|
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.HeaderComments;
|
import cc.carm.lib.configuration.annotation.HeaderComments;
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
|
|
||||||
@HeaderComments({"", "数据库配置", " 用于提供数据库连接,进行数据库操作。"})
|
@HeaderComments({"", "数据库配置", " 用于提供数据库连接,进行数据库操作。"})
|
||||||
@@ -16,17 +15,17 @@ public interface DatabaseConfiguration extends Configuration {
|
|||||||
"- MySQL(新): com.mysql.cj.jdbc.Driver",
|
"- MySQL(新): com.mysql.cj.jdbc.Driver",
|
||||||
"- MariaDB(推荐): org.mariadb.jdbc.Driver",
|
"- MariaDB(推荐): org.mariadb.jdbc.Driver",
|
||||||
})
|
})
|
||||||
ConfigValue<String> DRIVER_NAME = ConfiguredValue.of(
|
ConfiguredValue<String> DRIVER_NAME = ConfiguredValue.of(
|
||||||
String.class, "com.mysql.cj.jdbc.Driver"
|
String.class, "com.mysql.cj.jdbc.Driver"
|
||||||
);
|
);
|
||||||
|
|
||||||
ConfigValue<String> HOST = ConfiguredValue.of(String.class, "127.0.0.1");
|
ConfiguredValue<String> HOST = ConfiguredValue.of(String.class, "127.0.0.1");
|
||||||
ConfigValue<Integer> PORT = ConfiguredValue.of(Integer.class, 3306);
|
ConfiguredValue<Integer> PORT = ConfiguredValue.of(Integer.class, 3306);
|
||||||
ConfigValue<String> DATABASE = ConfiguredValue.of(String.class, "minecraft");
|
ConfiguredValue<String> DATABASE = ConfiguredValue.of(String.class, "minecraft");
|
||||||
ConfigValue<String> USERNAME = ConfiguredValue.of(String.class, "root");
|
ConfiguredValue<String> USERNAME = ConfiguredValue.of(String.class, "root");
|
||||||
ConfigValue<String> PASSWORD = ConfiguredValue.of(String.class, "password");
|
ConfiguredValue<String> PASSWORD = ConfiguredValue.of(String.class, "password");
|
||||||
|
|
||||||
ConfigValue<String> EXTRA = ConfiguredValue.of(String.class, "?useSSL=false");
|
ConfiguredValue<String> EXTRA = ConfiguredValue.of(String.class, "?useSSL=false");
|
||||||
|
|
||||||
static String buildJDBC() {
|
static String buildJDBC() {
|
||||||
return String.format("jdbc:mysql://%s:%s/%s%s", HOST.get(), PORT.get(), DATABASE.get(), EXTRA.get());
|
return String.format("jdbc:mysql://%s:%s/%s%s", HOST.get(), PORT.get(), DATABASE.get(), EXTRA.get());
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ public interface DemoConfiguration extends Configuration {
|
|||||||
|
|
||||||
@ConfigPath(root = true)
|
@ConfigPath(root = true)
|
||||||
@FooterComments({"此处内容将显示在配置条目的下方", "可用于补充说明,但一般不建议使用"})
|
@FooterComments({"此处内容将显示在配置条目的下方", "可用于补充说明,但一般不建议使用"})
|
||||||
ConfiguredValue<Long> TEST_NUMBER = ConfiguredValue.with(Long.class)
|
ConfiguredValue<Long> TEST_NUMBER = ConfiguredValue.with(Long.class).defaults(123456789L).build();
|
||||||
.validate(l -> l > 100, "数值必须大于100")
|
|
||||||
.validate(l -> l < 100000000, "数值必须小于100000000")
|
|
||||||
.defaults(123456789L).build();
|
|
||||||
|
|
||||||
@HeaderComments({"枚举类型测试"})
|
@HeaderComments({"枚举类型测试"})
|
||||||
@FooterComments({"上述的枚举内容本质上是通过STRING解析的"})
|
@FooterComments({"上述的枚举内容本质上是通过STRING解析的"})
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ package cc.carm.lib.configuration.demo.tests.conf;
|
|||||||
|
|
||||||
import cc.carm.lib.configuration.Configuration;
|
import cc.carm.lib.configuration.Configuration;
|
||||||
import cc.carm.lib.configuration.annotation.HeaderComments;
|
import cc.carm.lib.configuration.annotation.HeaderComments;
|
||||||
|
import cc.carm.lib.configuration.annotation.ValueRange;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
|
|
||||||
@HeaderComments("Inner Test")
|
@HeaderComments("service")
|
||||||
public class InstanceConfig implements Configuration {
|
public class InstanceConfig implements Configuration {
|
||||||
|
|
||||||
|
@ValueRange(min = 0, max = 100, message = "The value must be between 0 and 100")
|
||||||
public final ConfiguredValue<Double> STATUS = ConfiguredValue.of(1.0D);
|
public final ConfiguredValue<Double> STATUS = ConfiguredValue.of(1.0D);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -11,7 +11,11 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
public class Validators {
|
public class Validators {
|
||||||
|
|
||||||
public static void initialize(ConfigurationHolder<?> holder) {
|
private Validators() {
|
||||||
|
throw new UnsupportedOperationException("API Register.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void activate(ConfigurationHolder<?> holder) {
|
||||||
holder.initializer().registerValidAnnotation(ValueRange.class, r -> (ho, value) -> {
|
holder.initializer().registerValidAnnotation(ValueRange.class, r -> (ho, value) -> {
|
||||||
if (!(value instanceof Number)) {
|
if (!(value instanceof Number)) {
|
||||||
throw new IllegalArgumentException("Value is not a number: " + value);
|
throw new IllegalArgumentException("Value is not a number: " + value);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package config;
|
package config;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||||
import cc.carm.lib.configuration.source.json.JSONConfigFactory;
|
|
||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
import cc.carm.lib.configuration.source.json.JSONConfigFactory;
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -18,12 +16,6 @@ public class JSONConfigTest {
|
|||||||
|
|
||||||
@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);
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package yaml.test;
|
package yaml.test;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.commentable.Commentable;
|
|
||||||
import cc.carm.lib.configuration.commentable.CommentableMeta;
|
import cc.carm.lib.configuration.commentable.CommentableMeta;
|
||||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
import cc.carm.lib.configuration.source.yaml.YAMLConfigFactory;
|
import cc.carm.lib.configuration.source.yaml.YAMLConfigFactory;
|
||||||
import cc.carm.lib.configuration.source.yaml.YAMLSource;
|
import cc.carm.lib.configuration.source.yaml.YAMLSource;
|
||||||
|
import cc.carm.lib.configuration.validators.Validators;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -19,6 +19,8 @@ public class YamlTests {
|
|||||||
ConfigurationHolder<YAMLSource> holder = YAMLConfigFactory.from("target/tests.yml")
|
ConfigurationHolder<YAMLSource> holder = YAMLConfigFactory.from("target/tests.yml")
|
||||||
.resourcePath("configs/sample.yml").build();
|
.resourcePath("configs/sample.yml").build();
|
||||||
|
|
||||||
|
Validators.activate(holder);
|
||||||
|
|
||||||
ConfigurationTest.testDemo(holder);
|
ConfigurationTest.testDemo(holder);
|
||||||
ConfigurationTest.testInner(holder);
|
ConfigurationTest.testInner(holder);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user