diff --git a/lib/src/main/java/net/tomatentum/marinara/Marinara.java b/lib/src/main/java/net/tomatentum/marinara/Marinara.java index cbed606..0896858 100644 --- a/lib/src/main/java/net/tomatentum/marinara/Marinara.java +++ b/lib/src/main/java/net/tomatentum/marinara/Marinara.java @@ -1,22 +1,34 @@ package net.tomatentum.marinara; +import net.tomatentum.marinara.registry.InteractionCheckRegistry; import net.tomatentum.marinara.registry.InteractionRegistry; import net.tomatentum.marinara.wrapper.LibraryWrapper; public class Marinara { public static Marinara load(LibraryWrapper wrapper) { - InteractionRegistry registry = new InteractionRegistry(wrapper); - return new Marinara(registry); + return new Marinara(wrapper); } private InteractionRegistry registry; + private InteractionCheckRegistry checkRegistry; + private LibraryWrapper wrapper; - private Marinara(InteractionRegistry registry) { - this.registry = registry; + private Marinara(LibraryWrapper wrapper) { + this.wrapper = wrapper; + this.registry = new InteractionRegistry(this); + this.checkRegistry = new InteractionCheckRegistry(); } public InteractionRegistry getRegistry() { return registry; } + + public InteractionCheckRegistry getCheckRegistry() { + return checkRegistry; + } + + public LibraryWrapper getWrapper() { + return wrapper; + } } diff --git a/lib/src/main/java/net/tomatentum/marinara/checks/AppliedCheck.java b/lib/src/main/java/net/tomatentum/marinara/checks/AppliedCheck.java new file mode 100644 index 0000000..266c57d --- /dev/null +++ b/lib/src/main/java/net/tomatentum/marinara/checks/AppliedCheck.java @@ -0,0 +1,26 @@ +package net.tomatentum.marinara.checks; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; + +public record AppliedCheck(InteractionCheck check, Annotation annotation) { + + public boolean pre() { + try { + return (boolean) check.getClass().getMethod("preExec", annotation.getClass()).invoke(check, annotation); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + e.printStackTrace(); + return false; + } + } + + public boolean post() { + try { + return (boolean) check.getClass().getMethod("postExec", annotation.getClass()).invoke(check, annotation); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + e.printStackTrace(); + return false; + } + } + +} diff --git a/lib/src/main/java/net/tomatentum/marinara/checks/InteractionCheck.java b/lib/src/main/java/net/tomatentum/marinara/checks/InteractionCheck.java new file mode 100644 index 0000000..f6e450c --- /dev/null +++ b/lib/src/main/java/net/tomatentum/marinara/checks/InteractionCheck.java @@ -0,0 +1,10 @@ +package net.tomatentum.marinara.checks; + +import java.lang.annotation.Annotation; + +public interface InteractionCheck { + + public boolean preExec(A annotation); + public boolean postExec(A annotation); + +} diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java index c366b48..f6b2a9e 100644 --- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java @@ -2,18 +2,18 @@ package net.tomatentum.marinara.interaction.methods; import java.lang.reflect.Method; +import net.tomatentum.marinara.Marinara; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.parser.AnnotationParser; import net.tomatentum.marinara.parser.ButtonParser; -import net.tomatentum.marinara.wrapper.LibraryWrapper; public class ButtonInteractionMethod extends InteractionMethod { private String customId; - ButtonInteractionMethod(Method method, InteractionHandler handler, LibraryWrapper wrapper) { - super(method, handler, wrapper); + ButtonInteractionMethod(Method method, InteractionHandler handler, Marinara marinara) { + super(method, handler, marinara); } @Override @@ -26,12 +26,12 @@ public class ButtonInteractionMethod extends InteractionMethod { @Override public Object getParameter(Object parameter, int index) { Class type = getMethod().getParameterTypes()[index+1]; - return wrapper.getComponentContextObject(parameter, type); + return marinara.getWrapper().getComponentContextObject(parameter, type); } @Override public boolean canRun(Object context) { - return wrapper.getButtonId(context).equals(customId); + return marinara.getWrapper().getButtonId(context).equals(customId); } @Override diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java index ca8d263..2a55f9d 100644 --- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java @@ -7,37 +7,48 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import net.tomatentum.marinara.Marinara; +import net.tomatentum.marinara.checks.AppliedCheck; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.interaction.annotation.Button; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; import net.tomatentum.marinara.parser.AnnotationParser; -import net.tomatentum.marinara.wrapper.LibraryWrapper; +import net.tomatentum.marinara.parser.InteractionCheckParser; public abstract class InteractionMethod { - public static InteractionMethod create(Method method, InteractionHandler handler, LibraryWrapper wrapper) { + public static InteractionMethod create(Method method, InteractionHandler handler, Marinara marinara) { if (method.isAnnotationPresent(SlashCommand.class) || method.isAnnotationPresent(SubCommand.class)) - return new SlashCommandInteractionMethod(method, handler, wrapper); + return new SlashCommandInteractionMethod(method, handler, marinara); if (method.isAnnotationPresent(Button.class)) - return new ButtonInteractionMethod(method, handler, wrapper); + return new ButtonInteractionMethod(method, handler, marinara); return null; } protected Method method; protected InteractionHandler handler; - protected LibraryWrapper wrapper; - protected AnnotationParser[] parsers; + protected Marinara marinara; + protected List parsers; + protected List appliedChecks; - protected InteractionMethod(Method method, InteractionHandler handler, LibraryWrapper wrapper) { + protected InteractionMethod(Method method, + InteractionHandler handler, + Marinara marinara + ) { if (!Arrays.asList(handler.getClass().getMethods()).contains(method)) throw new InvalidParameterException("Method does not apply to specified handler"); + this.method = method; this.handler = handler; - this.wrapper = wrapper; - this.parsers = getParsers(); - Arrays.stream(parsers).forEach(AnnotationParser::parse); + this.marinara = marinara; + this.parsers = new ArrayList<>(Arrays.asList(getParsers())); + this.appliedChecks = new ArrayList<>(); + + parsers.add(new InteractionCheckParser(method, appliedChecks::add, marinara.getCheckRegistry())); + + parsers.stream().forEach(AnnotationParser::parse); } public abstract AnnotationParser[] getParsers(); @@ -49,6 +60,23 @@ public abstract class InteractionMethod { public abstract InteractionType getType(); public void run(Object context) { + this.appliedChecks.forEach(AppliedCheck::pre); + + method.setAccessible(true); + try { + method.invoke(handler, getParameters(context)); + }catch (IllegalAccessException | InvocationTargetException ex) { + throw new RuntimeException(ex); + } + + this.appliedChecks.forEach(AppliedCheck::post); + } + + public Method getMethod() { + return method; + } + + private Object[] getParameters(Object context) { int parameterCount = method.getParameterCount(); List parameters = new ArrayList<>(); @@ -59,16 +87,7 @@ public abstract class InteractionMethod { } parameters.add(getParameter(context, i-1)); } - method.setAccessible(true); - try { - method.invoke(handler, parameters.toArray()); - }catch (IllegalAccessException | InvocationTargetException ex) { - throw new RuntimeException(ex); - } - } - - public Method getMethod() { - return method; + return parameters.toArray(); } } diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java index cd63d69..666dd3c 100644 --- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java @@ -2,19 +2,19 @@ package net.tomatentum.marinara.interaction.methods; import java.lang.reflect.Method; +import net.tomatentum.marinara.Marinara; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition; import net.tomatentum.marinara.parser.AnnotationParser; import net.tomatentum.marinara.parser.SlashCommandParser; -import net.tomatentum.marinara.wrapper.LibraryWrapper; public class SlashCommandInteractionMethod extends InteractionMethod { private ExecutableSlashCommandDefinition commandDefinition; - SlashCommandInteractionMethod(Method method, InteractionHandler handler, LibraryWrapper wrapper) { - super(method, handler, wrapper); + SlashCommandInteractionMethod(Method method, InteractionHandler handler, Marinara marinara) { + super(method, handler, marinara); } @Override @@ -26,12 +26,12 @@ public class SlashCommandInteractionMethod extends InteractionMethod { @Override public Object getParameter(Object context, int index) { - return wrapper.convertCommandOption(context, commandDefinition.options()[index].type(), commandDefinition.options()[index].name()); + return marinara.getWrapper().convertCommandOption(context, commandDefinition.options()[index].type(), commandDefinition.options()[index].name()); } @Override public boolean canRun(Object context) { - ExecutableSlashCommandDefinition other = wrapper.getCommandDefinition(context); + ExecutableSlashCommandDefinition other = marinara.getWrapper().getCommandDefinition(context); return commandDefinition.equals(other); } diff --git a/lib/src/main/java/net/tomatentum/marinara/parser/InteractionCheckParser.java b/lib/src/main/java/net/tomatentum/marinara/parser/InteractionCheckParser.java new file mode 100644 index 0000000..2722456 --- /dev/null +++ b/lib/src/main/java/net/tomatentum/marinara/parser/InteractionCheckParser.java @@ -0,0 +1,42 @@ +package net.tomatentum.marinara.parser; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Optional; +import java.util.function.Consumer; + +import net.tomatentum.marinara.checks.AppliedCheck; +import net.tomatentum.marinara.checks.InteractionCheck; +import net.tomatentum.marinara.registry.InteractionCheckRegistry; + +public class InteractionCheckParser implements AnnotationParser { + + private InteractionCheckRegistry checkRegistry; + private Method method; + private Consumer consumer; + + public InteractionCheckParser(Method method, Consumer consumer, InteractionCheckRegistry checkRegistry) { + this.checkRegistry = checkRegistry; + this.method = method; + this.consumer = consumer; + } + + @Override + public void parse() { + Annotation[] annotations = method.getAnnotations(); + Arrays.stream(annotations).forEach(this::convertAnnotation); + } + + private void convertAnnotation(Annotation annotation) { + Optional> check = this.checkRegistry.getCheckFromAnnotation(annotation.getClass()); + if (check.isPresent()) + consumer.accept(new AppliedCheck(check.get(), annotation)); + } + + @Override + public Method getMethod() { + return this.method; + } + +} diff --git a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionCheckRegistry.java b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionCheckRegistry.java new file mode 100644 index 0000000..59a643e --- /dev/null +++ b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionCheckRegistry.java @@ -0,0 +1,32 @@ +package net.tomatentum.marinara.registry; + +import java.lang.annotation.Annotation; +import java.lang.reflect.TypeVariable; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import net.tomatentum.marinara.checks.InteractionCheck; + +public class InteractionCheckRegistry { + + private List> checks; + + public InteractionCheckRegistry() { + this.checks = new ArrayList<>(); + } + + public void addCheck(InteractionCheck check) { + checks.add(check); + } + + public Optional> getCheckFromAnnotation(Class annotation) { + for (InteractionCheck interactionCheck : checks) { + TypeVariable type = interactionCheck.getClass().getTypeParameters()[0]; + if (type.getClass().equals(annotation.getClass())) + return Optional.of(interactionCheck); + } + return Optional.empty(); + } + +} diff --git a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java index 31e3ad1..443ea39 100644 --- a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java +++ b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java @@ -5,27 +5,27 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import net.tomatentum.marinara.Marinara; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition; import net.tomatentum.marinara.interaction.methods.SlashCommandInteractionMethod; import net.tomatentum.marinara.interaction.methods.InteractionMethod; -import net.tomatentum.marinara.wrapper.LibraryWrapper; public class InteractionRegistry { private List interactionMethods; - private LibraryWrapper wrapper; + private Marinara marinara; - public InteractionRegistry(LibraryWrapper wrapper) { + public InteractionRegistry(Marinara marinara) { this.interactionMethods = new ArrayList<>(); - this.wrapper = wrapper; - wrapper.subscribeInteractions(this::handle); + this.marinara = marinara; + marinara.getWrapper().subscribeInteractions(this::handle); } public void addInteractions(InteractionHandler interactionHandler) { for (Method method : interactionHandler.getClass().getMethods()) { - InteractionMethod iMethod = InteractionMethod.create(method, interactionHandler, wrapper); + InteractionMethod iMethod = InteractionMethod.create(method, interactionHandler, marinara); if (iMethod != null) this.interactionMethods.add(iMethod); } @@ -48,12 +48,12 @@ public class InteractionRegistry { defs.add(new SlashCommandDefinition(def.applicationCommand()).addExecutableCommand(def)); }); - wrapper.registerSlashCommands(defs.toArray(new SlashCommandDefinition[0])); + marinara.getWrapper().registerSlashCommands(defs.toArray(new SlashCommandDefinition[0])); } public void handle(Object context) { interactionMethods.forEach((m) -> { - InteractionType type = wrapper.getInteractionType(context.getClass()); + InteractionType type = marinara.getWrapper().getInteractionType(context.getClass()); if (m.getType().equals(type)) m.run(context); });