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

feat(validator): Support validators for config values.

BREAKING CHANGE: `ValueManifest` and `ConfigValue` added a new type "UNIT" to mark the minimal unit value of this instance.

link #132
This commit is contained in:
2025-03-16 23:56:36 +08:00
parent 854e3df49f
commit fae048dd69
52 changed files with 577 additions and 166 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.0</version> <version>4.1.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<properties> <properties>
@@ -15,6 +15,7 @@ public class ValueAdapter<TYPE>
implements ValueSerializer<TYPE>, ValueParser<TYPE> { implements ValueSerializer<TYPE>, ValueParser<TYPE> {
protected final @NotNull ValueType<TYPE> type; protected final @NotNull ValueType<TYPE> type;
protected @Nullable ValueSerializer<TYPE> serializer; protected @Nullable ValueSerializer<TYPE> serializer;
protected @Nullable ValueParser<TYPE> deserializer; protected @Nullable ValueParser<TYPE> deserializer;
@@ -53,13 +54,17 @@ public class ValueAdapter<TYPE>
} }
@Override @Override
public Object serialize(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<? super TYPE> type, @NotNull TYPE value) throws Exception { public @Nullable Object serialize(
@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<? super TYPE> type,
@NotNull TYPE value) throws Exception {
if (serializer == null) throw new UnsupportedOperationException("Serializer is not supported"); if (serializer == null) throw new UnsupportedOperationException("Serializer is not supported");
return serializer.serialize(holder, type, value); return serializer.serialize(holder, type, value);
} }
@Override @Override
public TYPE parse(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<? super TYPE> type, @NotNull Object value) throws Exception { public @Nullable TYPE parse(
@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<? super TYPE> type,
@NotNull Object value) throws Exception {
if (deserializer == null) throw new UnsupportedOperationException("Deserializer is not supported"); if (deserializer == null) throw new UnsupportedOperationException("Deserializer is not supported");
return deserializer.parse(holder, type, value); return deserializer.parse(holder, type, value);
} }
@@ -61,7 +61,9 @@ public class ValueAdapterRegistry {
} }
} }
public <T> void register(@NotNull ValueType<T> type, @Nullable ValueSerializer<T> serializer, @Nullable ValueParser<T> deserializer) { public <T> void register(@NotNull ValueType<T> type,
@Nullable ValueSerializer<T> serializer,
@Nullable ValueParser<T> deserializer) {
if (serializer == null && deserializer == null) return; if (serializer == null && deserializer == null) return;
ValueAdapter<T> existing = adapterOf(type); ValueAdapter<T> existing = adapterOf(type);
if (existing != null) { if (existing != null) {
@@ -2,6 +2,7 @@ package cc.carm.lib.configuration.adapter;
import cc.carm.lib.configuration.source.ConfigurationHolder; import cc.carm.lib.configuration.source.ConfigurationHolder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** /**
* Value deserializer, convert base data to target value. * Value deserializer, convert base data to target value.
@@ -11,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
@FunctionalInterface @FunctionalInterface
public interface ValueParser<TYPE> { public interface ValueParser<TYPE> {
TYPE parse( @Nullable TYPE parse(
@NotNull ConfigurationHolder<?> holder, @NotNull ConfigurationHolder<?> holder,
@NotNull ValueType<? super TYPE> type, @NotNull Object data @NotNull ValueType<? super TYPE> type, @NotNull Object data
) throws Exception; ) throws Exception;
@@ -2,6 +2,7 @@ package cc.carm.lib.configuration.adapter;
import cc.carm.lib.configuration.source.ConfigurationHolder; import cc.carm.lib.configuration.source.ConfigurationHolder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** /**
* Value serializer, convert target value to base data. * Value serializer, convert target value to base data.
@@ -11,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
@FunctionalInterface @FunctionalInterface
public interface ValueSerializer<TYPE> { public interface ValueSerializer<TYPE> {
Object serialize( @Nullable Object serialize(
@NotNull ConfigurationHolder<?> holder, @NotNull ConfigurationHolder<?> holder,
@NotNull ValueType<? super TYPE> type, @NotNull TYPE value @NotNull ValueType<? super TYPE> type, @NotNull TYPE value
) throws Exception; ) throws Exception;
@@ -5,6 +5,8 @@ import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.source.section.ConfigureSection; import cc.carm.lib.configuration.source.section.ConfigureSection;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.UUID;
import static cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapter.*; import static cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapter.*;
public interface StandardAdapters { public interface StandardAdapters {
@@ -17,6 +19,12 @@ public interface StandardAdapters {
@NotNull ValueAdapter<Enum<?>> ENUMS = PrimitiveAdapter.ofEnum(); @NotNull ValueAdapter<Enum<?>> ENUMS = PrimitiveAdapter.ofEnum();
@NotNull ValueAdapter<UUID> UUID = new ValueAdapter<>(
ValueType.of(UUID.class),
(provider, type, value) -> value.toString(),
(provider, type, value) -> java.util.UUID.fromString(value.toString())
);
@NotNull ValueAdapter<ConfigureSection> SECTIONS = new ValueAdapter<>( @NotNull ValueAdapter<ConfigureSection> SECTIONS = new ValueAdapter<>(
ValueType.of(ConfigureSection.class), ValueType.of(ConfigureSection.class),
(provider, type, value) -> value, (provider, type, value) -> value,
@@ -0,0 +1,21 @@
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());
}
});
});
}
}
@@ -1,21 +1,26 @@
package cc.carm.lib.configuration.builder; package cc.carm.lib.configuration.builder;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.function.DataValidator;
import cc.carm.lib.configuration.function.ValueValidator;
import cc.carm.lib.configuration.source.ConfigurationHolder; import cc.carm.lib.configuration.source.ConfigurationHolder;
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;
import cc.carm.lib.configuration.value.ConfigValue; import cc.carm.lib.configuration.value.ConfigValue;
import cc.carm.lib.configuration.value.ValueManifest; import cc.carm.lib.configuration.value.ValueManifest;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.NotNullByDefault;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
@NotNullByDefault
public abstract class AbstractConfigBuilder< public abstract class AbstractConfigBuilder<
TYPE, RESULT extends ConfigValue<TYPE>, HOLDER extends ConfigurationHolder<?>, TYPE, UNIT, RESULT extends ConfigValue<TYPE, UNIT>, HOLDER extends ConfigurationHolder<?>,
SELF extends AbstractConfigBuilder<TYPE, RESULT, HOLDER, SELF> SELF extends AbstractConfigBuilder<TYPE, UNIT, RESULT, HOLDER, SELF>
> { > {
protected final Class<? super HOLDER> providerClass; protected final Class<? super HOLDER> providerClass;
@@ -24,6 +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 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) -> {
}; };
@@ -37,54 +43,124 @@ public abstract class AbstractConfigBuilder<
return type; return type;
} }
protected abstract @NotNull SELF self(); protected abstract SELF self();
public abstract @NotNull RESULT build(); public abstract @NotNull RESULT build();
public @NotNull SELF holder(@Nullable HOLDER holder) { public SELF holder(@Nullable HOLDER holder) {
this.holder = holder; this.holder = holder;
return self(); return self();
} }
public @NotNull SELF path(@Nullable String path) { public SELF path(@Nullable String path) {
this.path = path; this.path = path;
return self(); return self();
} }
public @NotNull SELF initializer(@NotNull BiConsumer<ConfigurationHolder<?>, String> initializer) { /**
* Set the {@link ValueValidator} for the value.
*
* @param validator The validator to set.
* @return this builder
*/
public SELF validator(@NotNull ValueValidator<? super UNIT> validator) {
this.valueValidator = validator;
return self();
}
/**
* Set the {@link DataValidator} for the value.
*
* @param validator The validator to set.
* @return this builder
*/
public SELF validator(@NotNull DataValidator<? super UNIT> validator) {
return validator((h, value) -> validator.validate(value));
}
/**
* Validate the value with the specified condition.
*
* @param validator The validator to set.
* @return this builder
*/
public SELF validate(@NotNull ValueValidator<? super UNIT> validator) {
return validator((h, v) -> {
this.valueValidator.validate(h, v);
validator.validate(h, v);
});
}
/**
* Validate the value with the specified condition.
*
* @param validator The validator to set.
* @return this builder
*/
public SELF validate(@NotNull DataValidator<? super UNIT> validator) {
return validate((h, value) -> validator.validate(value));
}
/**
* Validate the value with the specified condition.
*
* @param condition The condition to check, if the condition is false, an exception will be thrown.
* @param exception The exception to throw if the condition is false.
* @return this builder
*/
public SELF validate(@NotNull Predicate<? super UNIT> condition, @NotNull Exception exception) {
return validate((h, value) -> {
if (!condition.test(value)) throw exception;
});
}
/**
* Validate the value with the specified condition.
*
* @param condition The condition to check, if the condition is false, an exception will be thrown.
* @param msg The message to throw if the condition is false.
* @return this builder
*/
public SELF validate(@NotNull Predicate<? super UNIT> condition, @NotNull String msg) {
return validate((h, value) -> {
if (!condition.test(value)) throw new IllegalArgumentException(msg);
});
}
public SELF initializer(@NotNull BiConsumer<ConfigurationHolder<?>, String> initializer) {
this.initializer = initializer; this.initializer = initializer;
return self(); return self();
} }
public @NotNull SELF append(@NotNull BiConsumer<ConfigurationHolder<?>, String> initializer) { public SELF append(@NotNull BiConsumer<ConfigurationHolder<?>, String> initializer) {
return initializer(initializer.andThen(initializer)); return initializer(initializer.andThen(initializer));
} }
public @NotNull SELF append(@NotNull Consumer<ConfigurationHolder<?>> initializer) { public SELF append(@NotNull Consumer<ConfigurationHolder<?>> initializer) {
return append((provider, valuePath) -> initializer.accept(provider)); return append((provider, valuePath) -> initializer.accept(provider));
} }
public @NotNull SELF defaults(@Nullable TYPE defaultValue) { public SELF defaults(@Nullable TYPE defaultValue) {
return defaults(() -> defaultValue); return defaults(() -> defaultValue);
} }
public @NotNull SELF defaults(@NotNull Supplier<@Nullable TYPE> supplier) { public SELF defaults(@NotNull Supplier<@Nullable TYPE> supplier) {
this.defaultValueSupplier = supplier; this.defaultValueSupplier = supplier;
return self(); return self();
} }
public <M> @NotNull SELF meta(@NotNull Consumer<@NotNull ConfigurationMetaHolder> metaConsumer) { public SELF meta(@NotNull Consumer<@NotNull ConfigurationMetaHolder> metaConsumer) {
return append((h, p) -> metaConsumer.accept(h.metadata(p))); return append((h, p) -> metaConsumer.accept(h.metadata(p)));
} }
public <M> @NotNull SELF meta(@NotNull ConfigurationMetadata<M> type, @Nullable M value) { public <M> SELF meta(@NotNull ConfigurationMetadata<M> type, @Nullable M value) {
return meta(h -> h.set(type, value)); return meta(h -> h.set(type, value));
} }
protected @NotNull ValueManifest<TYPE> buildManifest() { protected @NotNull ValueManifest<TYPE, UNIT> buildManifest() {
return new ValueManifest<>( return new ValueManifest<>(
type(), this.defaultValueSupplier, this.initializer, type(), this.defaultValueSupplier, this.valueValidator,
this.holder, this.path this.initializer, this.holder, this.path
); );
} }
@@ -4,8 +4,11 @@ import cc.carm.lib.configuration.adapter.ValueType;
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.value.ConfigValue;
public abstract class CommonConfigBuilder<TYPE, RESULT extends ConfigValue<TYPE>, SELF extends CommonConfigBuilder<TYPE, RESULT, SELF>> public abstract class CommonConfigBuilder<
extends AbstractConfigBuilder<TYPE, RESULT, ConfigurationHolder<?>, SELF> { TYPE, UNIT,
RESULT extends ConfigValue<TYPE, UNIT>,
SELF extends CommonConfigBuilder<TYPE, UNIT, RESULT, SELF>
> extends AbstractConfigBuilder<TYPE, UNIT, RESULT, ConfigurationHolder<?>, SELF> {
protected CommonConfigBuilder(ValueType<TYPE> type) { protected CommonConfigBuilder(ValueType<TYPE> type) {
super(ConfigurationHolder.class, type); super(ConfigurationHolder.class, type);
@@ -4,7 +4,7 @@ import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.CommonConfigBuilder; import cc.carm.lib.configuration.builder.CommonConfigBuilder;
import cc.carm.lib.configuration.function.DataFunction; import cc.carm.lib.configuration.function.DataFunction;
import cc.carm.lib.configuration.function.ValueConsumer; import cc.carm.lib.configuration.function.ValueComposer;
import cc.carm.lib.configuration.function.ValueHandler; import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection; import cc.carm.lib.configuration.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.ConfigValue; import cc.carm.lib.configuration.value.ConfigValue;
@@ -14,45 +14,45 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
public abstract class AbstractSectionBuilder< public abstract class AbstractSectionBuilder<
TYPE, PARAM, TYPE, UNIT,
RESULT extends ConfigValue<TYPE>, RESULT extends ConfigValue<TYPE, UNIT>,
SELF extends AbstractSectionBuilder<TYPE, PARAM, RESULT, SELF> SELF extends AbstractSectionBuilder<TYPE, UNIT, RESULT, SELF>
> extends CommonConfigBuilder<TYPE, RESULT, SELF> { > extends CommonConfigBuilder<TYPE, UNIT, RESULT, SELF> {
protected final @NotNull ValueType<PARAM> paramType; protected final @NotNull ValueType<UNIT> paramType;
protected @NotNull ValueHandler<ConfigureSection, PARAM> parser; protected @NotNull ValueHandler<ConfigureSection, UNIT> parser;
protected @NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer; protected @NotNull ValueHandler<UNIT, ? extends Map<String, Object>> serializer;
protected AbstractSectionBuilder(@NotNull ValueType<TYPE> type, @NotNull ValueType<PARAM> paramType, protected AbstractSectionBuilder(@NotNull ValueType<TYPE> type, @NotNull ValueType<UNIT> paramType,
@NotNull ValueHandler<ConfigureSection, PARAM> parser, @NotNull ValueHandler<ConfigureSection, UNIT> parser,
@NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer) { @NotNull ValueHandler<UNIT, ? extends Map<String, Object>> serializer) {
super(type); super(type);
this.paramType = paramType; this.paramType = paramType;
this.parser = parser; this.parser = parser;
this.serializer = serializer; this.serializer = serializer;
} }
public @NotNull SELF parse(@NotNull DataFunction<ConfigureSection, PARAM> valueParser) { public @NotNull SELF parse(@NotNull DataFunction<ConfigureSection, UNIT> valueParser) {
return parse((p, section) -> valueParser.handle(section)); return parse((p, section) -> valueParser.handle(section));
} }
public @NotNull SELF parse(@NotNull ValueHandler<ConfigureSection, PARAM> valueParser) { public @NotNull SELF parse(@NotNull ValueHandler<ConfigureSection, UNIT> valueParser) {
this.parser = valueParser; this.parser = valueParser;
return self(); return self();
} }
public @NotNull SELF serialize(@NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer) { public @NotNull SELF serialize(@NotNull ValueHandler<UNIT, ? extends Map<String, Object>> serializer) {
this.serializer = serializer; this.serializer = serializer;
return self(); return self();
} }
public @NotNull SELF serialize(@NotNull DataFunction<PARAM, ? extends Map<String, Object>> serializer) { public @NotNull SELF serialize(@NotNull DataFunction<UNIT, ? extends Map<String, Object>> serializer) {
return serialize((p, value) -> serializer.handle(value)); return serialize((p, value) -> serializer.handle(value));
} }
public @NotNull SELF serialize(@NotNull ValueConsumer<Map<String, Object>, PARAM> serializer) { public @NotNull SELF serialize(@NotNull ValueComposer<Map<String, Object>, UNIT> serializer) {
return serialize((h, value) -> { return serialize((h, value) -> {
Map<String, Object> map = new LinkedHashMap<>(); Map<String, Object> map = new LinkedHashMap<>();
serializer.accept(h, map, value); serializer.accept(h, map, value);
@@ -60,7 +60,7 @@ public abstract class AbstractSectionBuilder<
}); });
} }
protected ValueAdapter<PARAM> buildAdapter() { protected ValueAdapter<UNIT> buildAdapter() {
return new ValueAdapter<>(this.paramType) return new ValueAdapter<>(this.paramType)
.parser((p, type, data) -> { .parser((p, type, data) -> {
ConfigureSection section = p.deserialize(ConfigureSection.class, data); ConfigureSection section = p.deserialize(ConfigureSection.class, data);
@@ -9,19 +9,19 @@ import cc.carm.lib.configuration.value.ConfigValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public abstract class AbstractSourceBuilder< public abstract class AbstractSourceBuilder<
V, SOURCE, PARAM, RESULT extends ConfigValue<V>, V, SOURCE, UNIT, RESULT extends ConfigValue<V, UNIT>,
SELF extends AbstractSourceBuilder<V, SOURCE, PARAM, RESULT, SELF> SELF extends AbstractSourceBuilder<V, SOURCE, UNIT, RESULT, SELF>
> extends CommonConfigBuilder<V, RESULT, SELF> { > extends CommonConfigBuilder<V, UNIT, RESULT, SELF> {
protected final @NotNull ValueType<SOURCE> sourceType; protected final @NotNull ValueType<SOURCE> sourceType;
protected final @NotNull ValueType<PARAM> paramType; protected final @NotNull ValueType<UNIT> paramType;
protected @NotNull ValueHandler<SOURCE, PARAM> valueParser; protected @NotNull ValueHandler<SOURCE, UNIT> valueParser;
protected @NotNull ValueHandler<PARAM, SOURCE> valueSerializer; protected @NotNull ValueHandler<UNIT, SOURCE> valueSerializer;
protected AbstractSourceBuilder(@NotNull ValueType<V> type, protected AbstractSourceBuilder(@NotNull ValueType<V> type,
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<PARAM> paramType, @NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<UNIT> paramType,
@NotNull ValueHandler<SOURCE, PARAM> parser, @NotNull ValueHandler<SOURCE, UNIT> parser,
@NotNull ValueHandler<PARAM, SOURCE> serializer) { @NotNull ValueHandler<UNIT, SOURCE> serializer) {
super(type); super(type);
this.sourceType = sourceType; this.sourceType = sourceType;
this.paramType = paramType; this.paramType = paramType;
@@ -29,25 +29,25 @@ public abstract class AbstractSourceBuilder<
this.valueSerializer = serializer; this.valueSerializer = serializer;
} }
public @NotNull SELF parse(@NotNull DataFunction<SOURCE, PARAM> parser) { public @NotNull SELF parse(@NotNull DataFunction<SOURCE, UNIT> parser) {
return parse((p, source) -> parser.handle(source)); return parse((p, source) -> parser.handle(source));
} }
public @NotNull SELF parse(@NotNull ValueHandler<SOURCE, PARAM> parser) { public @NotNull SELF parse(@NotNull ValueHandler<SOURCE, UNIT> parser) {
this.valueParser = parser; this.valueParser = parser;
return self(); return self();
} }
public @NotNull SELF serialize(@NotNull ValueHandler<PARAM, SOURCE> serializer) { public @NotNull SELF serialize(@NotNull ValueHandler<UNIT, SOURCE> serializer) {
this.valueSerializer = serializer; this.valueSerializer = serializer;
return self(); return self();
} }
public @NotNull SELF serialize(@NotNull DataFunction<PARAM, SOURCE> serializer) { public @NotNull SELF serialize(@NotNull DataFunction<UNIT, SOURCE> serializer) {
return serialize((p, value) -> serializer.handle(value)); return serialize((p, value) -> serializer.handle(value));
} }
protected ValueAdapter<PARAM> buildAdapter() { protected ValueAdapter<UNIT> buildAdapter() {
return new ValueAdapter<>(this.paramType) return new ValueAdapter<>(this.paramType)
.parser((holder, type, data) -> { .parser((holder, type, data) -> {
SOURCE source = holder.deserialize(this.sourceType, data); SOURCE source = holder.deserialize(this.sourceType, data);
@@ -8,9 +8,11 @@ import cc.carm.lib.configuration.value.standard.ConfiguredList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class SectionListBuilder<V> extends AbstractSectionBuilder<List<V>, V, ConfiguredList<V>, SectionListBuilder<V>> { public class SectionListBuilder<V>
extends AbstractSectionBuilder<List<V>, V, ConfiguredList<V>, SectionListBuilder<V>> {
protected @NotNull Supplier<? extends List<V>> constructor; protected @NotNull Supplier<? extends List<V>> constructor;
@@ -32,6 +34,14 @@ public class SectionListBuilder<V> extends AbstractSectionBuilder<List<V>, V, Co
return defaults(new ArrayList<>(values)); return defaults(new ArrayList<>(values));
} }
public final @NotNull SectionListBuilder<V> defaults(@NotNull Consumer<List<V>> constructor) {
return defaults(() -> {
List<V> list = new ArrayList<>();
constructor.accept(list);
return list;
});
}
public SectionListBuilder<V> constructor(@NotNull Supplier<? extends List<V>> constructor) { public SectionListBuilder<V> constructor(@NotNull Supplier<? extends List<V>> constructor) {
this.constructor = constructor; this.constructor = constructor;
return this; return this;
@@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class SourceListBuilder<SOURCE, V> public class SourceListBuilder<SOURCE, V>
@@ -34,6 +35,23 @@ public class SourceListBuilder<SOURCE, V>
return defaults(new ArrayList<>(values)); return defaults(new ArrayList<>(values));
} }
public final @NotNull SourceListBuilder<SOURCE, V> defaults(@NotNull Consumer<List<V>> constructor) {
return defaults(() -> {
List<V> list = new ArrayList<>();
constructor.accept(list);
return list;
});
}
public SourceListBuilder<SOURCE, V> constructor(@NotNull Supplier<? extends List<V>> constructor) {
this.constructor = constructor;
return this;
}
public <LIST extends List<V>> SourceListBuilder<SOURCE, V> construct(@NotNull LIST list) {
return constructor(() -> list);
}
@Override @Override
protected @NotNull SourceListBuilder<SOURCE, V> self() { protected @NotNull SourceListBuilder<SOURCE, V> self() {
return this; return this;
@@ -14,10 +14,7 @@ import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class SectionMapBuilder<MAP extends Map<K, V>, K, V> public class SectionMapBuilder<MAP extends Map<K, V>, K, V>
extends AbstractSectionBuilder< extends AbstractSectionBuilder<Map<K, V>, V, ConfiguredMap<K, V>, SectionMapBuilder<MAP, K, V>> {
Map<K, V>, V, ConfiguredMap<K, V>,
SectionMapBuilder<MAP, K, V>
> {
protected final @NotNull ValueType<K> keyType; protected final @NotNull ValueType<K> keyType;
@@ -13,10 +13,7 @@ import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class SourceMapBuilder<MAP extends Map<K, V>, SOURCE, K, V> public class SourceMapBuilder<MAP extends Map<K, V>, SOURCE, K, V>
extends AbstractSourceBuilder< extends AbstractSourceBuilder<Map<K, V>, SOURCE, V, ConfiguredMap<K, V>, SourceMapBuilder<MAP, SOURCE, K, V>> {
Map<K, V>, SOURCE, V, ConfiguredMap<K, V>,
SourceMapBuilder<MAP, SOURCE, K, V>
> {
protected final @NotNull ValueType<K> keyType; protected final @NotNull ValueType<K> keyType;
@@ -1,7 +1,6 @@
package cc.carm.lib.configuration.builder.value; package cc.carm.lib.configuration.builder.value;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
import cc.carm.lib.configuration.function.ValueHandler; import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection; import cc.carm.lib.configuration.source.section.ConfigureSection;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -6,7 +6,8 @@ import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.value.standard.ConfiguredValue; import cc.carm.lib.configuration.value.standard.ConfiguredValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class SourceValueBuilder<S, V> extends AbstractSourceBuilder<V, S, V, ConfiguredValue<V>, SourceValueBuilder<S, V>> { public class SourceValueBuilder<S, V>
extends AbstractSourceBuilder<V, S, V, ConfiguredValue<V>, SourceValueBuilder<S, V>> {
public SourceValueBuilder(@NotNull ValueType<S> sourceType, @NotNull ValueType<V> valueType, public SourceValueBuilder(@NotNull ValueType<S> sourceType, @NotNull ValueType<V> valueType,
@@ -0,0 +1,17 @@
package cc.carm.lib.configuration.function;
import org.jetbrains.annotations.Nullable;
@FunctionalInterface
public interface DataValidator<T> {
void validate(@Nullable T value) throws Exception;
default DataValidator<T> compose(DataValidator<? super T> other) {
return value -> {
validate(value);
other.validate(value);
};
}
}
@@ -0,0 +1,29 @@
package cc.carm.lib.configuration.function;
import cc.carm.lib.configuration.source.ConfigurationHolder;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface ValueComposer<T, U> {
/**
* Accept the value and the data, and then compose the value.
*
* @param holder The configuration holder
* @param type The value type, e.g. {@link java.util.List}, {@link java.util.Map}, etc.
* @param data The unit data
* @throws Exception If an error occurs
*/
void accept(@NotNull ConfigurationHolder<?> holder, @NotNull T type, @NotNull U data) throws Exception;
default ValueComposer<T, U> andThen(ValueComposer<? super T, ? super U> after) {
return (holder, unit, data) -> {
accept(holder, unit, data);
after.accept(holder, unit, data);
};
}
}
@@ -1,21 +0,0 @@
package cc.carm.lib.configuration.function;
import cc.carm.lib.configuration.source.ConfigurationHolder;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface ValueConsumer<U, T> {
void accept(@NotNull ConfigurationHolder<?> holder, @NotNull U unit, @NotNull T data) throws Exception;
default ValueConsumer<U, T> andThen(ValueConsumer<? super U, ? super T> after) {
return (holder, unit, data) -> {
accept(holder, unit, data);
after.accept(holder, unit, data);
};
}
}
@@ -0,0 +1,7 @@
package cc.carm.lib.configuration.function;
public interface ValueSupplier {
}
@@ -0,0 +1,47 @@
package cc.carm.lib.configuration.function;
import cc.carm.lib.configuration.source.ConfigurationHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@FunctionalInterface
public interface ValueValidator<T> {
void validate(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception;
default ValueValidator<T> compose(ValueValidator<? super T> other) {
return (holder, value) -> {
validate(holder, value);
other.validate(holder, value);
};
}
static <V> ValueValidator<V> none() {
return (holder, data) -> {
};
}
static <V> ValueValidator<V> nonnull() {
return nonnull("Value cannot be null");
}
static <V> ValueValidator<V> nonnull(String message) {
return (holder, data) -> {
if (data == null) throw new IllegalArgumentException(message);
};
}
static <V extends Number> ValueValidator<V> range(V min, V max) {
return range(min, max, "Value must be in range [" + min + ", " + max + "]");
}
static <V extends Number> ValueValidator<V> range(V min, V max, String message) {
return (holder, data) -> {
if (data.doubleValue() < min.doubleValue() || data.doubleValue() > max.doubleValue()) {
throw new IllegalArgumentException(message);
}
};
}
}
@@ -38,10 +38,11 @@ public abstract class ConfigurationFactory<
protected @NotNull Map<String, ConfigurationMetaHolder> metadata = new HashMap<>(); protected @NotNull Map<String, ConfigurationMetaHolder> metadata = new HashMap<>();
protected ConfigurationInitializer initializer = new ConfigurationInitializer(); protected ConfigurationInitializer initializer = new ConfigurationInitializer();
public ConfigurationFactory() { protected ConfigurationFactory() {
this.adapters.register(StandardAdapters.PRIMITIVES); this.adapters.register(StandardAdapters.PRIMITIVES);
this.adapters.register(StandardAdapters.SECTIONS); this.adapters.register(StandardAdapters.SECTIONS);
this.adapters.register(StandardAdapters.ENUMS); this.adapters.register(StandardAdapters.ENUMS);
this.adapters.register(StandardAdapters.UUID);
} }
protected abstract SELF self(); protected abstract SELF self();
@@ -86,7 +86,7 @@ public abstract class ConfigurationHolder<SOURCE extends ConfigureSource<?, ?, S
@NotNull @NotNull
@UnmodifiableView @UnmodifiableView
public Map<String, ConfigValue<?>> registeredValues() { public Map<String, ConfigValue<?, ?>> registeredValues() {
return extractMetadata(StandardMeta.VALUE); return extractMetadata(StandardMeta.VALUE);
} }
@@ -129,7 +129,7 @@ public abstract class ConfigurationHolder<SOURCE extends ConfigureSource<?, ?, S
} }
} }
public void initialize(@NotNull ValueManifest<?> value) { public void initialize(@NotNull ValueManifest<?, ?> value) {
value.holder(this); value.holder(this);
} }
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
public interface ConfigInitializeHandler<T, V> { public interface ConfigInitializeHandler<T, V> {
static <T, V> ConfigInitializeHandler<T, V> start() { static <T, V> ConfigInitializeHandler<T, V> start() {
return (provider, path, value, instace) -> { return (provider, path, value, instance) -> {
}; };
} }
@@ -21,7 +21,7 @@ import java.util.function.Function;
public class ConfigurationInitializer { public class ConfigurationInitializer {
protected @NotNull PathGenerator pathGenerator; protected @NotNull PathGenerator pathGenerator;
protected @NotNull ConfigInitializeHandler<Field, ConfigValue<?>> valueInitializer; protected @NotNull ConfigInitializeHandler<Field, ConfigValue<?, ?>> valueInitializer;
protected @NotNull ConfigInitializeHandler<Class<? extends Configuration>, Object> classInitializer; protected @NotNull ConfigInitializeHandler<Class<? extends Configuration>, Object> classInitializer;
public ConfigurationInitializer() { public ConfigurationInitializer() {
@@ -29,7 +29,7 @@ public class ConfigurationInitializer {
} }
public ConfigurationInitializer(@NotNull PathGenerator pathGenerator, public ConfigurationInitializer(@NotNull PathGenerator pathGenerator,
@NotNull ConfigInitializeHandler<Field, ConfigValue<?>> valueInitializer, @NotNull ConfigInitializeHandler<Field, ConfigValue<?, ?>> valueInitializer,
@NotNull ConfigInitializeHandler<Class<? extends Configuration>, Object> classInitializer) { @NotNull ConfigInitializeHandler<Class<? extends Configuration>, Object> classInitializer) {
this.pathGenerator = pathGenerator; this.pathGenerator = pathGenerator;
this.valueInitializer = valueInitializer; this.valueInitializer = valueInitializer;
@@ -44,11 +44,11 @@ public class ConfigurationInitializer {
return pathGenerator; return pathGenerator;
} }
public ConfigInitializeHandler<Field, ConfigValue<?>> fieldInitializer() { public ConfigInitializeHandler<Field, ConfigValue<?, ?>> fieldInitializer() {
return valueInitializer; return valueInitializer;
} }
public void fieldInitializer(@NotNull ConfigInitializeHandler<Field, ConfigValue<?>> fieldInitializer) { public void fieldInitializer(@NotNull ConfigInitializeHandler<Field, ConfigValue<?,?>> fieldInitializer) {
this.valueInitializer = fieldInitializer; this.valueInitializer = fieldInitializer;
} }
@@ -60,7 +60,7 @@ public class ConfigurationInitializer {
this.classInitializer = classInitializer; this.classInitializer = classInitializer;
} }
public void appendFieldInitializer(@NotNull ConfigInitializeHandler<Field, ConfigValue<?>> fieldInitializer) { public void appendFieldInitializer(@NotNull ConfigInitializeHandler<Field, ConfigValue<?,?>> fieldInitializer) {
this.valueInitializer = this.valueInitializer.andThen(fieldInitializer); this.valueInitializer = this.valueInitializer.andThen(fieldInitializer);
} }
@@ -163,9 +163,9 @@ public class ConfigurationInitializer {
field.setAccessible(true); field.setAccessible(true);
Object object = field.get(source); Object object = field.get(source);
// //
if (object instanceof ConfigValue<?>) { if (object instanceof ConfigValue<?,?>) {
// 目标是 ConfigValue 实例,进行具体的初始化注入 // 目标是 ConfigValue 实例,进行具体的初始化注入
ConfigValue<?> value = (ConfigValue<?>) object; ConfigValue<?,?> value = (ConfigValue<?,?>) object;
String path = getFieldPath(holder, parent, field); String path = getFieldPath(holder, parent, field);
if (path == null) return; if (path == null) return;
value.initialize(holder, path); value.initialize(holder, path);
@@ -7,6 +7,6 @@ public interface StandardMeta {
/** /**
* To mark the {@link ConfigValue} instance of specific path. * To mark the {@link ConfigValue} instance of specific path.
*/ */
ConfigurationMetadata<ConfigValue<?>> VALUE = ConfigurationMetadata.of(); ConfigurationMetadata<ConfigValue<?, ?>> VALUE = ConfigurationMetadata.of();
} }
@@ -33,9 +33,9 @@ import java.util.Optional;
* @see ValueManifest Base class providing metadata and default value handling * @see ValueManifest Base class providing metadata and default value handling
* @see ConfigurationHolder Responsible for configuration source persistence * @see ConfigurationHolder Responsible for configuration source persistence
*/ */
public abstract class ConfigValue<T> extends ValueManifest<T> { public abstract class ConfigValue<T, U> extends ValueManifest<T, U> {
protected ConfigValue(@NotNull ValueManifest<T> manifest) { protected ConfigValue(@NotNull ValueManifest<T, U> manifest) {
super(manifest); super(manifest);
} }
@@ -1,6 +1,7 @@
package cc.carm.lib.configuration.value; package cc.carm.lib.configuration.value;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.function.ValueValidator;
import cc.carm.lib.configuration.source.ConfigurationHolder; import cc.carm.lib.configuration.source.ConfigurationHolder;
import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder; import cc.carm.lib.configuration.source.meta.ConfigurationMetaHolder;
import cc.carm.lib.configuration.source.section.ConfigureSource; import cc.carm.lib.configuration.source.section.ConfigureSource;
@@ -11,37 +12,48 @@ import org.jetbrains.annotations.Nullable;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ValueManifest<T> { public class ValueManifest<TYPE, UNIT> {
protected final @NotNull ValueType<T> type; protected final @NotNull ValueType<TYPE> type;
protected final @NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer; protected final @NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer;
protected @Nullable ConfigurationHolder<?> holder; protected @Nullable ConfigurationHolder<?> holder;
protected @Nullable String path; // Section path protected @Nullable String path; // Section path
protected @NotNull Supplier<@Nullable T> defaultSupplier; protected @NotNull ValueValidator<? super UNIT> validator;
protected @NotNull Supplier<@Nullable TYPE> defaultSupplier;
public ValueManifest(@NotNull ValueType<T> type) { public ValueManifest(@NotNull ValueType<TYPE> type) {
this(type, () -> null, EMPTY_INITIALIZER, null, null); this(type, () -> null, ValueValidator.none(), EMPTY_INITIALIZER, null, null);
} }
public ValueManifest(@NotNull T defaultValue) { public ValueManifest(@NotNull TYPE defaultValue) {
this(ValueType.of(defaultValue), () -> defaultValue); this(ValueType.of(defaultValue), () -> defaultValue);
} }
public ValueManifest(@NotNull ValueType<T> type, @NotNull Supplier<@Nullable T> defaultSupplier) { public ValueManifest(@NotNull ValueType<TYPE> type, @NotNull Supplier<@Nullable TYPE> defaultSupplier) {
this(type, defaultSupplier, EMPTY_INITIALIZER, null, null); this(type, defaultSupplier, ValueValidator.none(), EMPTY_INITIALIZER, null, null);
} }
public ValueManifest(@NotNull ValueType<T> type, @NotNull Supplier<@Nullable T> defaultSupplier, public ValueManifest(@NotNull ValueType<TYPE> type,
@NotNull Supplier<@Nullable TYPE> defaultSupplier,
@NotNull ValueValidator<? super UNIT> validator) {
this(type, defaultSupplier, validator, EMPTY_INITIALIZER, null, null);
}
public ValueManifest(@NotNull ValueType<TYPE> type, @NotNull Supplier<@Nullable TYPE> defaultSupplier,
@NotNull ValueValidator<? super UNIT> validator,
@NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer) { @NotNull BiConsumer<@NotNull ConfigurationHolder<?>, @NotNull String> initializer) {
this(type, defaultSupplier, initializer, null, null); this(type, defaultSupplier, validator, initializer, null, null);
} }
public ValueManifest(@NotNull ValueType<T> type, @NotNull Supplier<@Nullable T> defaultSupplier, public ValueManifest(@NotNull ValueType<TYPE> type,
@NotNull Supplier<@Nullable TYPE> defaultSupplier,
@NotNull ValueValidator<? super 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;
this.validator = validator;
this.initializer = initializer; this.initializer = initializer;
this.defaultSupplier = defaultSupplier; this.defaultSupplier = defaultSupplier;
this.holder = holder; this.holder = holder;
@@ -49,8 +61,8 @@ public class ValueManifest<T> {
initialize(); initialize();
} }
protected ValueManifest(@NotNull ValueManifest<T> manifest) { protected ValueManifest(@NotNull ValueManifest<TYPE, UNIT> manifest) {
this(manifest.type, manifest.defaultSupplier, manifest.initializer, manifest.holder, manifest.path); this(manifest.type, manifest.defaultSupplier, manifest.validator, manifest.initializer, manifest.holder, manifest.path);
} }
public void initialize(@NotNull ConfigurationHolder<?> holder, @NotNull String path) { public void initialize(@NotNull ConfigurationHolder<?> holder, @NotNull String path) {
@@ -63,7 +75,7 @@ public class ValueManifest<T> {
if (holder != null && path != null) this.initializer.accept(holder, path); if (holder != null && path != null) this.initializer.accept(holder, path);
} }
public @NotNull ValueType<T> type() { public @NotNull ValueType<TYPE> type() {
return this.type; return this.type;
} }
@@ -75,20 +87,40 @@ public class ValueManifest<T> {
this.path = path; this.path = path;
} }
public @Nullable T defaults() { public @Nullable TYPE defaults() {
return this.defaultSupplier.get(); return this.defaultSupplier.get();
} }
public void defaults(@Nullable T defaultValue) { public void defaults(@Nullable TYPE defaultValue) {
defaults(() -> defaultValue); defaults(() -> defaultValue);
} }
public void defaults(@NotNull Supplier<@Nullable T> defaultValue) { public void defaults(@NotNull Supplier<@Nullable TYPE> defaultValue) {
this.defaultSupplier = defaultValue; this.defaultSupplier = defaultValue;
} }
public boolean hasDefaults() { public boolean hasDefaults() {
return this.defaultSupplier.get() != null; return defaults() != null;
}
public @NotNull ValueValidator<? super UNIT> validator() {
return this.validator;
}
public void validator(@NotNull ValueValidator<? super UNIT> validator) {
this.validator = validator;
}
public void validate(@NotNull ValueValidator<? super UNIT> validator) {
validator((h, v) -> {
this.validator.validate(h, v);
validator.validate(h, v);
});
}
protected UNIT withValidated(@Nullable UNIT value) throws Exception {
validator.validate(holder(), value);
return value;
} }
public @NotNull String path() { public @NotNull String path() {
@@ -105,7 +137,7 @@ public class ValueManifest<T> {
return holder().config(); return holder().config();
} }
public ConfigurationMetaHolder metadata() { public @NotNull ConfigurationMetaHolder metadata() {
return holder().metadata(path()); return holder().metadata(path());
} }
@@ -9,12 +9,12 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public abstract class CachedConfigValue<T> extends ConfigValue<T> { public abstract class CachedConfigValue<T, U> extends ConfigValue<T, U> {
protected @Nullable T cachedValue; protected @Nullable T cachedValue;
protected long parsedTime = -1; protected long parsedTime = -1;
protected CachedConfigValue(@NotNull ValueManifest<T> manifest) { protected CachedConfigValue(@NotNull ValueManifest<T, U> manifest) {
super(manifest); super(manifest);
} }
@@ -5,6 +5,7 @@ import cc.carm.lib.configuration.adapter.ValueParser;
import cc.carm.lib.configuration.adapter.ValueSerializer; import cc.carm.lib.configuration.adapter.ValueSerializer;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.list.ConfigListBuilder; import cc.carm.lib.configuration.builder.list.ConfigListBuilder;
import cc.carm.lib.configuration.builder.list.SourceListBuilder;
import cc.carm.lib.configuration.value.ValueManifest; import cc.carm.lib.configuration.value.ValueManifest;
import cc.carm.lib.configuration.value.impl.CachedConfigValue; import cc.carm.lib.configuration.value.impl.CachedConfigValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -15,7 +16,7 @@ import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements List<V> { public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements List<V> {
public static <T> @NotNull ConfigListBuilder<T> builderOf(@NotNull Class<T> type) { public static <T> @NotNull ConfigListBuilder<T> builderOf(@NotNull Class<T> type) {
return builderOf(ValueType.of(type)); return builderOf(ValueType.of(type));
@@ -25,10 +26,26 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements Lis
return new ConfigListBuilder<>(type); return new ConfigListBuilder<>(type);
} }
public static <T> @NotNull SourceListBuilder<T, T> with(@NotNull Class<T> registeredType) {
return with(ValueType.of(registeredType));
}
public static <T> @NotNull SourceListBuilder<T, T> with(@NotNull ValueType<T> registeredType) {
return new ConfigListBuilder<>(registeredType).from(registeredType);
}
@SafeVarargs
public static <T> @NotNull ConfiguredList<T> of(@NotNull T value, @NotNull T... values) {
List<T> list = new ArrayList<>();
list.add(value);
Collections.addAll(list, values);
return with(ValueType.of(value)).defaults(list).build();
}
protected final @NotNull Supplier<? extends List<V>> constructor; protected final @NotNull Supplier<? extends List<V>> constructor;
protected final @NotNull ValueAdapter<V> paramAdapter; protected final @NotNull ValueAdapter<V> paramAdapter;
public ConfiguredList(@NotNull ValueManifest<List<V>> manifest, public ConfiguredList(@NotNull ValueManifest<List<V>, V> manifest,
@NotNull Supplier<? extends List<V>> constructor, @NotNull Supplier<? extends List<V>> constructor,
@NotNull ValueAdapter<V> paramAdapter) { @NotNull ValueAdapter<V> paramAdapter) {
super(manifest); super(manifest);
@@ -79,7 +96,7 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements Lis
for (Object dataVal : data) { for (Object dataVal : data) {
if (dataVal == null) continue; if (dataVal == null) continue;
try { try {
list.add(parser.parse(holder(), paramType(), dataVal)); list.add(withValidated(parser.parse(holder(), paramType(), dataVal)));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -88,20 +105,21 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>> implements Lis
} }
@Override @Override
public void set(@Nullable List<V> value) { public void set(@Nullable List<V> list) {
updateCache(value); updateCache(list);
if (value == null) { if (list == null) {
setData(null); setData(null);
return; return;
} }
ValueSerializer<V> serializer = serializer(); ValueSerializer<V> serializer = serializer();
if (serializer == null) return; if (serializer == null) return;
List<Object> data = new ArrayList<>(); List<Object> data = new ArrayList<>();
for (V val : value) { for (V val : list) {
if (val == null) continue; if (val == null) continue;
try { try {
data.add(serializer.serialize(holder(), paramType(), val)); data.add(serializer.serialize(holder(), paramType(), withValidated(val)));
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@@ -17,7 +17,11 @@ import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements Map<K, V> { public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> implements Map<K, V> {
public static <V> ConfigMapCreator<String, V> builderOf(@NotNull Class<V> valueType) {
return builderOf(String.class, valueType);
}
public static <K, V> ConfigMapCreator<K, V> builderOf(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) { public static <K, V> ConfigMapCreator<K, V> builderOf(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
return new ConfigMapCreator<>(keyType, valueType); return new ConfigMapCreator<>(keyType, valueType);
@@ -38,7 +42,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
protected final @NotNull ValueAdapter<K> keyAdapter; protected final @NotNull ValueAdapter<K> keyAdapter;
protected final @NotNull ValueAdapter<V> valueAdapter; protected final @NotNull ValueAdapter<V> valueAdapter;
public ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest, public ConfiguredMap(@NotNull ValueManifest<Map<K, V>, V> manifest,
@NotNull Supplier<? extends Map<K, V>> constructor, @NotNull Supplier<? extends Map<K, V>> constructor,
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) { @NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
super(manifest); super(manifest);
@@ -80,8 +84,9 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
if (keys.isEmpty()) return getDefaultFirst(map); if (keys.isEmpty()) return getDefaultFirst(map);
ValueParser<K> keyParser = parserFor(keyAdapter); ValueParser<K> keyParser = parserFor(keyAdapter);
if (keyParser == null) return getDefaultFirst(map);
ValueParser<V> valueParser = parserFor(valueAdapter); ValueParser<V> valueParser = parserFor(valueAdapter);
if (keyParser == null || valueParser == null) return getDefaultFirst(map); if (valueParser == null) return getDefaultFirst(map);
for (String dataKey : keys) { for (String dataKey : keys) {
Object dataVal = section.get(dataKey); Object dataVal = section.get(dataKey);
@@ -89,7 +94,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
try { try {
K key = keyParser.parse(holder(), keyType(), dataKey); K key = keyParser.parse(holder(), keyType(), dataKey);
V value = valueParser.parse(holder(), valueType(), dataVal); V value = valueParser.parse(holder(), valueType(), dataVal);
map.put(key, value); map.put(key, withValidated(value));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -116,8 +121,9 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
} }
ValueSerializer<K> keySerializer = serializerFor(keyAdapter); ValueSerializer<K> keySerializer = serializerFor(keyAdapter);
if (keySerializer == null) return;
ValueSerializer<V> valueSerializer = serializerFor(valueAdapter); ValueSerializer<V> valueSerializer = serializerFor(valueAdapter);
if (keySerializer == null || valueSerializer == null) return; if (valueSerializer == null) return;
Map<Object, Object> data = new LinkedHashMap<>(); Map<Object, Object> data = new LinkedHashMap<>();
@@ -125,7 +131,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
try { try {
data.put( data.put(
keySerializer.serialize(holder(), keyType(), entry.getKey()), keySerializer.serialize(holder(), keyType(), entry.getKey()),
valueSerializer.serialize(holder(), valueType(), entry.getValue()) valueSerializer.serialize(holder(), valueType(), withValidated(entry.getValue()))
); );
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -5,6 +5,8 @@ import cc.carm.lib.configuration.adapter.ValueParser;
import cc.carm.lib.configuration.adapter.ValueSerializer; import cc.carm.lib.configuration.adapter.ValueSerializer;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.value.ConfigValueBuilder; import cc.carm.lib.configuration.builder.value.ConfigValueBuilder;
import cc.carm.lib.configuration.builder.value.SourceValueBuilder;
import cc.carm.lib.configuration.source.ConfigurationHolder;
import cc.carm.lib.configuration.value.ValueManifest; import cc.carm.lib.configuration.value.ValueManifest;
import cc.carm.lib.configuration.value.impl.CachedConfigValue; import cc.carm.lib.configuration.value.impl.CachedConfigValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -12,16 +14,54 @@ import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ConfiguredValue<V> extends CachedConfigValue<V> { public class ConfiguredValue<V> extends CachedConfigValue<V, V> {
/**
* Create a new value builder.
*
* @param type The type of the value.
* @param <V> The type of the value.
* @return a {@link ConfigValueBuilder} with the specified type.
*/
public static <V> ConfigValueBuilder<V> builderOf(@NotNull Class<V> type) { public static <V> ConfigValueBuilder<V> builderOf(@NotNull Class<V> type) {
return new ConfigValueBuilder<>(ValueType.of(type)); return new ConfigValueBuilder<>(ValueType.of(type));
} }
/**
* Create a new value builder.
*
* @param type The type of the value.
* @param <V> The type of the value.
* @return a {@link ConfigValueBuilder} with the specified type.
*/
public static <V> ConfigValueBuilder<V> builderOf(@NotNull ValueType<V> type) { public static <V> ConfigValueBuilder<V> builderOf(@NotNull ValueType<V> type) {
return new ConfigValueBuilder<>(type); return new ConfigValueBuilder<>(type);
} }
/**
* Create a new value builder with the specified {@link ConfigurationHolder#registeredValues()} type.
*
* @param registeredType The type of the value.
* @param <V> The type of the value.
* @return a {@link SourceValueBuilder} with the specified registered type.
* @see ValueAdapter
*/
public static <V> SourceValueBuilder<V, V> with(@NotNull Class<V> registeredType) {
return with(ValueType.of(registeredType));
}
/**
* Create a new value builder with the specified {@link ConfigurationHolder#registeredValues()} type.
*
* @param registeredType The type of the value.
* @param <V> The type of the value.
* @return a {@link SourceValueBuilder} with the specified registered type.
* @see ValueAdapter
*/
public static <V> SourceValueBuilder<V, V> with(@NotNull ValueType<V> registeredType) {
return new ConfigValueBuilder<>(registeredType).from(registeredType);
}
public static <V> ConfiguredValue<V> of(@NotNull V defaults) { public static <V> ConfiguredValue<V> of(@NotNull V defaults) {
return of(ValueType.of(defaults), () -> defaults); return of(ValueType.of(defaults), () -> defaults);
} }
@@ -51,7 +91,7 @@ public class ConfiguredValue<V> extends CachedConfigValue<V> {
); );
} }
public static <V> ConfiguredValue<V> of(@NotNull ValueManifest<V> manifest, public static <V> ConfiguredValue<V> of(@NotNull ValueManifest<V, V> manifest,
@Nullable ValueParser<V> parser, @Nullable ValueParser<V> parser,
@Nullable ValueSerializer<V> serializer) { @Nullable ValueSerializer<V> serializer) {
ValueAdapter<V> adapter = new ValueAdapter<>(manifest.type()); ValueAdapter<V> adapter = new ValueAdapter<>(manifest.type());
@@ -60,13 +100,13 @@ public class ConfiguredValue<V> extends CachedConfigValue<V> {
return of(manifest, adapter); return of(manifest, adapter);
} }
public static <V> ConfiguredValue<V> of(@NotNull ValueManifest<V> manifest, @NotNull ValueAdapter<V> adapter) { public static <V> ConfiguredValue<V> of(@NotNull ValueManifest<V, V> manifest, @NotNull ValueAdapter<V> adapter) {
return new ConfiguredValue<>(manifest, adapter); return new ConfiguredValue<>(manifest, adapter);
} }
protected final @NotNull ValueAdapter<V> adapter; protected final @NotNull ValueAdapter<V> adapter;
public ConfiguredValue(@NotNull ValueManifest<V> manifest, @NotNull ValueAdapter<V> adapter) { public ConfiguredValue(@NotNull ValueManifest<V, V> manifest, @NotNull ValueAdapter<V> adapter) {
super(manifest); super(manifest);
this.adapter = adapter; this.adapter = adapter;
} }
@@ -103,11 +143,13 @@ public class ConfiguredValue<V> extends CachedConfigValue<V> {
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 { try {
// If there are no errors, update the cache and return. // If there are no errors, update the cache and return.
return updateCache(parser.parse(holder(), type(), data)); V parsed = parser.parse(holder(), type(), data);
return updateCache(withValidated(parsed));
} catch (Exception e) { } catch (Exception e) {
// There was a parsing error, prompted and returned the default value. // There was a validate or parsing error, prompted and returned the default value.
e.printStackTrace(); e.printStackTrace();
return defaults(); return defaults();
} }
@@ -121,7 +163,7 @@ public class ConfiguredValue<V> extends CachedConfigValue<V> {
* @param value The value to be set * @param value The value to be set
*/ */
@Override @Override
public void set(V value) { public void set(@Nullable V value) {
updateCache(value); // Update cache updateCache(value); // Update cache
if (value == null) { if (value == null) {
setData(null); setData(null);
@@ -132,7 +174,7 @@ public class ConfiguredValue<V> extends CachedConfigValue<V> {
if (serializer == null) return; // No serializer, do nothing. if (serializer == null) return; // No serializer, do nothing.
try { try {
setData(serializer.serialize(holder(), type(), value)); setData(serializer.serialize(holder(), type(), withValidated(value)));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.0</version> <version>4.1.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<properties> <properties>
@@ -4,7 +4,6 @@ import cc.carm.lib.configuration.Configuration;
import cc.carm.lib.configuration.annotation.*; import cc.carm.lib.configuration.annotation.*;
import cc.carm.lib.configuration.demo.tests.model.ItemStack; import cc.carm.lib.configuration.demo.tests.model.ItemStack;
import cc.carm.lib.configuration.demo.tests.model.UserRecord; import cc.carm.lib.configuration.demo.tests.model.UserRecord;
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.ConfiguredValue; import cc.carm.lib.configuration.value.standard.ConfiguredValue;
@@ -26,15 +25,18 @@ public interface DemoConfiguration extends Configuration {
@ConfigPath(root = true) @ConfigPath(root = true)
@ConfigVersion(2) @ConfigVersion(2)
ConfigValue<Double> VERSION = ConfiguredValue.of(Double.class, 2.0D); ConfiguredValue<Double> VERSION = ConfiguredValue.of(Double.class, 2.0D);
@ConfigPath(root = true) @ConfigPath(root = true)
@FooterComments({"此处内容将显示在配置条目的下方", "可用于补充说明,但一般不建议使用"}) @FooterComments({"此处内容将显示在配置条目的下方", "可用于补充说明,但一般不建议使用"})
ConfigValue<Long> TEST_NUMBER = ConfiguredValue.of(1000000L); ConfiguredValue<Long> TEST_NUMBER = ConfiguredValue.with(Long.class)
.validate(l -> l > 100, "数值必须大于100")
.validate(l -> l < 100000000, "数值必须小于100000000")
.defaults(123456789L).build();
@HeaderComments({"枚举类型测试"}) @HeaderComments({"枚举类型测试"})
@FooterComments({"上述的枚举内容本质上是通过STRING解析的"}) @FooterComments({"上述的枚举内容本质上是通过STRING解析的"})
ConfigValue<ChronoUnit> TEST_ENUM = ConfiguredValue.of(ChronoUnit.class, ChronoUnit.DAYS); ConfiguredValue<ChronoUnit> TEST_ENUM = ConfiguredValue.of(ChronoUnit.class, ChronoUnit.DAYS);
@HeaderComments({"空值测试"}) @HeaderComments({"空值测试"})
@InlineComment("空值Inline注释") @InlineComment("空值Inline注释")
@@ -72,7 +74,7 @@ public interface DemoConfiguration extends Configuration {
class SUB implements Configuration { class SUB implements Configuration {
@ConfigPath(value = "uuid-value", root = true) @ConfigPath(value = "uuid-value", root = true)
public static final ConfigValue<UUID> UUID_CONFIG_VALUE = ConfiguredValue public static final ConfiguredValue<UUID> UUID_CONFIG_VALUE = ConfiguredValue
.builderOf(UUID.class).fromString() .builderOf(UUID.class).fromString()
.parse((holder, data) -> UUID.fromString(data)) .parse((holder, data) -> UUID.fromString(data))
.build(); .build();
@@ -2,12 +2,11 @@ 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.value.ConfigValue;
import cc.carm.lib.configuration.value.standard.ConfiguredValue; import cc.carm.lib.configuration.value.standard.ConfiguredValue;
@HeaderComments("Inner Test") @HeaderComments("Inner Test")
public class InstanceConfig implements Configuration { public class InstanceConfig implements Configuration {
public final ConfigValue<Double> STATUS = ConfiguredValue.of(1.0D); public final ConfiguredValue<Double> STATUS = ConfiguredValue.of(1.0D);
} }
@@ -6,7 +6,6 @@ import cc.carm.lib.configuration.annotation.FooterComments;
import cc.carm.lib.configuration.annotation.HeaderComments; import cc.carm.lib.configuration.annotation.HeaderComments;
import cc.carm.lib.configuration.annotation.InlineComment; import cc.carm.lib.configuration.annotation.InlineComment;
import cc.carm.lib.configuration.demo.tests.model.UserRecord; import cc.carm.lib.configuration.demo.tests.model.UserRecord;
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;
@@ -20,7 +19,7 @@ public class RegistryConfig implements Configuration {
@FooterComments({"12313213212"}) @FooterComments({"12313213212"})
@InlineComment(value = "用户名(匹配注释)", regex = "name") // 通过注解给配置添加注释。 @InlineComment(value = "用户名(匹配注释)", regex = "name") // 通过注解给配置添加注释。
@InlineComment(value = "信息", regex = {"info.*", "info.game.*"}) // 通过注解给配置添加注释。 @InlineComment(value = "信息", regex = {"info.*", "info.game.*"}) // 通过注解给配置添加注释。
public final ConfigValue<UserRecord> OWNER = ConfiguredValue.builderOf(UserRecord.class).fromSection() public final ConfiguredValue<UserRecord> OWNER = ConfiguredValue.builderOf(UserRecord.class).fromSection()
.defaults(new UserRecord("Carm", UUID.randomUUID())) .defaults(new UserRecord("Carm", UUID.randomUUID()))
.parse((holder, section) -> UserRecord.deserialize(section)) .parse((holder, section) -> UserRecord.deserialize(section))
.serialize((holder, data) -> data.serialize()).build(); .serialize((holder, data) -> data.serialize()).build();
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+51
View File
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId>
<version>4.1.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>configured-feature-validators</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>configured-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,16 @@
package cc.carm.lib.configuration.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValuePattern {
String value();
String message() default "Invalid value format!";
}
@@ -0,0 +1,18 @@
package cc.carm.lib.configuration.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValueRange {
long min() default Long.MIN_VALUE;
long max() default Long.MAX_VALUE;
String message() default "Value out of range.";
}
@@ -0,0 +1,8 @@
package cc.carm.lib.configuration.validators;
public class StandardValidators {
}
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+2 -1
View File
@@ -15,13 +15,14 @@
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>4.1.0</version> <version>4.1.1</version>
<modules> <modules>
<module>core</module> <module>core</module>
<module>features/section</module> <module>features/section</module>
<module>features/file</module> <module>features/file</module>
<module>features/commentable</module> <module>features/commentable</module>
<module>features/versioned</module> <module>features/versioned</module>
<module>features/validators</module>
<module>features/text</module> <module>features/text</module>
<module>providers/yaml</module> <module>providers/yaml</module>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent> <parent>
<artifactId>configured-parent</artifactId> <artifactId>configured-parent</artifactId>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<version>4.1.0</version> <version>4.1.1</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>