201 lines
6.9 KiB
Java
201 lines
6.9 KiB
Java
package io.gitlab.jfronny.libjf.config.impl.dsl;
|
|
|
|
import io.gitlab.jfronny.commons.serialize.gson.api.GsonHolder;
|
|
import io.gitlab.jfronny.commons.throwable.ThrowingConsumer;
|
|
import io.gitlab.jfronny.commons.throwable.ThrowingSupplier;
|
|
import io.gitlab.jfronny.gson.JsonElement;
|
|
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
|
import io.gitlab.jfronny.libjf.LibJf;
|
|
import io.gitlab.jfronny.libjf.config.api.v1.Entry;
|
|
import io.gitlab.jfronny.libjf.config.api.v1.EntryInfo;
|
|
import io.gitlab.jfronny.libjf.config.api.v1.type.Type;
|
|
import io.gitlab.jfronny.libjf.config.impl.entrypoint.JfConfigSafe;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Field;
|
|
import java.util.Arrays;
|
|
import java.util.Objects;
|
|
import java.util.stream.Collectors;
|
|
|
|
public class DslEntryInfo<T> implements EntryInfo<T> {
|
|
private final String name;
|
|
private final T defaultValue;
|
|
private final ThrowingSupplier<T, IllegalAccessException> get;
|
|
private final ThrowingConsumer<T, IllegalAccessException> set;
|
|
private final Type type;
|
|
private final int width;
|
|
private final double minValue;
|
|
private final double maxValue;
|
|
|
|
public DslEntryInfo(String name,
|
|
T defaultValue,
|
|
ThrowingSupplier<T, IllegalAccessException> get,
|
|
ThrowingConsumer<T, IllegalAccessException> set,
|
|
Type type,
|
|
int width,
|
|
double minValue,
|
|
double maxValue) {
|
|
this.name = name;
|
|
this.defaultValue = defaultValue;
|
|
this.get = get;
|
|
this.set = set;
|
|
this.type = type;
|
|
this.width = width;
|
|
this.minValue = minValue;
|
|
this.maxValue = maxValue;
|
|
}
|
|
|
|
public DslEntryInfo(String name,
|
|
T def,
|
|
ThrowingSupplier<T, IllegalAccessException> get,
|
|
ThrowingConsumer<T, IllegalAccessException> set,
|
|
Type type) {
|
|
this(name, def, get, set, type, 100, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
|
|
}
|
|
|
|
public static DslEntryInfo<Object> ofField(Field field) {
|
|
Entry entry = field.getAnnotation(Entry.class);
|
|
Object defaultValue = null;
|
|
try {
|
|
defaultValue = field.get(null);
|
|
} catch (IllegalAccessException ignored) {
|
|
}
|
|
//noinspection unchecked,rawtypes
|
|
return new DslEntryInfo<Object>(
|
|
field.getName(),
|
|
defaultValue,
|
|
() -> field.get(null),
|
|
v -> field.set(null, v),
|
|
(Type) Type.ofClass(field.getGenericType()),
|
|
entry == null ? 100 : entry.width(),
|
|
entry == null ? Double.NEGATIVE_INFINITY : entry.min(),
|
|
entry == null ? Double.POSITIVE_INFINITY : entry.max()
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
public T getDefault() {
|
|
return defaultValue;
|
|
}
|
|
|
|
@Override
|
|
public T getValue() throws IllegalAccessException {
|
|
return get.get();
|
|
}
|
|
|
|
@Override
|
|
public void setValue(T value) throws IllegalAccessException {
|
|
set.accept(value);
|
|
}
|
|
|
|
@Override
|
|
public Type getValueType() {
|
|
return type;
|
|
}
|
|
|
|
@Override
|
|
public void fix() {
|
|
Object value;
|
|
try {
|
|
value = getValue();
|
|
} catch (IllegalAccessException e) {
|
|
LibJf.LOGGER.error("Could not read value", e);
|
|
return;
|
|
}
|
|
final Object valueOriginal = value;
|
|
if (value instanceof final Integer v) {
|
|
if (v < minValue) value = (int)minValue;
|
|
if (v > maxValue) value = (int)maxValue;
|
|
} else if (value instanceof final Float v) {
|
|
if (v < minValue) value = (float)minValue;
|
|
if (v > maxValue) value = (float)maxValue;
|
|
} else if (value instanceof final Double v) {
|
|
if (v < minValue) value = minValue;
|
|
if (v > maxValue) value = maxValue;
|
|
}
|
|
if (valueOriginal != value) {
|
|
try {
|
|
setUnchecked(value);
|
|
} catch (IllegalAccessException e) {
|
|
LibJf.LOGGER.error("Could not write value", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void loadFromJson(JsonElement element) throws IllegalAccessException {
|
|
if (type.isBool()) {
|
|
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isBoolean()) {
|
|
setUnchecked(element.getAsBoolean());
|
|
}
|
|
} else if (type.isString()) {
|
|
if (element.isJsonPrimitive()) {
|
|
setUnchecked(element.getAsString());
|
|
}
|
|
} else if (type.isInt()) {
|
|
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) {
|
|
setUnchecked(element.getAsNumber().intValue());
|
|
}
|
|
} else if (type.isLong()) {
|
|
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) {
|
|
setUnchecked(element.getAsNumber().longValue());
|
|
}
|
|
} else if (type.isDouble()) {
|
|
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) {
|
|
setUnchecked(element.getAsNumber().doubleValue());
|
|
}
|
|
} else if (type.isFloat()) {
|
|
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) {
|
|
setUnchecked(element.getAsNumber().floatValue());
|
|
}
|
|
} else if (type.isEnum()) {
|
|
Type.TEnum<T> e = (Type.TEnum<T>) type;
|
|
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
|
setUnchecked(e.optionForString(element.getAsString()));
|
|
}
|
|
} else {
|
|
setValue(GsonHolder.getGson().fromJson(element, type.asClass()));
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private void setUnchecked(Object object) throws IllegalAccessException {
|
|
if (object == null) return;
|
|
setValue((T) object);
|
|
}
|
|
|
|
@Override
|
|
public void writeTo(JsonWriter writer, String translationPrefix) throws IOException, IllegalAccessException {
|
|
T value = getValue();
|
|
String val;
|
|
if ((val = JfConfigSafe.TRANSLATION_SUPPLIER.apply(translationPrefix + getName() + ".tooltip")) != null) {
|
|
writer.comment(val);
|
|
}
|
|
if (type.isEnum()) {
|
|
writer.comment("Valid: [" + Arrays.stream(((Type.TEnum<T>)type).options()).map(Objects::toString).collect(Collectors.joining(", ")) + "]");
|
|
}
|
|
writer.name(name);
|
|
GsonHolder.getGson().toJson(value, Objects.requireNonNullElse(type.asClass(), String.class), writer);
|
|
}
|
|
|
|
@Override
|
|
public int getWidth() {
|
|
return width;
|
|
}
|
|
|
|
@Override
|
|
public double getMinValue() {
|
|
return minValue;
|
|
}
|
|
|
|
@Override
|
|
public double getMaxValue() {
|
|
return maxValue;
|
|
}
|
|
}
|