69 lines
3.3 KiB
Java
69 lines
3.3 KiB
Java
package io.gitlab.jfronny.libjf.config.impl.reflect;
|
|
|
|
import io.gitlab.jfronny.commons.reflect.Reflect;
|
|
import io.gitlab.jfronny.commons.throwable.ThrowingConsumer;
|
|
import io.gitlab.jfronny.libjf.LibJf;
|
|
import io.gitlab.jfronny.libjf.config.api.v1.*;
|
|
import io.gitlab.jfronny.libjf.config.api.v1.dsl.CategoryBuilder;
|
|
import io.gitlab.jfronny.libjf.config.api.v1.dsl.ConfigBuilder;
|
|
import io.gitlab.jfronny.libjf.config.api.v1.reflect.ReflectiveConfigBuilder;
|
|
import io.gitlab.jfronny.libjf.config.impl.AuxiliaryMetadata;
|
|
import io.gitlab.jfronny.libjf.config.impl.dsl.DslEntryInfo;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
import java.util.Objects;
|
|
|
|
public class ReflectiveConfigBuilderImpl implements ReflectiveConfigBuilder {
|
|
public static final String CONFIG_PRESET_DEFAULT = "libjf-config-v1.default";
|
|
private final AuxiliaryMetadata rootMeta;
|
|
private final Class<?> rootClass;
|
|
|
|
public ReflectiveConfigBuilderImpl(String id, Class<?> klazz) {
|
|
this.rootClass = Objects.requireNonNull(klazz);
|
|
this.rootMeta = AuxiliaryMetadata.of(klazz.getAnnotation(JfConfig.class))
|
|
.merge(AuxiliaryMetadata.forMod(id));
|
|
}
|
|
|
|
@Override
|
|
public ConfigBuilder<?> apply(ConfigBuilder<?> builder) {
|
|
return applyCategory(builder, rootClass, rootMeta);
|
|
}
|
|
|
|
private static <T extends CategoryBuilder<?>> T applyCategory(T builder, Class<?> configClass, AuxiliaryMetadata meta) {
|
|
meta.applyTo(builder);
|
|
for (Field field : configClass.getFields()) {
|
|
if (field.isAnnotationPresent(Entry.class)) {
|
|
builder.value(DslEntryInfo.ofField(field));
|
|
}
|
|
}
|
|
builder.addPreset(CONFIG_PRESET_DEFAULT, ConfigCategory::reset);
|
|
for (Method method : configClass.getMethods()) {
|
|
try {
|
|
if (method.isAnnotationPresent(Preset.class)) {
|
|
builder.addPreset(builder.getTranslationPrefix() + method.getName(), ReflectiveConfigBuilderImpl.<ConfigCategory>staticToConsumer(configClass, method).addHandler(e -> LibJf.LOGGER.error("Could not apply preset", e)));
|
|
} else if (method.isAnnotationPresent(Verifier.class)) {
|
|
builder.addVerifier(ReflectiveConfigBuilderImpl.<ConfigCategory>staticToConsumer(configClass, method).addHandler(e -> LibJf.LOGGER.error("Could not run verifier", e)));
|
|
}
|
|
} catch (Throwable t) {
|
|
LibJf.LOGGER.error("Could not process method " + method.getName() + " of config class " + configClass.getName());
|
|
}
|
|
}
|
|
|
|
for (Class<?> categoryClass : configClass.getClasses()) {
|
|
if (categoryClass.isAnnotationPresent(Category.class)) {
|
|
String name = categoryClass.getSimpleName();
|
|
name = Character.toLowerCase(name.charAt(0)) + name.substring(1); // camelCase
|
|
builder.category(name, builder1 -> applyCategory(builder1, categoryClass, AuxiliaryMetadata.of(categoryClass.getAnnotation(Category.class))));
|
|
}
|
|
}
|
|
|
|
return builder;
|
|
}
|
|
|
|
public static <T> ThrowingConsumer<T, Throwable> staticToConsumer(Class<?> klazz, Method method) throws Throwable {
|
|
Runnable rn = Reflect.staticProcedure(klazz, method.getName());
|
|
return c -> rn.run();
|
|
}
|
|
}
|