From 64329ad7ccedba53c47ccd3a08b9eb97e756122c Mon Sep 17 00:00:00 2001 From: nextdaydelivery <79922345+nxtdaydelivery@users.noreply.github.com> Date: Mon, 25 Jul 2022 11:39:45 +0100 Subject: Config Checker (#67) --- api/OneConfig.api | 8 +++++++ .../oneconfig/config/core/ConfigUtils.java | 21 ++++++++++++++++- .../core/exceptions/InvalidTypeException.java | 26 ++++++++++++++++++++++ .../gson/NonProfileSpecificExclusionStrategy.java | 1 + .../config/gson/ProfileExclusionStrategy.java | 1 + .../polyfrost/oneconfig/events/EventManager.java | 19 +++++++++++++++- 6 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/core/exceptions/InvalidTypeException.java diff --git a/api/OneConfig.api b/api/OneConfig.api index a910bad..564976d 100644 --- a/api/OneConfig.api +++ b/api/OneConfig.api @@ -201,6 +201,14 @@ public class cc/polyfrost/oneconfig/config/core/OneKeyBind { public fun setRunnable (Ljava/lang/Runnable;)V } +public class cc/polyfrost/oneconfig/config/core/exceptions/InvalidTypeException : java/lang/RuntimeException { + public fun ()V + public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/Throwable;)V + protected fun (Ljava/lang/String;Ljava/lang/Throwable;ZZ)V + public fun (Ljava/lang/Throwable;)V +} + public final class cc/polyfrost/oneconfig/config/data/InfoType : java/lang/Enum { public static final field ERROR Lcc/polyfrost/oneconfig/config/data/InfoType; public static final field INFO Lcc/polyfrost/oneconfig/config/data/InfoType; diff --git a/src/main/java/cc/polyfrost/oneconfig/config/core/ConfigUtils.java b/src/main/java/cc/polyfrost/oneconfig/config/core/ConfigUtils.java index 2b3c90b..bacfe8b 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/core/ConfigUtils.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/core/ConfigUtils.java @@ -1,6 +1,7 @@ package cc.polyfrost.oneconfig.config.core; -import cc.polyfrost.oneconfig.config.annotations.Exclude; +import cc.polyfrost.oneconfig.config.core.exceptions.InvalidTypeException; +import cc.polyfrost.oneconfig.config.data.OptionType; import cc.polyfrost.oneconfig.config.elements.BasicOption; import cc.polyfrost.oneconfig.config.elements.OptionCategory; import cc.polyfrost.oneconfig.config.elements.OptionPage; @@ -20,31 +21,49 @@ public class ConfigUtils { public static BasicOption getOption(Option option, Field field, Object instance) { switch (option.type()) { case SWITCH: + check(OptionType.SWITCH, field, boolean.class, Boolean.class); return ConfigSwitch.create(field, instance); case CHECKBOX: + check(OptionType.CHECKBOX, field, boolean.class, Boolean.class); return ConfigCheckbox.create(field, instance); case INFO: return ConfigInfo.create(field, instance); case HEADER: return ConfigHeader.create(field, instance); case COLOR: + check(OptionType.COLOR, field, OneColor.class); return ConfigColorElement.create(field, instance); case DROPDOWN: + check(OptionType.DROPDOWN, field, int.class, Integer.class); return ConfigDropdown.create(field, instance); case TEXT: + check(OptionType.TEXT, field, String.class); return ConfigTextBox.create(field, instance); case BUTTON: + check(OptionType.BUTTON, field, Runnable.class); return ConfigButton.create(field, instance); case SLIDER: + check(OptionType.SLIDER, field, int.class, float.class, Integer.class, Float.class); return ConfigSlider.create(field, instance); case KEYBIND: + check(OptionType.KEYBIND, field, OneKeyBind.class); return ConfigKeyBind.create(field, instance); case DUAL_OPTION: + check(OptionType.DUAL_OPTION, field, boolean.class, Boolean.class); return ConfigDualOption.create(field, instance); } return null; } + private static void check(OptionType type, Field field, Class... expectedType) { + // I have tried to check for supertype classes like Boolean other ways. + // but they actually don't extend their primitive types (because that is impossible) so isAssignableFrom doesn't work. + for (Class clazz : expectedType) { + if(field.getType().equals(clazz)) return; + } + throw new InvalidTypeException("Field " + field.getName() + " in config " + field.getDeclaringClass().getName() + " is annotated as a " + type.toString() + ", but is not of valid type, expected " + Arrays.toString(expectedType) + " (found " + field.getType() + ")"); + } + public static ArrayList getClassOptions(Object object) { ArrayList options = new ArrayList<>(); ArrayList fields = getClassFields(object.getClass()); diff --git a/src/main/java/cc/polyfrost/oneconfig/config/core/exceptions/InvalidTypeException.java b/src/main/java/cc/polyfrost/oneconfig/config/core/exceptions/InvalidTypeException.java new file mode 100644 index 0000000..4ccaaf8 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/core/exceptions/InvalidTypeException.java @@ -0,0 +1,26 @@ +package cc.polyfrost.oneconfig.config.core.exceptions; + +public class InvalidTypeException extends RuntimeException { + + public InvalidTypeException() { + super(); + } + + public InvalidTypeException(String message) { + super(message); + } + + public InvalidTypeException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidTypeException(Throwable cause) { + super(cause); + } + + protected InvalidTypeException(String message, Throwable cause, + boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/NonProfileSpecificExclusionStrategy.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/NonProfileSpecificExclusionStrategy.java index e773295..b737d70 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/gson/NonProfileSpecificExclusionStrategy.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/NonProfileSpecificExclusionStrategy.java @@ -14,6 +14,7 @@ public class NonProfileSpecificExclusionStrategy extends ExclusionUtils implemen @Override public boolean shouldSkipField(FieldAttributes f) { if (isSuperClassOf(f.getDeclaredClass(), Config.class)) return true; + if (f.getDeclaredClass().isAssignableFrom(Runnable.class)) return true; if (f.getAnnotation(NonProfileSpecific.class) == null) return true; Exclude exclude = f.getAnnotation(Exclude.class); return exclude != null; diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/ProfileExclusionStrategy.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/ProfileExclusionStrategy.java index ad9722b..0df63b0 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/gson/ProfileExclusionStrategy.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/ProfileExclusionStrategy.java @@ -14,6 +14,7 @@ public class ProfileExclusionStrategy extends ExclusionUtils implements Exclusio @Override public boolean shouldSkipField(FieldAttributes f) { if (isSuperClassOf(f.getDeclaredClass(), Config.class)) return true; + if (f.getDeclaredClass().isAssignableFrom(Runnable.class)) return true; if (f.getAnnotation(NonProfileSpecific.class) != null) return true; Exclude exclude = f.getAnnotation(Exclude.class); return exclude != null; diff --git a/src/main/java/cc/polyfrost/oneconfig/events/EventManager.java b/src/main/java/cc/polyfrost/oneconfig/events/EventManager.java index 8492806..4e43410 100644 --- a/src/main/java/cc/polyfrost/oneconfig/events/EventManager.java +++ b/src/main/java/cc/polyfrost/oneconfig/events/EventManager.java @@ -1,7 +1,10 @@ package cc.polyfrost.oneconfig.events; +import cc.polyfrost.oneconfig.config.core.exceptions.InvalidTypeException; import cc.polyfrost.oneconfig.libs.eventbus.EventBus; +import cc.polyfrost.oneconfig.libs.eventbus.exception.ExceptionHandler; import cc.polyfrost.oneconfig.libs.eventbus.invokers.LMFInvoker; +import org.jetbrains.annotations.NotNull; /** * Manages all events from OneConfig. @@ -11,7 +14,7 @@ public final class EventManager { * The instance of the {@link EventManager}. */ public static final EventManager INSTANCE = new EventManager(); - private final EventBus eventBus = new EventBus(new LMFInvoker(), Throwable::printStackTrace); + private final EventBus eventBus = new EventBus(new LMFInvoker(), new OneConfigExceptionHandler()); private EventManager() { @@ -55,4 +58,18 @@ public final class EventManager { public void post(Object event) { eventBus.post(event); } + + + /** + * Bypass to allow special exceptions to actually crash + */ + private static class OneConfigExceptionHandler implements ExceptionHandler { + @Override + public void handle(@NotNull Exception e) { + if(e instanceof InvalidTypeException) { + throw (InvalidTypeException) e; + } + else e.printStackTrace(); + } + } } -- cgit