diff options
Diffstat (limited to 'dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java')
-rw-r--r-- | dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java | 374 |
1 files changed, 187 insertions, 187 deletions
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java index 2d7c333..34ea8de 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java @@ -1,187 +1,187 @@ -package io.dico.dicore.command.registration.reflect; - -import io.dico.dicore.command.*; -import io.dico.dicore.command.annotation.Cmd; -import io.dico.dicore.command.annotation.GenerateCommands; -import io.dico.dicore.command.parameter.type.IParameterTypeSelector; -import org.bukkit.command.CommandSender; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -public final class ReflectiveCommand extends Command { - private static final int continuationMask = 1 << 3; - private final Cmd cmdAnnotation; - private final Method method; - private final Object instance; - private String[] parameterOrder; - - // hasContinuation | hasContext | hasSender | hasReceiver - private final int flags; - - ReflectiveCommand(IParameterTypeSelector selector, Method method, Object instance) throws CommandParseException { - if (!method.isAnnotationPresent(Cmd.class)) { - throw new CommandParseException("No @Cmd present for the method " + method.toGenericString()); - } - cmdAnnotation = method.getAnnotation(Cmd.class); - - java.lang.reflect.Parameter[] parameters = method.getParameters(); - - if (!method.isAccessible()) try { - method.setAccessible(true); - } catch (Exception ex) { - throw new CommandParseException("Failed to make method accessible"); - } - - if (!Modifier.isStatic(method.getModifiers())) { - if (instance == null) { - try { - instance = method.getDeclaringClass().newInstance(); - } catch (Exception ex) { - throw new CommandParseException("No instance given for instance method, and failed to create new instance", ex); - } - } else if (!method.getDeclaringClass().isInstance(instance)) { - throw new CommandParseException("Given instance is not an instance of the method's declaring class"); - } - } - - this.method = method; - this.instance = instance; - this.flags = ReflectiveRegistration.parseCommandAttributes(selector, method, this, parameters); - } - - public Method getMethod() { - return method; - } - - public Object getInstance() { - return instance; - } - - public String getCmdName() { return cmdAnnotation.value(); } - - void setParameterOrder(String[] parameterOrder) { - this.parameterOrder = parameterOrder; - } - - ICommandAddress getAddress() { - ChildCommandAddress result = new ChildCommandAddress(); - result.setCommand(this); - - Cmd cmd = cmdAnnotation; - result.getNames().add(cmd.value()); - for (String alias : cmd.aliases()) { - result.getNames().add(alias); - } - result.finalizeNames(); - - GenerateCommands generateCommands = method.getAnnotation(GenerateCommands.class); - if (generateCommands != null) { - ReflectiveRegistration.generateCommands(result, generateCommands.value()); - } - - return result; - } - - @Override - public String execute(CommandSender sender, ExecutionContext context) throws CommandException { - String[] parameterOrder = this.parameterOrder; - int extraArgumentCount = Integer.bitCount(flags); - int parameterStartIndex = Integer.bitCount(flags & ~continuationMask); - - Object[] args = new Object[parameterOrder.length + extraArgumentCount]; - - int i = 0; - - int mask = 1; - if ((flags & mask) != 0) { - // Has receiver - try { - args[i++] = ((ICommandInterceptor) instance).getReceiver(context, method, getCmdName()); - } catch (Exception ex) { - handleException(ex); - return null; // unreachable - } - } - - mask <<= 1; - if ((flags & mask) != 0) { - // Has sender - args[i++] = sender; - } - - mask <<= 1; - if ((flags & mask) != 0) { - // Has context - args[i++] = context; - } - - mask <<= 1; - if ((flags & mask) != 0) { - // Has continuation - - extraArgumentCount--; - } - - for (int n = args.length; i < n; i++) { - args[i] = context.get(parameterOrder[i - extraArgumentCount]); - } - - if ((flags & mask) != 0) { - // Since it has continuation, call as coroutine - return callAsCoroutine(context, args); - } - - return callSynchronously(args); - } - - private boolean isSuspendFunction() { - try { - return KotlinReflectiveRegistrationKt.isSuspendFunction(method); - } catch (Throwable ex) { - return false; - } - } - - public String callSynchronously(Object[] args) throws CommandException { - try { - return getResult(method.invoke(instance, args), null); - } catch (Exception ex) { - return getResult(null, ex); - } - } - - public static String getResult(Object returned, Exception ex) throws CommandException { - if (ex != null) { - handleException(ex); - return null; // unreachable - } - - if (returned instanceof String) { - return (String) returned; - } - return null; - } - - public static void handleException(Exception ex) throws CommandException { - if (ex instanceof InvocationTargetException) { - if (ex.getCause() instanceof CommandException) { - throw (CommandException) ex.getCause(); - } - - ex.printStackTrace(); - throw new CommandException("An internal error occurred while executing this command.", ex); - } - if (ex instanceof CommandException) { - throw (CommandException) ex; - } - ex.printStackTrace(); - throw new CommandException("An internal error occurred while executing this command.", ex); - } - - private String callAsCoroutine(ExecutionContext context, Object[] args) { - return KotlinReflectiveRegistrationKt.callAsCoroutine(this, (ICommandInterceptor) instance, context, args); - } - -} +package io.dico.dicore.command.registration.reflect;
+
+import io.dico.dicore.command.*;
+import io.dico.dicore.command.annotation.Cmd;
+import io.dico.dicore.command.annotation.GenerateCommands;
+import io.dico.dicore.command.parameter.type.IParameterTypeSelector;
+import org.bukkit.command.CommandSender;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public final class ReflectiveCommand extends Command {
+ private static final int continuationMask = 1 << 3;
+ private final Cmd cmdAnnotation;
+ private final Method method;
+ private final Object instance;
+ private String[] parameterOrder;
+
+ // hasContinuation | hasContext | hasSender | hasReceiver
+ private final int flags;
+
+ ReflectiveCommand(IParameterTypeSelector selector, Method method, Object instance) throws CommandParseException {
+ if (!method.isAnnotationPresent(Cmd.class)) {
+ throw new CommandParseException("No @Cmd present for the method " + method.toGenericString());
+ }
+ cmdAnnotation = method.getAnnotation(Cmd.class);
+
+ java.lang.reflect.Parameter[] parameters = method.getParameters();
+
+ if (!method.isAccessible()) try {
+ method.setAccessible(true);
+ } catch (Exception ex) {
+ throw new CommandParseException("Failed to make method accessible");
+ }
+
+ if (!Modifier.isStatic(method.getModifiers())) {
+ if (instance == null) {
+ try {
+ instance = method.getDeclaringClass().newInstance();
+ } catch (Exception ex) {
+ throw new CommandParseException("No instance given for instance method, and failed to create new instance", ex);
+ }
+ } else if (!method.getDeclaringClass().isInstance(instance)) {
+ throw new CommandParseException("Given instance is not an instance of the method's declaring class");
+ }
+ }
+
+ this.method = method;
+ this.instance = instance;
+ this.flags = ReflectiveRegistration.parseCommandAttributes(selector, method, this, parameters);
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public Object getInstance() {
+ return instance;
+ }
+
+ public String getCmdName() { return cmdAnnotation.value(); }
+
+ void setParameterOrder(String[] parameterOrder) {
+ this.parameterOrder = parameterOrder;
+ }
+
+ ICommandAddress getAddress() {
+ ChildCommandAddress result = new ChildCommandAddress();
+ result.setCommand(this);
+
+ Cmd cmd = cmdAnnotation;
+ result.getNames().add(cmd.value());
+ for (String alias : cmd.aliases()) {
+ result.getNames().add(alias);
+ }
+ result.finalizeNames();
+
+ GenerateCommands generateCommands = method.getAnnotation(GenerateCommands.class);
+ if (generateCommands != null) {
+ ReflectiveRegistration.generateCommands(result, generateCommands.value());
+ }
+
+ return result;
+ }
+
+ @Override
+ public String execute(CommandSender sender, ExecutionContext context) throws CommandException {
+ String[] parameterOrder = this.parameterOrder;
+ int extraArgumentCount = Integer.bitCount(flags);
+ int parameterStartIndex = Integer.bitCount(flags & ~continuationMask);
+
+ Object[] args = new Object[parameterOrder.length + extraArgumentCount];
+
+ int i = 0;
+
+ int mask = 1;
+ if ((flags & mask) != 0) {
+ // Has receiver
+ try {
+ args[i++] = ((ICommandInterceptor) instance).getReceiver(context, method, getCmdName());
+ } catch (Exception ex) {
+ handleException(ex);
+ return null; // unreachable
+ }
+ }
+
+ mask <<= 1;
+ if ((flags & mask) != 0) {
+ // Has sender
+ args[i++] = sender;
+ }
+
+ mask <<= 1;
+ if ((flags & mask) != 0) {
+ // Has context
+ args[i++] = context;
+ }
+
+ mask <<= 1;
+ if ((flags & mask) != 0) {
+ // Has continuation
+
+ extraArgumentCount--;
+ }
+
+ for (int n = args.length; i < n; i++) {
+ args[i] = context.get(parameterOrder[i - extraArgumentCount]);
+ }
+
+ if ((flags & mask) != 0) {
+ // Since it has continuation, call as coroutine
+ return callAsCoroutine(context, args);
+ }
+
+ return callSynchronously(args);
+ }
+
+ private boolean isSuspendFunction() {
+ try {
+ return KotlinReflectiveRegistrationKt.isSuspendFunction(method);
+ } catch (Throwable ex) {
+ return false;
+ }
+ }
+
+ public String callSynchronously(Object[] args) throws CommandException {
+ try {
+ return getResult(method.invoke(instance, args), null);
+ } catch (Exception ex) {
+ return getResult(null, ex);
+ }
+ }
+
+ public static String getResult(Object returned, Exception ex) throws CommandException {
+ if (ex != null) {
+ handleException(ex);
+ return null; // unreachable
+ }
+
+ if (returned instanceof String) {
+ return (String) returned;
+ }
+ return null;
+ }
+
+ public static void handleException(Exception ex) throws CommandException {
+ if (ex instanceof InvocationTargetException) {
+ if (ex.getCause() instanceof CommandException) {
+ throw (CommandException) ex.getCause();
+ }
+
+ ex.printStackTrace();
+ throw new CommandException("An internal error occurred while executing this command.", ex);
+ }
+ if (ex instanceof CommandException) {
+ throw (CommandException) ex;
+ }
+ ex.printStackTrace();
+ throw new CommandException("An internal error occurred while executing this command.", ex);
+ }
+
+ private String callAsCoroutine(ExecutionContext context, Object[] args) {
+ return KotlinReflectiveRegistrationKt.callAsCoroutine(this, (ICommandInterceptor) instance, context, args);
+ }
+
+}
|