package com.gt22.pbbot.utils; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.jooq.lambda.Unchecked; import java.io.FileReader; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; //=============================================================================================================== // Я серьёзно советую не читать код который идёт дальше если он ещё работает // Чтение этого кода может закончится психической травмой от переизбытка рефлексии //=============================================================================================================== public class ConfigUtils { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ManualConfigProperty {} public static T loadConfig(Class configClass, String configFilename, JsonElement defaultConfig) throws Exception { return loadConfig(configClass, new JsonParser().parse(new FileReader(configFilename)).getAsJsonObject(), defaultConfig.getAsJsonObject()); } public static T loadConfig(Class configClass, JsonObject config, JsonObject defaultConfig) throws Exception { T cfg = configClass.newInstance(); Arrays.stream(configClass.getFields()).forEach(Unchecked.consumer(f -> { if(!f.isAnnotationPresent(ManualConfigProperty.class)) { String name = f.getName(); f.setAccessible(true); JsonElement value = config.has(name) ? config.get(name) : defaultConfig.get(name); if (value == null) { f.set(cfg, null); } else { f.set(cfg, convertElementToType(f.getType(), value)); } } })); try { Method loadManual = configClass.getMethod("loadManual", JsonObject.class); loadManual.invoke(cfg, config); } catch(NoSuchMethodException e) { //No manual load } return cfg; } private static Object convertElementToType(Class type, JsonElement e) { if (type == String.class) { return e.getAsString(); } else if (type == byte.class || type == Byte.class) { return e.getAsByte(); } else if (type == short.class || type == Short.class) { return e.getAsShort(); } else if (type == int.class || type == Integer.class) { return e.getAsInt(); } else if (type == long.class || type == Long.class) { return e.getAsLong(); } else if (type == double.class || type == Double.class) { return e.getAsDouble(); } else if (type == float.class || type == Float.class) { return e.getAsFloat(); } else if (type == char.class || type == Character.class) { return e.getAsCharacter(); } else if (type == Number.class) { return e.getAsNumber(); } else if (type == BigInteger.class) { return e.getAsBigInteger(); } else if (type == BigDecimal.class) { return e.getAsBigDecimal(); } else if (type.isArray()) { JsonArray arr = e.getAsJsonArray(); Class arrType = type.getComponentType(); Object ret = Array.newInstance(arrType, arr.size()); for(int i = 0; i < arr.size(); i++) { Object o = convertElementToType(arrType, arr.get(i)); Array.set(ret, i, o); } return ret; } else { throw new IllegalArgumentException("Invalid type " + type.getName()); } } }