2022-08-26 20:51:00 +02:00
package io.gitlab.jfronny.libjf.config.impl.reflect ;
2022-10-15 11:29:48 +02:00
import io.gitlab.jfronny.commons.reflect.Reflect ;
import io.gitlab.jfronny.commons.throwable.ThrowingConsumer ;
2022-08-26 20:51:00 +02:00
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 ;
2022-10-15 11:29:48 +02:00
import java.lang.reflect.Field ;
import java.lang.reflect.Method ;
2022-08-26 20:51:00 +02:00
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 ( ) ) {
2022-10-15 11:29:48 +02:00
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 ( ) ) ;
2022-08-26 20:51:00 +02:00
}
}
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 ;
}
2022-10-15 11:29:48 +02:00
public static < T > ThrowingConsumer < T , Throwable > staticToConsumer ( Class < ? > klazz , Method method ) throws Throwable {
Runnable rn = Reflect . staticProcedure ( klazz , method . getName ( ) ) ;
return c - > rn . run ( ) ;
}
2022-08-26 20:51:00 +02:00
}