From a14b30caeac8835f83ee34fdecb26e7c7d5f81e0 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 14 Jan 2018 19:01:26 -0500 Subject: [PATCH] Add @CatchAll as a better named replacement to @UnknownHandler UnknownHandler will still work until we remove it in some future major update --- .../co/aikar/commands/BukkitRootCommand.java | 2 +- .../co/aikar/commands/BungeeRootCommand.java | 2 +- .../java/co/aikar/commands/BaseCommand.java | 29 ++++++++++-------- .../java/co/aikar/commands/CommandHelp.java | 2 +- .../co/aikar/commands/RegisteredCommand.java | 2 +- .../java/co/aikar/commands/RootCommand.java | 2 +- .../aikar/commands/annotation/CatchAll.java | 30 +++++++++++++++++++ .../commands/annotation/UnknownHandler.java | 4 +++ .../co/aikar/commands/SpongeRootCommand.java | 2 +- 9 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 core/src/main/java/co/aikar/commands/annotation/CatchAll.java diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java b/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java index 44919cc9..11970a22 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java @@ -65,7 +65,7 @@ public class BukkitRootCommand extends Command implements RootCommand { } public void addChild(BaseCommand command) { - if (this.defCommand == null || !command.subCommands.get("__default").isEmpty()) { + if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { this.defCommand = command; this.setPermission(command.permission); //this.setDescription(command.getDescription()); diff --git a/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java b/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java index 58e72d78..b93d173b 100644 --- a/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java +++ b/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java @@ -54,7 +54,7 @@ public class BungeeRootCommand extends Command implements RootCommand, TabExecut @Override public void addChild(BaseCommand command) { - if (this.defCommand == null || !command.subCommands.get("__default").isEmpty()) { + if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { this.defCommand = command; } diff --git a/core/src/main/java/co/aikar/commands/BaseCommand.java b/core/src/main/java/co/aikar/commands/BaseCommand.java index 027b5a8c..1ced5fad 100644 --- a/core/src/main/java/co/aikar/commands/BaseCommand.java +++ b/core/src/main/java/co/aikar/commands/BaseCommand.java @@ -23,6 +23,7 @@ package co.aikar.commands; +import co.aikar.commands.annotation.CatchAll; import co.aikar.commands.annotation.CommandAlias; import co.aikar.commands.annotation.CommandPermission; import co.aikar.commands.annotation.Default; @@ -60,7 +61,7 @@ import java.util.stream.Stream; @SuppressWarnings("unused") public abstract class BaseCommand { - public static final String UNKNOWN = "__unknown"; + public static final String CATCHALL = "__catchall"; public static final String DEFAULT = "__default"; final SetMultimap subCommands = HashMultimap.create(); private Method preCommandHandler; @@ -138,7 +139,7 @@ public abstract class BaseCommand { } boolean foundDefault = false; - boolean foundUnknown = false; + boolean foundCatchAll = false; boolean isParentEmpty = parentSubcommand.isEmpty(); for (Method method : self.getMethods()) { method.setAccessible(true); @@ -172,14 +173,16 @@ public abstract class BaseCommand { } UnknownHandler unknown = method.getAnnotation(UnknownHandler.class); + CatchAll catchAll = method.getAnnotation(CatchAll.class); PreCommand preCommand = method.getAnnotation(PreCommand.class); - if (unknown != null || (!foundUnknown && helpCommand != null)) { - if (!foundUnknown) { - if (unknown != null) { - this.subCommands.get(UNKNOWN).clear(); - foundUnknown = true; + boolean hasCatchAll = catchAll != null || unknown != null; + if (hasCatchAll || (!foundCatchAll && helpCommand != null)) { + if (!foundCatchAll) { + if (hasCatchAll) { + this.subCommands.get(CATCHALL).clear(); + foundCatchAll = true; } - registerSubcommand(method, UNKNOWN); + registerSubcommand(method, CATCHALL); } else { ACFUtil.sneaky(new IllegalStateException("Multiple @UnknownHandler/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); } @@ -353,8 +356,8 @@ public abstract class BaseCommand { if (subCommands.get(DEFAULT) != null && args.length == 0) { executeSubcommand(commandContext, DEFAULT, issuer, args); - } else if (subCommands.get(UNKNOWN) != null) { - if (!executeSubcommand(commandContext, UNKNOWN, issuer, args)) { + } else if (subCommands.get(CATCHALL) != null) { + if (!executeSubcommand(commandContext, CATCHALL, issuer, args)) { help(issuer, args); } } else if (subCommands.get(DEFAULT) != null) { @@ -473,8 +476,8 @@ public abstract class BaseCommand { if (search != null) { cmds.addAll(completeCommand(issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel, isAsync)); - } else if (subCommands.get(UNKNOWN).size() == 1) { - cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(UNKNOWN)), args, commandLabel, isAsync)); + } else if (subCommands.get(CATCHALL).size() == 1) { + cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(CATCHALL)), args, commandLabel, isAsync)); } else if (subCommands.get(DEFAULT).size() == 1) { cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(DEFAULT)), args, commandLabel, isAsync)); } @@ -490,7 +493,7 @@ public abstract class BaseCommand { String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); for (Map.Entry entry : subCommands.entries()) { final String key = entry.getKey(); - if (key.startsWith(argString) && !UNKNOWN.equals(key) && !DEFAULT.equals(key)) { + if (key.startsWith(argString) && !CATCHALL.equals(key) && !DEFAULT.equals(key)) { final RegisteredCommand value = entry.getValue(); if (!value.hasPermission(issuer)) { continue; diff --git a/core/src/main/java/co/aikar/commands/CommandHelp.java b/core/src/main/java/co/aikar/commands/CommandHelp.java index 943896e5..11b35ea0 100644 --- a/core/src/main/java/co/aikar/commands/CommandHelp.java +++ b/core/src/main/java/co/aikar/commands/CommandHelp.java @@ -53,7 +53,7 @@ public class CommandHelp { Set seen = new HashSet<>(); subCommands.entries().forEach(e -> { String key = e.getKey(); - if (key.equals("__default") || key.equals("__unknown")){ + if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.CATCHALL)){ return; } diff --git a/core/src/main/java/co/aikar/commands/RegisteredCommand.java b/core/src/main/java/co/aikar/commands/RegisteredCommand.java index ed151e5c..9c4daf7e 100644 --- a/core/src/main/java/co/aikar/commands/RegisteredCommand.java +++ b/core/src/main/java/co/aikar/commands/RegisteredCommand.java @@ -72,7 +72,7 @@ public class RegisteredCommand { String key = e.getKey(); RegisteredCommand registeredCommand = e.getValue(); - if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.UNKNOWN)) { + if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.CATCHALL)) { return; } Set registered = subCommands.get(key); diff --git a/core/src/main/java/co/aikar/commands/annotation/CatchAll.java b/core/src/main/java/co/aikar/commands/annotation/CatchAll.java new file mode 100644 index 00000000..672c50bf --- /dev/null +++ b/core/src/main/java/co/aikar/commands/annotation/CatchAll.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016-2018 Daniel Ennis (Aikar) - MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package co.aikar.commands.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface CatchAll {} diff --git a/core/src/main/java/co/aikar/commands/annotation/UnknownHandler.java b/core/src/main/java/co/aikar/commands/annotation/UnknownHandler.java index 767fb1a1..7fa64c1b 100644 --- a/core/src/main/java/co/aikar/commands/annotation/UnknownHandler.java +++ b/core/src/main/java/co/aikar/commands/annotation/UnknownHandler.java @@ -27,5 +27,9 @@ package co.aikar.commands.annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * @deprecated Use {@link CatchAll instead, which is more accurately named} + */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) public @interface UnknownHandler {} diff --git a/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java b/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java index bd754998..f548f5a7 100644 --- a/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java +++ b/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java @@ -96,7 +96,7 @@ public class SpongeRootCommand implements CommandCallable, RootCommand { } public void addChild(BaseCommand command) { - if (this.defCommand == null || !command.subCommands.get("__default").isEmpty()) { + if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { this.defCommand = command; } addChildShared(this.children, this.subCommands, command);