1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2026-06-04 18:48:20 +08:00

refactor(collection): Refactor builders of collection types (including List and Set).

This commit is contained in:
2025-09-27 02:09:42 +08:00
parent c86985017f
commit b17c157e18
30 changed files with 728 additions and 387 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.8</version> <version>4.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<properties> <properties>
@@ -0,0 +1,55 @@
package cc.carm.lib.configuration.builder.collection;
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.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
public abstract class SectionCollectionBuilder<
V, C extends Collection<V>,
RESULT extends CollectionConfigValue<V, C, ?>,
SELF extends SectionCollectionBuilder<V, C, RESULT, SELF>
> extends AbstractSectionBuilder<C, V, RESULT, SELF> {
protected @NotNull Supplier<? extends C> constructor;
public SectionCollectionBuilder(@NotNull Supplier<? extends C> constructor,
@NotNull ValueType<V> paramType,
@NotNull ValueHandler<ConfigureSection, V> parser,
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
super(new ValueType<C>() {
}, paramType, parser, serializer);
this.constructor = constructor;
}
@SafeVarargs
public final @NotNull SELF defaults(@NotNull V... values) {
return defaults(c -> c.addAll(Arrays.asList(values)));
}
public final @NotNull SELF defaults(@NotNull Consumer<C> constructor) {
return defaults(() -> {
C collection = this.constructor.get();
constructor.accept(collection);
return collection;
});
}
public SELF constructor(@NotNull Supplier<? extends C> constructor) {
this.constructor = constructor;
return self();
}
public SELF construct(@NotNull C collection) {
return constructor(() -> collection);
}
}
@@ -0,0 +1,138 @@
package cc.carm.lib.configuration.builder.collection;
import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.ValueManifest;
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;
public class SimpleCollectionCreator<V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>> {
public static <V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>>
@NotNull SimpleCollectionCreator<V, C, RESULT> create(
@NotNull ValueType<V> type,
@NotNull Supplier<? extends C> defaultConstructor,
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
return new SimpleCollectionCreator<>(type, defaultConstructor, factory);
}
protected final @NotNull Supplier<? extends C> defaultConstructor;
protected final @NotNull ValueType<V> type;
protected final @NotNull CollectionValueFactory<V, C, RESULT> factory;
public SimpleCollectionCreator(@NotNull ValueType<V> type,
@NotNull Supplier<? extends C> defaultConstructor,
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
this.defaultConstructor = defaultConstructor;
this.type = type;
this.factory = factory;
}
public <S> @NotNull Source<S, V, C, RESULT> from(@NotNull Class<S> sourceType) {
return from(ValueType.of(sourceType));
}
public <S> @NotNull Source<S, V, C, RESULT> from(@NotNull ValueType<S> sourceType) {
return new Source<S, V, C, RESULT>(
defaultConstructor, sourceType, type,
ValueHandler.required(type),
ValueHandler.required(sourceType),
factory
);
}
public @NotNull SimpleCollectionCreator.Source<Object, V, C, RESULT> fromObject() {
return new Source<Object, V, C, RESULT>(
defaultConstructor, ValueType.OBJECT, type,
ValueHandler.deserialize(type), ValueHandler.toObject(),
factory
);
}
public @NotNull SimpleCollectionCreator.Source<String, V, C, RESULT> fromString() {
return new Source<String, V, C, RESULT>(
defaultConstructor, ValueType.STRING, type,
ValueHandler.required(type), ValueHandler.stringValue(),
factory
);
}
public @NotNull SimpleCollectionCreator.Section<V, C, RESULT> fromSection() {
return new Section<V, C, RESULT>(
defaultConstructor, type,
ValueHandler.required(type), ValueHandler.required(),
factory
);
}
@FunctionalInterface
public interface CollectionValueFactory<V, C, RESULT> {
@NotNull RESULT build(
@NotNull ValueManifest<C, V> manifest,
@NotNull Supplier<? extends C> constructor,
@NotNull ValueAdapter<V> paramAdapter
);
}
public static class Source<SOURCE, V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>>
extends SourceCollectionBuilder<SOURCE, V, C, RESULT, Source<SOURCE, V, C, RESULT>> {
protected final @NotNull CollectionValueFactory<V, C, RESULT> factory;
public Source(
@NotNull Supplier<? extends C> constructor,
@NotNull ValueType<SOURCE> sourceType,
@NotNull ValueType<V> paramType,
@NotNull ValueHandler<SOURCE, V> parser,
@NotNull ValueHandler<V, SOURCE> serializer,
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
super(constructor, sourceType, paramType, parser, serializer);
this.factory = factory;
}
@Override
protected @NotNull SimpleCollectionCreator.Source<SOURCE, V, C, RESULT> self() {
return this;
}
@Override
public @NotNull RESULT build() {
return factory.build(buildManifest(), constructor, buildAdapter());
}
}
public static class Section<V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>>
extends SectionCollectionBuilder<V, C, RESULT, Section<V, C, RESULT>> {
protected final @NotNull CollectionValueFactory<V, C, RESULT> factory;
public Section(
@NotNull Supplier<? extends C> constructor,
@NotNull ValueType<V> paramType,
@NotNull ValueHandler<ConfigureSection, V> parser,
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer,
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
super(constructor, paramType, parser, serializer);
this.factory = factory;
}
@Override
protected @NotNull SimpleCollectionCreator.Section<V, C, RESULT> self() {
return this;
}
@Override
public @NotNull RESULT build() {
return factory.build(buildManifest(), constructor, buildAdapter());
}
}
}
@@ -0,0 +1,53 @@
package cc.carm.lib.configuration.builder.collection;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.impl.AbstractSourceBuilder;
import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Supplier;
public abstract class SourceCollectionBuilder<
SOURCE, V, C extends Collection<V>,
RESULT extends CollectionConfigValue<V, C, ?>,
SELF extends SourceCollectionBuilder<SOURCE, V, C, RESULT, SELF>
>
extends AbstractSourceBuilder<C, SOURCE, V, RESULT, SELF> {
protected @NotNull Supplier<? extends C> constructor;
public SourceCollectionBuilder(@NotNull Supplier<? extends C> constructor,
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType,
@NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer) {
super(new ValueType<C>() {
}, sourceType, paramType, parser, serializer);
this.constructor = constructor;
}
@SafeVarargs
public final @NotNull SELF defaults(@NotNull V... values) {
return defaults(c -> c.addAll(Arrays.asList(values)));
}
public final @NotNull SELF defaults(@NotNull Consumer<C> constructor) {
return defaults(() -> {
C collection = this.constructor.get();
constructor.accept(collection);
return collection;
});
}
public SELF constructor(@NotNull Supplier<? extends C> constructor) {
this.constructor = constructor;
return self();
}
public SELF construct(@NotNull C collection) {
return constructor(() -> collection);
}
}
@@ -1,51 +0,0 @@
package cc.carm.lib.configuration.builder.list;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.function.ValueHandler;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class ConfigListBuilder<V> {
protected final @NotNull ValueType<V> type;
public ConfigListBuilder(@NotNull ValueType<V> type) {
this.type = type;
}
public <S> @NotNull SourceListBuilder<S, V> from(@NotNull Class<S> sourceType) {
return from(ValueType.of(sourceType));
}
public <S> @NotNull SourceListBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
return new SourceListBuilder<>(
ArrayList::new, sourceType, type,
ValueHandler.required(type),
ValueHandler.required(sourceType)
);
}
public @NotNull SourceListBuilder<Object, V> fromObject() {
return new SourceListBuilder<>(
ArrayList::new, ValueType.OBJECT, type,
ValueHandler.deserialize(type), ValueHandler.toObject()
);
}
public @NotNull SourceListBuilder<String, V> fromString() {
return new SourceListBuilder<>(
ArrayList::new, ValueType.STRING, type,
ValueHandler.required(type), ValueHandler.stringValue()
);
}
public @NotNull SectionListBuilder<V> fromSection() {
return new SectionListBuilder<>(
ArrayList::new, type,
ValueHandler.required(type), ValueHandler.required()
);
}
}
@@ -0,0 +1,17 @@
package cc.carm.lib.configuration.builder.list;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.collection.SimpleCollectionCreator;
import cc.carm.lib.configuration.value.standard.ConfiguredList;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class ConfigListCreator<V> extends SimpleCollectionCreator<V, List<V>, ConfiguredList<V>> {
public ConfigListCreator(@NotNull ValueType<V> type) {
super(type, ArrayList::new, ConfiguredList::new);
}
}
@@ -1,63 +0,0 @@
package cc.carm.lib.configuration.builder.list;
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.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.standard.ConfiguredList;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class SectionListBuilder<V>
extends AbstractSectionBuilder<List<V>, V, ConfiguredList<V>, SectionListBuilder<V>> {
protected @NotNull Supplier<? extends List<V>> constructor;
public SectionListBuilder(@NotNull Supplier<? extends List<V>> constructor,
@NotNull ValueType<V> paramType,
@NotNull ValueHandler<ConfigureSection, V> parser,
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
super(new ValueType<List<V>>() {
}, paramType, parser, serializer);
this.constructor = constructor;
}
@SafeVarargs
public final @NotNull SectionListBuilder<V> defaults(@NotNull V... values) {
return defaults(new ArrayList<>(Arrays.asList(values)));
}
public final @NotNull SectionListBuilder<V> defaults(@NotNull Collection<V> 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) {
this.constructor = constructor;
return this;
}
public <LIST extends List<V>> SectionListBuilder<V> construct(@NotNull LIST list) {
return constructor(() -> list);
}
@Override
protected @NotNull SectionListBuilder<V> self() {
return this;
}
@Override
public @NotNull ConfiguredList<V> build() {
return new ConfiguredList<>(buildManifest(), constructor, buildAdapter());
}
}
@@ -1,65 +0,0 @@
package cc.carm.lib.configuration.builder.list;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.impl.AbstractSourceBuilder;
import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.value.standard.ConfiguredList;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class SourceListBuilder<SOURCE, V>
extends AbstractSourceBuilder<List<V>, SOURCE, V, ConfiguredList<V>, SourceListBuilder<SOURCE, V>> {
protected @NotNull Supplier<? extends List<V>> constructor;
public SourceListBuilder(@NotNull Supplier<? extends List<V>> constructor,
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType,
@NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer) {
super(new ValueType<List<V>>() {
}, sourceType, paramType, parser, serializer);
this.constructor = constructor;
}
@SafeVarargs
public final @NotNull SourceListBuilder<SOURCE, V> defaults(@NotNull V... values) {
return defaults(new ArrayList<>(Arrays.asList(values)));
}
public final @NotNull SourceListBuilder<SOURCE, V> defaults(@NotNull Collection<V> 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
protected @NotNull SourceListBuilder<SOURCE, V> self() {
return this;
}
@Override
public @NotNull ConfiguredList<V> build() {
return new ConfiguredList<>(buildManifest(), this.constructor, buildAdapter());
}
}
@@ -0,0 +1,210 @@
package cc.carm.lib.configuration.value.impl;
import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueParser;
import cc.carm.lib.configuration.adapter.ValueSerializer;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.value.ValueManifest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Base implementation of a collection config value, like {@link List} or {@link Set}.
*
* @param <V> Value type
* @param <C> Collection type
* @param <SELF> Self reference type (used for internal call or recursive generics)
*/
public abstract class CollectionConfigValue<
V, C extends Collection<V>,
SELF extends CollectionConfigValue<V, C, SELF>
> extends CachedConfigValue<C, V> implements Collection<V> {
protected final @NotNull Supplier<? extends C> constructor;
protected final @NotNull ValueAdapter<V> paramAdapter;
public CollectionConfigValue(@NotNull ValueManifest<C, V> manifest,
@NotNull Supplier<? extends C> constructor,
@NotNull ValueAdapter<V> paramAdapter) {
super(manifest);
this.constructor = constructor;
this.paramAdapter = paramAdapter;
}
/**
* @return Adapter of this value.
*/
public @NotNull ValueAdapter<V> adapter() {
return this.paramAdapter;
}
public @NotNull ValueType<V> paramType() {
return adapter().type();
}
/**
* @return Value's parser, parse base object to value.
*/
public @Nullable ValueParser<V> parser() {
return parserFor(adapter());
}
/**
* @return Value's serializer, parse value to base object.
*/
public @Nullable ValueSerializer<V> serializer() {
return serializerFor(adapter());
}
private @NotNull C createCollection() {
return constructor.get();
}
@Override
public @NotNull C get() {
if (!cacheExpired()) return getCachedOrDefault(createCollection());
// Data that is outdated and needs to be parsed again.
C set = createCollection();
try {
List<?> data = config().contains(path()) ? config().getList(path()) : null;
if (data == null) return getDefaultFirst(set);
ValueParser<V> parser = parser();
if (parser == null) return getDefaultFirst(set);
int i = 0;
for (Object dataVal : data) {
if (dataVal == null) continue;
try {
set.add(withValidated(parser.parse(holder(), paramType(), dataVal)));
} catch (Exception e) {
throwing(path + "[" + i + "]", e);
}
}
} catch (Exception ex) {
throwing(ex);
}
return updateCache(set);
}
@Override
public void set(@Nullable C collection) {
updateCache(collection);
if (collection == null) {
setData(null);
return;
}
ValueSerializer<V> serializer = serializer();
if (serializer == null) return;
List<Object> data = new ArrayList<>();
for (V val : collection) {
if (val == null) continue;
try {
data.add(serializer.serialize(holder(), paramType(), withValidated(val)));
} catch (Exception ex) {
throwing(ex);
}
}
setData(data);
}
public @NotNull C copy() {
C other = createCollection();
other.addAll(resolve());
return other;
}
public abstract @NotNull SELF self();
public <T> @NotNull T handle(Function<C, T> function) {
C list = resolve();
T result = function.apply(list);
set(list);
return result;
}
public @NotNull SELF modify(Consumer<C> consumer) {
C list = resolve();
consumer.accept(list);
set(list);
return self();
}
@Override
public int size() {
return resolve().size();
}
@Override
public boolean isEmpty() {
return resolve().isEmpty();
}
@Override
public boolean contains(Object o) {
return resolve().contains(o);
}
@NotNull
@Override
public Iterator<V> iterator() {
return resolve().iterator();
}
@NotNull
@Override
public Object @NotNull [] toArray() {
return resolve().toArray();
}
@NotNull
@Override
public <T> T @NotNull [] toArray(@NotNull T[] a) {
return resolve().toArray(a);
}
@Override
public boolean containsAll(@NotNull Collection<?> c) {
return new HashSet<>(resolve()).containsAll(c);
}
@Override
public boolean add(V v) {
handle(list -> list.add(v));
return true;
}
@Override
public boolean addAll(@NotNull Collection<? extends V> c) {
return handle(list -> list.addAll(c));
}
@Override
public boolean remove(Object o) {
return handle(list -> list.remove(o));
}
@Override
public boolean removeAll(@NotNull Collection<?> c) {
return handle(list -> list.removeAll(c));
}
@Override
public boolean retainAll(@NotNull Collection<?> c) {
return handle(list -> list.retainAll(c));
}
@Override
public void clear() {
modify(Collection::clear);
}
}
@@ -1,37 +1,33 @@
package cc.carm.lib.configuration.value.standard; package cc.carm.lib.configuration.value.standard;
import cc.carm.lib.configuration.adapter.ValueAdapter; import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueParser;
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.collection.SimpleCollectionCreator;
import cc.carm.lib.configuration.builder.list.SourceListBuilder; import cc.carm.lib.configuration.builder.list.ConfigListCreator;
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.CollectionConfigValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements List<V> { public class ConfiguredList<V> extends CollectionConfigValue<V, List<V>, ConfiguredList<V>> implements List<V> {
public static <T> @NotNull ConfigListBuilder<T> builderOf(@NotNull Class<T> type) { public static <T> @NotNull ConfigListCreator<T> builderOf(@NotNull Class<T> type) {
return builderOf(ValueType.of(type)); return builderOf(ValueType.of(type));
} }
public static <T> @NotNull ConfigListBuilder<T> builderOf(@NotNull ValueType<T> type) { public static <T> @NotNull ConfigListCreator<T> builderOf(@NotNull ValueType<T> type) {
return new ConfigListBuilder<>(type); return new ConfigListCreator<>(type);
} }
public static <T> @NotNull SourceListBuilder<Object, T> with(@NotNull Class<T> registeredType) { public static <T>
@NotNull SimpleCollectionCreator.Source<Object, T, List<T>, ConfiguredList<T>> with(@NotNull Class<T> registeredType) {
return with(ValueType.of(registeredType)); return with(ValueType.of(registeredType));
} }
public static <T> @NotNull SourceListBuilder<Object, T> with(@NotNull ValueType<T> registeredType) { public static <T> @NotNull SimpleCollectionCreator.Source<Object, T, List<T>, ConfiguredList<T>> with(@NotNull ValueType<T> registeredType) {
return new ConfigListBuilder<>(registeredType).fromObject(); return builderOf(registeredType).fromObject();
} }
@SafeVarargs @SafeVarargs
@@ -42,94 +38,10 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
return with(ValueType.of(value)).defaults(list).build(); return with(ValueType.of(value)).defaults(list).build();
} }
protected final @NotNull Supplier<? extends List<V>> constructor;
protected final @NotNull ValueAdapter<V> paramAdapter;
public ConfiguredList(@NotNull ValueManifest<List<V>, 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, constructor, paramAdapter);
this.constructor = constructor;
this.paramAdapter = paramAdapter;
}
/**
* @return Adapter of this value.
*/
public @NotNull ValueAdapter<V> adapter() {
return this.paramAdapter;
}
public @NotNull ValueType<V> paramType() {
return adapter().type();
}
/**
* @return Value's parser, parse base object to value.
*/
public @Nullable ValueParser<V> parser() {
return parserFor(adapter());
}
/**
* @return Value's serializer, parse value to base object.
*/
public @Nullable ValueSerializer<V> serializer() {
return serializerFor(adapter());
}
private @NotNull List<V> createList() {
return constructor.get();
}
@Override
public @NotNull List<V> get() {
if (!cacheExpired()) return getCachedOrDefault(createList());
// Data that is outdated and needs to be parsed again.
List<V> list = createList();
try {
List<?> data = config().contains(path()) ? config().getList(path()) : null;
if (data == null) return getDefaultFirst(list);
ValueParser<V> parser = parser();
if (parser == null) return getDefaultFirst(list);
int i = 0;
for (Object dataVal : data) {
if (dataVal == null) continue;
try {
list.add(withValidated(parser.parse(holder(), paramType(), dataVal)));
} catch (Exception e) {
throwing(path + "[" + i + "]", e);
}
}
} catch (Exception ex) {
throwing(ex);
}
return updateCache(list);
}
@Override
public void set(@Nullable List<V> list) {
updateCache(list);
if (list == null) {
setData(null);
return;
}
ValueSerializer<V> serializer = serializer();
if (serializer == null) return;
List<Object> data = new ArrayList<>();
for (V val : list) {
if (val == null) continue;
try {
data.add(serializer.serialize(holder(), paramType(), withValidated(val)));
} catch (Exception ex) {
throwing(ex);
}
}
setData(data);
} }
@Override @Override
@@ -137,21 +49,8 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
return resolve().get(index); return resolve().get(index);
} }
public @NotNull List<V> copy() { @Override
return new ArrayList<>(resolve()); public @NotNull ConfiguredList<V> self() {
}
public <T> @NotNull T handle(Function<List<V>, T> function) {
List<V> list = resolve();
T result = function.apply(list);
set(list);
return result;
}
public @NotNull ConfiguredList<V> modify(Consumer<List<V>> consumer) {
List<V> list = resolve();
consumer.accept(list);
set(list);
return this; return this;
} }
@@ -160,89 +59,22 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
return handle(list -> list.set(index, element)); return handle(list -> list.set(index, element));
} }
@Override
public int size() {
return resolve().size();
}
@Override
public boolean isEmpty() {
return resolve().isEmpty();
}
@Override
public boolean contains(Object o) {
return resolve().contains(o);
}
@NotNull
@Override
public Iterator<V> iterator() {
return resolve().iterator();
}
@NotNull
@Override
public Object @NotNull [] toArray() {
return resolve().toArray();
}
@NotNull
@Override
public <T> T @NotNull [] toArray(@NotNull T[] a) {
return resolve().toArray(a);
}
@Override
public boolean containsAll(@NotNull Collection<?> c) {
return new HashSet<>(resolve()).containsAll(c);
}
@Override
public boolean add(V v) {
handle(list -> list.add(v));
return true;
}
@Override @Override
public void add(int index, V element) { public void add(int index, V element) {
modify(list -> list.add(index, element)); modify(list -> list.add(index, element));
} }
@Override
public boolean addAll(@NotNull Collection<? extends V> c) {
return handle(list -> list.addAll(c));
}
@Override @Override
public boolean addAll(int index, @NotNull Collection<? extends V> c) { public boolean addAll(int index, @NotNull Collection<? extends V> c) {
return handle(list -> list.addAll(index, c)); return handle(list -> list.addAll(index, c));
} }
@Override
public boolean remove(Object o) {
return handle(list -> list.remove(o));
}
@Override @Override
public V remove(int index) { public V remove(int index) {
return handle(list -> list.remove(index)); return handle(list -> list.remove(index));
} }
@Override
public boolean removeAll(@NotNull Collection<?> c) {
return handle(list -> list.removeAll(c));
}
@Override
public boolean retainAll(@NotNull Collection<?> c) {
return handle(list -> list.retainAll(c));
}
@Override
public void clear() {
modify(List::clear);
}
@Override @Override
public int indexOf(Object o) { public int indexOf(Object o) {
@@ -272,4 +104,5 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
return resolve().subList(fromIndex, toIndex); return resolve().subList(fromIndex, toIndex);
} }
} }
+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.8</version> <version>4.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<properties> <properties>
+64
View File
@@ -0,0 +1,64 @@
<?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.2.0</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-collections</artifactId>
<packaging>jar</packaging>
<name>Configured - Collections Feature</name>
<url>https://github.com/CarmJos/configured</url>
<description>Provides more collection type support for the Configured framework.</description>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>configured-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>configured-gson</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</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,96 @@
package cc.carm.lib.configuration.builder.set;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.collection.SectionCollectionBuilder;
import cc.carm.lib.configuration.builder.collection.SourceCollectionBuilder;
import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.collections.ConfiguredSet;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
public class ConfigSetBuilder<V> {
protected final @NotNull ValueType<V> type;
public ConfigSetBuilder(@NotNull ValueType<V> type) {
this.type = type;
}
public <S> @NotNull SourceBuilder<S, V> from(@NotNull Class<S> sourceType) {
return from(ValueType.of(sourceType));
}
public <S> @NotNull SourceBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
return new SourceBuilder<>(
sourceType, type,
ValueHandler.required(type),
ValueHandler.required(sourceType)
);
}
public @NotNull ConfigSetBuilder.SourceBuilder<Object, V> fromObject() {
return new SourceBuilder<>(
ValueType.OBJECT, type,
ValueHandler.deserialize(type), ValueHandler.toObject()
);
}
public @NotNull ConfigSetBuilder.SourceBuilder<String, V> fromString() {
return new SourceBuilder<>(
ValueType.STRING, type,
ValueHandler.required(type), ValueHandler.stringValue()
);
}
public @NotNull ConfigSetBuilder.SectionBuilder<V> fromSection() {
return new SectionBuilder<>(type, ValueHandler.required(type), ValueHandler.required());
}
public static class SourceBuilder<SOURCE, V> extends SourceCollectionBuilder<SOURCE, V, Set<V>, ConfiguredSet<V>, SourceBuilder<SOURCE, V>> {
public SourceBuilder(@NotNull ValueType<SOURCE> sourceType,
@NotNull ValueType<V> paramType,
@NotNull ValueHandler<SOURCE, V> parser,
@NotNull ValueHandler<V, SOURCE> serializer) {
super(LinkedHashSet::new, sourceType, paramType, parser, serializer);
}
@Override
protected @NotNull ConfigSetBuilder.SourceBuilder<SOURCE, V> self() {
return this;
}
@Override
public @NotNull ConfiguredSet<V> build() {
return new ConfiguredSet<>(buildManifest(), constructor, buildAdapter());
}
}
public static class SectionBuilder<V> extends SectionCollectionBuilder<V, Set<V>, ConfiguredSet<V>, SectionBuilder<V>> {
public SectionBuilder(@NotNull ValueType<V> paramType,
@NotNull ValueHandler<ConfigureSection, V> parser,
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
super(LinkedHashSet::new, paramType, parser, serializer);
}
@Override
protected @NotNull ConfigSetBuilder.SectionBuilder<V> self() {
return this;
}
@Override
public @NotNull ConfiguredSet<V> build() {
return new ConfiguredSet<>(buildManifest(), constructor, buildAdapter());
}
}
}
@@ -0,0 +1,52 @@
package cc.carm.lib.configuration.value.collections;
import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.set.ConfigSetBuilder;
import cc.carm.lib.configuration.value.ValueManifest;
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Supplier;
public class ConfiguredSet<V> extends CollectionConfigValue<V, Set<V>, ConfiguredSet<V>> implements Set<V> {
public static <T> @NotNull ConfigSetBuilder<T> builderOf(@NotNull Class<T> type) {
return builderOf(ValueType.of(type));
}
public static <T> @NotNull ConfigSetBuilder<T> builderOf(@NotNull ValueType<T> type) {
return new ConfigSetBuilder<>(type);
}
public static <T> @NotNull ConfigSetBuilder.SourceBuilder<Object, T> with(@NotNull Class<T> registeredType) {
return with(ValueType.of(registeredType));
}
public static <T> @NotNull ConfigSetBuilder.SourceBuilder<Object, T> with(@NotNull ValueType<T> registeredType) {
return builderOf(registeredType).fromObject();
}
@SafeVarargs
public static <T> @NotNull ConfiguredSet<T> of(@NotNull T value, @NotNull T... values) {
Set<T> list = new LinkedHashSet<>();
list.add(value);
Collections.addAll(list, values);
return with(ValueType.of(value)).defaults(list).build();
}
public ConfiguredSet(@NotNull ValueManifest<Set<V>, V> manifest,
@NotNull Supplier<? extends Set<V>> constructor,
@NotNull ValueAdapter<V> paramAdapter) {
super(manifest, constructor, paramAdapter);
}
@Override
public @NotNull ConfiguredSet<V> self() {
return this;
}
}
+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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
@@ -1,29 +1,30 @@
package cc.carm.lib.configuration.kotlin.value package cc.carm.lib.configuration.kotlin.value
import cc.carm.lib.configuration.adapter.ValueType import cc.carm.lib.configuration.adapter.ValueType
import cc.carm.lib.configuration.builder.list.SourceListBuilder import cc.carm.lib.configuration.builder.collection.SimpleCollectionCreator
import cc.carm.lib.configuration.value.standard.ConfiguredList import cc.carm.lib.configuration.value.standard.ConfiguredList
import kotlin.reflect.KClass import kotlin.reflect.KClass
inline fun <S : Any, reified V> listFrom( inline fun <S : Any, reified V> listFrom(
clazz: KClass<S>, block: (SourceListBuilder<S, V>.() -> Unit) clazz: KClass<S>, block: (SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>.() -> Unit)
): ConfiguredList<V> { ): ConfiguredList<V> {
return listFrom(clazz.java, block) return listFrom(clazz.java, block)
} }
inline fun <S : Any, reified V> listFrom( inline fun <S : Any, reified V> listFrom(
clazz: Class<S>, block: (SourceListBuilder<S, V>.() -> Unit) clazz: Class<S>, block: (SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>.() -> Unit)
): ConfiguredList<V> { ): ConfiguredList<V> {
return listFrom(ValueType.of(clazz), block) return listFrom(ValueType.of(clazz), block)
} }
inline fun <S : Any, reified V> listFrom( inline fun <S : Any, reified V> listFrom(
valueType: ValueType<S>, block: (SourceListBuilder<S, V>.() -> Unit) valueType: ValueType<S>, block: (SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>.() -> Unit)
): ConfiguredList<V> { ): ConfiguredList<V> {
val configBuilder = ConfiguredList.builderOf(V::class.java) val configBuilder = ConfiguredList.builderOf(V::class.java)
val sourceValueBuilder: SourceListBuilder<S, V> = if (valueType.rawType == String::class.java) { val sourceValueBuilder: SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>> =
if (valueType.rawType == String::class.java) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
configBuilder.fromString() as SourceListBuilder<S, V> configBuilder.fromString() as SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>
} else configBuilder.from(valueType) } else configBuilder.from(valueType)
return sourceValueBuilder.also(block).build() return sourceValueBuilder.also(block).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.8</version> <version>4.2.0</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
+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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>
+2 -1
View File
@@ -16,11 +16,12 @@
<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.8</version> <version>4.2.0</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/collections</module>
<module>features/commentable</module> <module>features/commentable</module>
<module>features/versioned</module> <module>features/versioned</module>
<module>features/validators</module> <module>features/validators</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</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.8</version> <version>4.2.0</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<properties> <properties>