diff --git a/core/src/main/java/co/aikar/commands/BaseCommand.java b/core/src/main/java/co/aikar/commands/BaseCommand.java index c2026a00..3dff86a3 100644 --- a/core/src/main/java/co/aikar/commands/BaseCommand.java +++ b/core/src/main/java/co/aikar/commands/BaseCommand.java @@ -25,11 +25,7 @@ package co.aikar.commands; import co.aikar.commands.annotation.*; import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.SetMultimap; +import com.google.common.collect.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -569,6 +565,18 @@ public abstract class BaseCommand { return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); } + + public Set getRequiredPermissions() { + if (this.permission == null || this.permission.isEmpty()) { + return ImmutableSet.of(); + } + return Sets.newHashSet(ACFPatterns.COMMA.split(this.permission)); + } + + public boolean requiresPermission(String permission) { + return getRequiredPermissions().contains(permission) || this.parentCommand != null && parentCommand.requiresPermission(permission); + } + public String getName() { return commandName; } diff --git a/core/src/main/java/co/aikar/commands/RegisteredCommand.java b/core/src/main/java/co/aikar/commands/RegisteredCommand.java index d2fb3f0e..44e14f9e 100644 --- a/core/src/main/java/co/aikar/commands/RegisteredCommand.java +++ b/core/src/main/java/co/aikar/commands/RegisteredCommand.java @@ -241,7 +241,7 @@ public class RegisteredCommand getPermissions() { + public Set getRequiredPermissions() { if (this.permission == null || this.permission.isEmpty()) { return ImmutableSet.of(); } @@ -260,7 +260,7 @@ public class RegisteredCommand
  • diff --git a/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html b/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html index cfb6650e..21f53842 100644 --- a/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html +++ b/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html @@ -148,7 +148,7 @@ extends co.aikar.commands.RegisteredCommand<
  • diff --git a/docs/acf-core/co/aikar/commands/BaseCommand.html b/docs/acf-core/co/aikar/commands/BaseCommand.html index 00f2fb73..ad0f4522 100644 --- a/docs/acf-core/co/aikar/commands/BaseCommand.html +++ b/docs/acf-core/co/aikar/commands/BaseCommand.html @@ -18,7 +18,7 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":42,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":42,"i19":10,"i20":10}; +var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":42,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":42,"i21":10,"i22":10}; var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"],32:["t6","Deprecated Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; @@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";

    -
    public abstract class BaseCommand
    +
    public abstract class BaseCommand
     extends Object
  • @@ -244,28 +244,36 @@ extends -boolean -hasPermission(CommandIssuer issuer)  +Set<String> +getRequiredPermissions()  boolean -hasPermission(Object issuer)  +hasPermission(CommandIssuer issuer)  +boolean +hasPermission(Object issuer)  + + void help(CommandIssuer issuer, String[] args)  - + void help(Object issuer, String[] args)  - + +boolean +requiresPermission(String permission)  + + BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler)  - + void showCommandHelp()
    Deprecated.  @@ -273,12 +281,12 @@ extends + void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd)  - + List<String> tabComplete(CommandIssuer issuer, String commandLabel, @@ -312,7 +320,7 @@ extends
  • UNKNOWN

    -
    public static final String UNKNOWN
    +
    public static final String UNKNOWN
    See Also:
    Constant Field Values
    @@ -325,7 +333,7 @@ extends
  • DEFAULT

    -
    public static final String DEFAULT
    +
    public static final String DEFAULT
    See Also:
    Constant Field Values
    @@ -346,7 +354,7 @@ extends
  • BaseCommand

    -
    public BaseCommand()
    +
    public BaseCommand()
  • @@ -355,7 +363,7 @@ extends
  • BaseCommand

    -
    public BaseCommand(String cmd)
    +
    public BaseCommand(String cmd)
  • @@ -372,7 +380,7 @@ extends
  • getExecCommandLabel

    -
    public String getExecCommandLabel()
    +
    public String getExecCommandLabel()
    Gets the root command name that the user actually typed
    Returns:
    @@ -386,7 +394,7 @@ extends
  • getExecSubcommand

    -
    public String getExecSubcommand()
    +
    public String getExecSubcommand()
    Gets the actual sub command name the user typed
    Returns:
    @@ -400,7 +408,7 @@ extends
  • getOrigArgs

    -
    public String[] getOrigArgs()
    +
    public String[] getOrigArgs()
    Gets the actual args in string form the user typed
    Returns:
    @@ -414,7 +422,7 @@ extends
  • execute

    -
    public void execute(CommandIssuer issuer,
    +
    public void execute(CommandIssuer issuer,
                         String commandLabel,
                         String[] args)
  • @@ -425,7 +433,7 @@ extends
  • getCurrentCommandIssuer

    -
    public CommandIssuer getCurrentCommandIssuer()
    +
    public CommandIssuer getCurrentCommandIssuer()
  • @@ -434,7 +442,7 @@ extends
  • getCurrentCommandManager

    -
    public CommandManager getCurrentCommandManager()
    +
    public CommandManager getCurrentCommandManager()
  • @@ -443,7 +451,7 @@ extends
  • canExecute

    -
    public boolean canExecute(CommandIssuer issuer,
    +
    public boolean canExecute(CommandIssuer issuer,
                               RegisteredCommand<?> cmd)
  • @@ -453,7 +461,7 @@ extends
  • tabComplete

    -
    public List<StringtabComplete(CommandIssuer issuer,
    +
    public List<StringtabComplete(CommandIssuer issuer,
                                     String commandLabel,
                                     String[] args)
                              throws IllegalArgumentException
    @@ -470,7 +478,7 @@ extends

    getCommandHelp

    @Deprecated
    -public CommandHelp getCommandHelp()
    +public CommandHelp getCommandHelp()
    Deprecated. Unstable API
  • @@ -481,7 +489,7 @@ public 

    showCommandHelp

    @Deprecated
    -public void showCommandHelp()
    +public void showCommandHelp()
    Deprecated. Unstable API
  • @@ -491,7 +499,7 @@ public void 
  • help

    -
    public void help(Object issuer,
    +
    public void help(Object issuer,
                      String[] args)
  • @@ -501,7 +509,7 @@ public void 
  • help

    -
    public void help(CommandIssuer issuer,
    +
    public void help(CommandIssuer issuer,
                      String[] args)
  • @@ -511,7 +519,7 @@ public void 
  • doHelp

    -
    public void doHelp(Object issuer,
    +
    public void doHelp(Object issuer,
                        String... args)
  • @@ -521,7 +529,7 @@ public void 
  • doHelp

    -
    public void doHelp(CommandIssuer issuer,
    +
    public void doHelp(CommandIssuer issuer,
                        String... args)
  • @@ -531,7 +539,7 @@ public void 
  • showSyntax

    -
    public void showSyntax(CommandIssuer issuer,
    +
    public void showSyntax(CommandIssuer issuer,
                            RegisteredCommand<?> cmd)
  • @@ -541,7 +549,7 @@ public void 
  • hasPermission

    -
    public boolean hasPermission(Object issuer)
    +
    public boolean hasPermission(Object issuer)
  • @@ -550,7 +558,25 @@ public void 
  • hasPermission

    -
    public boolean hasPermission(CommandIssuer issuer)
    +
    public boolean hasPermission(CommandIssuer issuer)
    +
  • + + + + + + + + + @@ -559,7 +585,7 @@ public void 
  • getName

    -
    public String getName()
    +
    public String getName()
  • @@ -568,7 +594,7 @@ public void 
  • getExceptionHandler

    -
    public ExceptionHandler getExceptionHandler()
    +
    public ExceptionHandler getExceptionHandler()
  • @@ -577,7 +603,7 @@ public void 
  • setExceptionHandler

    -
    public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler)
    +
    public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler)
  • @@ -586,7 +612,7 @@ public void 
  • getDefaultRegisteredCommand

    -
    public RegisteredCommand getDefaultRegisteredCommand()
    +
    public RegisteredCommand getDefaultRegisteredCommand()
  • diff --git a/docs/acf-core/co/aikar/commands/ForwardingCommand.html b/docs/acf-core/co/aikar/commands/ForwardingCommand.html index 88c701c1..5b0390be 100644 --- a/docs/acf-core/co/aikar/commands/ForwardingCommand.html +++ b/docs/acf-core/co/aikar/commands/ForwardingCommand.html @@ -171,7 +171,7 @@ extends BaseCommand -canExecute, doHelp, doHelp, getCommandHelp, getCurrentCommandIssuer, getCurrentCommandManager, getDefaultRegisteredCommand, getExceptionHandler, getExecCommandLabel, getExecSubcommand, getName, getOrigArgs, hasPermission, help, help, setExceptionHandler, showCommandHelp, showSyntax
  • +canExecute, doHelp, doHelp, getCommandHelp, getCurrentCommandIssuer, getCurrentCommandManager, getDefaultRegisteredCommand, getExceptionHandler, getExecCommandLabel, getExecSubcommand, getName, getOrigArgs, getRequiredPermissions, hasPermission, help, help, requiresPermission, setExceptionHandler, showCommandHelp, showSyntax
  • See Also:
    -
    getPermissions()
    +
    getRequiredPermissions()
    - + diff --git a/docs/acf-core/index-all.html b/docs/acf-core/index-all.html index 7b646f96..aa4a4eae 100644 --- a/docs/acf-core/index-all.html +++ b/docs/acf-core/index-all.html @@ -580,12 +580,14 @@
    Deprecated. 
    -
    getPermissions() - Method in class co.aikar.commands.RegisteredCommand
    -
     
    getPrefSubCommand() - Method in class co.aikar.commands.RegisteredCommand
     
    getRegisteredCommand() - Method in class co.aikar.commands.CommandOperationContext
     
    +
    getRequiredPermissions() - Method in class co.aikar.commands.BaseCommand
    +
     
    +
    getRequiredPermissions() - Method in class co.aikar.commands.RegisteredCommand
    +
     
    getResolvedArg(String) - Method in class co.aikar.commands.CommandExecutionContext
     
    getResolvedArg(Class<?>...) - Method in class co.aikar.commands.CommandExecutionContext
    @@ -1215,6 +1217,8 @@
     
    replaceStrings(String, String...) - Static method in class co.aikar.commands.ACFUtil
     
    +
    requiresPermission(String) - Method in class co.aikar.commands.BaseCommand
    +
     
    requiresPermission(String) - Method in class co.aikar.commands.RegisteredCommand
     
    ROMANIAN - Static variable in class co.aikar.commands.Locales
    diff --git a/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html b/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html index 7288a876..98623342 100644 --- a/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html +++ b/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html @@ -33,595 +33,603 @@ 025 026import co.aikar.commands.annotation.*; 027import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil; -028import com.google.common.collect.HashMultimap; -029import com.google.common.collect.ImmutableList; -030import com.google.common.collect.Iterables; -031import com.google.common.collect.Lists; -032import com.google.common.collect.SetMultimap; -033 -034import java.lang.reflect.Constructor; -035import java.lang.reflect.InvocationTargetException; -036import java.lang.reflect.Method; -037import java.lang.reflect.Parameter; -038import java.util.*; -039import java.util.Optional; -040import java.util.stream.Collectors; -041import java.util.stream.Stream; -042 -043@SuppressWarnings("unused") -044public abstract class BaseCommand { -045 -046 public static final String UNKNOWN = "__unknown"; -047 public static final String DEFAULT = "__default"; -048 final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create(); -049 private Method preCommandHandler; -050 +028import com.google.common.collect.*; +029 +030import java.lang.reflect.Constructor; +031import java.lang.reflect.InvocationTargetException; +032import java.lang.reflect.Method; +033import java.lang.reflect.Parameter; +034import java.util.*; +035import java.util.Optional; +036import java.util.stream.Collectors; +037import java.util.stream.Stream; +038 +039@SuppressWarnings("unused") +040public abstract class BaseCommand { +041 +042 public static final String UNKNOWN = "__unknown"; +043 public static final String DEFAULT = "__default"; +044 final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create(); +045 private Method preCommandHandler; +046 +047 @SuppressWarnings("WeakerAccess") +048 private String execLabel; +049 @SuppressWarnings("WeakerAccess") +050 private String execSubcommand; 051 @SuppressWarnings("WeakerAccess") -052 private String execLabel; -053 @SuppressWarnings("WeakerAccess") -054 private String execSubcommand; -055 @SuppressWarnings("WeakerAccess") -056 private String[] origArgs; -057 CommandManager<?, ?, ?> manager = null; -058 BaseCommand parentCommand; -059 Map<String, RootCommand> registeredCommands = new HashMap<>(); -060 String description; -061 String commandName; -062 String usageMessage; -063 String permission; -064 -065 private ExceptionHandler exceptionHandler = null; -066 CommandOperationContext lastCommandOperationContext; -067 -068 public BaseCommand() {} -069 public BaseCommand(String cmd) { -070 this.commandName = cmd; -071 } -072 -073 /** -074 * Gets the root command name that the user actually typed -075 * @return Name -076 */ -077 public String getExecCommandLabel() { -078 return execLabel; -079 } -080 -081 /** -082 * Gets the actual sub command name the user typed -083 * @return Name -084 */ -085 public String getExecSubcommand() { -086 return execSubcommand; -087 } -088 -089 /** -090 * Gets the actual args in string form the user typed -091 * @return Args -092 */ -093 public String[] getOrigArgs() { -094 return origArgs; +052 private String[] origArgs; +053 CommandManager<?, ?, ?> manager = null; +054 BaseCommand parentCommand; +055 Map<String, RootCommand> registeredCommands = new HashMap<>(); +056 String description; +057 String commandName; +058 String usageMessage; +059 String permission; +060 +061 private ExceptionHandler exceptionHandler = null; +062 CommandOperationContext lastCommandOperationContext; +063 +064 public BaseCommand() {} +065 public BaseCommand(String cmd) { +066 this.commandName = cmd; +067 } +068 +069 /** +070 * Gets the root command name that the user actually typed +071 * @return Name +072 */ +073 public String getExecCommandLabel() { +074 return execLabel; +075 } +076 +077 /** +078 * Gets the actual sub command name the user typed +079 * @return Name +080 */ +081 public String getExecSubcommand() { +082 return execSubcommand; +083 } +084 +085 /** +086 * Gets the actual args in string form the user typed +087 * @return Args +088 */ +089 public String[] getOrigArgs() { +090 return origArgs; +091 } +092 +093 void setParentCommand(BaseCommand command) { +094 this.parentCommand = command; 095 } -096 -097 void setParentCommand(BaseCommand command) { -098 this.parentCommand = command; -099 } -100 void onRegister(CommandManager manager) { -101 onRegister(manager, this.commandName); -102 } -103 void onRegister(CommandManager manager, String cmd) { -104 this.manager = manager; -105 final Class<? extends BaseCommand> self = this.getClass(); -106 CommandAlias rootCmdAliasAnno = self.getAnnotation(CommandAlias.class); -107 String rootCmdAlias = rootCmdAliasAnno != null ? manager.getCommandReplacements().replace(rootCmdAliasAnno.value()).toLowerCase() : null; -108 if (cmd == null && rootCmdAlias != null) { -109 cmd = ACFPatterns.PIPE.split(rootCmdAlias)[0]; -110 } -111 this.commandName = cmd != null ? cmd : self.getSimpleName().toLowerCase(); -112 -113 this.description = this.commandName + " commands"; -114 this.usageMessage = "/" + this.commandName; -115 -116 final CommandPermission perm = self.getAnnotation(CommandPermission.class); -117 if (perm != null) { -118 this.permission = manager.getCommandReplacements().replace(perm.value()); -119 } -120 -121 boolean foundDefault = false; -122 boolean foundUnknown = false; -123 for (Method method : self.getMethods()) { -124 method.setAccessible(true); -125 String sublist = null; -126 String sub = getSubcommandValue(method); -127 final Default def = method.getAnnotation(Default.class); -128 final HelpCommand helpCommand = method.getAnnotation(HelpCommand.class); -129 -130 final CommandAlias commandAliases = method.getAnnotation(CommandAlias.class); -131 -132 if (def != null || (!foundDefault && helpCommand != null)) { -133 if (!foundDefault) { -134 registerSubcommand(method, DEFAULT); -135 if (def != null) { -136 foundDefault = true; -137 } -138 } else { -139 ACFUtil.sneaky(new IllegalStateException("Multiple @Default/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); -140 } -141 } -142 -143 if (sub != null) { -144 sublist = sub; -145 } else if (commandAliases != null) { -146 sublist = commandAliases.value(); -147 } else if (helpCommand != null) { -148 sublist = helpCommand.value(); -149 } -150 -151 UnknownHandler unknown = method.getAnnotation(UnknownHandler.class); -152 PreCommand preCommand = method.getAnnotation(PreCommand.class); -153 if (unknown != null || (!foundUnknown && helpCommand != null)) { -154 if (!foundUnknown) { -155 registerSubcommand(method, UNKNOWN); -156 if (unknown != null) { -157 foundUnknown = true; -158 } -159 } else { -160 ACFUtil.sneaky(new IllegalStateException("Multiple @UnknownHandler/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); -161 } -162 } else if (preCommand != null) { -163 if (this.preCommandHandler == null) { -164 this.preCommandHandler = method; -165 } else { -166 ACFUtil.sneaky(new IllegalStateException("Multiple @PreCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); -167 } -168 } -169 if (Objects.equals(method.getDeclaringClass(), this.getClass()) && sublist != null) { -170 registerSubcommand(method, sublist); -171 } -172 } -173 -174 if (rootCmdAlias != null) { -175 Set<String> cmdList = new HashSet<>(); -176 Collections.addAll(cmdList, ACFPatterns.PIPE.split(rootCmdAlias)); -177 cmdList.remove(cmd); -178 for (String cmdAlias : cmdList) { -179 register(cmdAlias, this); -180 } +096 void onRegister(CommandManager manager) { +097 onRegister(manager, this.commandName); +098 } +099 void onRegister(CommandManager manager, String cmd) { +100 this.manager = manager; +101 final Class<? extends BaseCommand> self = this.getClass(); +102 CommandAlias rootCmdAliasAnno = self.getAnnotation(CommandAlias.class); +103 String rootCmdAlias = rootCmdAliasAnno != null ? manager.getCommandReplacements().replace(rootCmdAliasAnno.value()).toLowerCase() : null; +104 if (cmd == null && rootCmdAlias != null) { +105 cmd = ACFPatterns.PIPE.split(rootCmdAlias)[0]; +106 } +107 this.commandName = cmd != null ? cmd : self.getSimpleName().toLowerCase(); +108 +109 this.description = this.commandName + " commands"; +110 this.usageMessage = "/" + this.commandName; +111 +112 final CommandPermission perm = self.getAnnotation(CommandPermission.class); +113 if (perm != null) { +114 this.permission = manager.getCommandReplacements().replace(perm.value()); +115 } +116 +117 boolean foundDefault = false; +118 boolean foundUnknown = false; +119 for (Method method : self.getMethods()) { +120 method.setAccessible(true); +121 String sublist = null; +122 String sub = getSubcommandValue(method); +123 final Default def = method.getAnnotation(Default.class); +124 final HelpCommand helpCommand = method.getAnnotation(HelpCommand.class); +125 +126 final CommandAlias commandAliases = method.getAnnotation(CommandAlias.class); +127 +128 if (def != null || (!foundDefault && helpCommand != null)) { +129 if (!foundDefault) { +130 registerSubcommand(method, DEFAULT); +131 if (def != null) { +132 foundDefault = true; +133 } +134 } else { +135 ACFUtil.sneaky(new IllegalStateException("Multiple @Default/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); +136 } +137 } +138 +139 if (sub != null) { +140 sublist = sub; +141 } else if (commandAliases != null) { +142 sublist = commandAliases.value(); +143 } else if (helpCommand != null) { +144 sublist = helpCommand.value(); +145 } +146 +147 UnknownHandler unknown = method.getAnnotation(UnknownHandler.class); +148 PreCommand preCommand = method.getAnnotation(PreCommand.class); +149 if (unknown != null || (!foundUnknown && helpCommand != null)) { +150 if (!foundUnknown) { +151 registerSubcommand(method, UNKNOWN); +152 if (unknown != null) { +153 foundUnknown = true; +154 } +155 } else { +156 ACFUtil.sneaky(new IllegalStateException("Multiple @UnknownHandler/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); +157 } +158 } else if (preCommand != null) { +159 if (this.preCommandHandler == null) { +160 this.preCommandHandler = method; +161 } else { +162 ACFUtil.sneaky(new IllegalStateException("Multiple @PreCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); +163 } +164 } +165 if (Objects.equals(method.getDeclaringClass(), this.getClass()) && sublist != null) { +166 registerSubcommand(method, sublist); +167 } +168 } +169 +170 if (rootCmdAlias != null) { +171 Set<String> cmdList = new HashSet<>(); +172 Collections.addAll(cmdList, ACFPatterns.PIPE.split(rootCmdAlias)); +173 cmdList.remove(cmd); +174 for (String cmdAlias : cmdList) { +175 register(cmdAlias, this); +176 } +177 } +178 +179 if (cmd != null) { +180 register(cmd, this); 181 } -182 -183 if (cmd != null) { -184 register(cmd, this); -185 } -186 for (Class<?> clazz : this.getClass().getDeclaredClasses()) { -187 if (BaseCommand.class.isAssignableFrom(clazz)) { -188 try { -189 BaseCommand subCommand = null; -190 Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); -191 for (Constructor<?> declaredConstructor : declaredConstructors) { -192 -193 declaredConstructor.setAccessible(true); -194 Parameter[] parameters = declaredConstructor.getParameters(); -195 if (parameters.length == 1) { -196 subCommand = (BaseCommand) declaredConstructor.newInstance(this); -197 } else { -198 manager.log(LogLevel.INFO, "Found unusable constructor: " + declaredConstructor.getName() + "(" + Stream.of(parameters).map(p -> p.getType().getSimpleName() + " " + p.getName()).collect(Collectors.joining("<c2>,</c2> ")) + ")"); -199 } -200 } -201 if (subCommand != null) { -202 subCommand.setParentCommand(this); -203 subCommand.onRegister(manager, cmd); -204 this.subCommands.putAll(subCommand.subCommands); -205 this.registeredCommands.putAll(subCommand.registeredCommands); -206 } else { -207 this.manager.log(LogLevel.ERROR, "Could not find a subcommand ctor for " + clazz.getName()); -208 } -209 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { -210 e.printStackTrace(); -211 } -212 } -213 } -214 -215 } -216 -217 private String getSubcommandValue(Method method) { -218 final Subcommand sub = method.getAnnotation(Subcommand.class); -219 if (sub == null) { -220 return null; -221 } -222 List<String> subList = new ArrayList<>(); -223 subList.add(sub.value()); -224 Class<?> clazz = method.getDeclaringClass(); -225 while (clazz != null) { -226 Subcommand classSub = clazz.getAnnotation(Subcommand.class); -227 if (classSub != null) { -228 subList.add(classSub.value()); -229 } -230 clazz = clazz.getEnclosingClass(); -231 } -232 Collections.reverse(subList); -233 return ACFUtil.join(subList, " "); -234 } -235 -236 private void register(String name, BaseCommand cmd) { -237 String nameLower = name.toLowerCase(); -238 RootCommand rootCommand = manager.obtainRootCommand(nameLower); -239 rootCommand.addChild(cmd); -240 -241 this.registeredCommands.put(nameLower, rootCommand); -242 } -243 -244 private void registerSubcommand(Method method, String subCommand) { -245 subCommand = manager.getCommandReplacements().replace(subCommand.toLowerCase()); -246 final String[] subCommandParts = ACFPatterns.SPACE.split(subCommand); -247 // Must run getSubcommandPossibility BEFORE we rewrite it just after this. -248 Set<String> cmdList = getSubCommandPossibilityList(subCommandParts); -249 -250 // Strip pipes off for auto complete addition -251 for (int i = 0; i < subCommandParts.length; i++) { -252 subCommandParts[i] = ACFPatterns.PIPE.split(subCommandParts[i])[0]; -253 } -254 String prefSubCommand = ApacheCommonsLangUtil.join(subCommandParts, " "); -255 final CommandAlias cmdAlias = method.getAnnotation(CommandAlias.class); +182 for (Class<?> clazz : this.getClass().getDeclaredClasses()) { +183 if (BaseCommand.class.isAssignableFrom(clazz)) { +184 try { +185 BaseCommand subCommand = null; +186 Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); +187 for (Constructor<?> declaredConstructor : declaredConstructors) { +188 +189 declaredConstructor.setAccessible(true); +190 Parameter[] parameters = declaredConstructor.getParameters(); +191 if (parameters.length == 1) { +192 subCommand = (BaseCommand) declaredConstructor.newInstance(this); +193 } else { +194 manager.log(LogLevel.INFO, "Found unusable constructor: " + declaredConstructor.getName() + "(" + Stream.of(parameters).map(p -> p.getType().getSimpleName() + " " + p.getName()).collect(Collectors.joining("<c2>,</c2> ")) + ")"); +195 } +196 } +197 if (subCommand != null) { +198 subCommand.setParentCommand(this); +199 subCommand.onRegister(manager, cmd); +200 this.subCommands.putAll(subCommand.subCommands); +201 this.registeredCommands.putAll(subCommand.registeredCommands); +202 } else { +203 this.manager.log(LogLevel.ERROR, "Could not find a subcommand ctor for " + clazz.getName()); +204 } +205 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { +206 e.printStackTrace(); +207 } +208 } +209 } +210 +211 } +212 +213 private String getSubcommandValue(Method method) { +214 final Subcommand sub = method.getAnnotation(Subcommand.class); +215 if (sub == null) { +216 return null; +217 } +218 List<String> subList = new ArrayList<>(); +219 subList.add(sub.value()); +220 Class<?> clazz = method.getDeclaringClass(); +221 while (clazz != null) { +222 Subcommand classSub = clazz.getAnnotation(Subcommand.class); +223 if (classSub != null) { +224 subList.add(classSub.value()); +225 } +226 clazz = clazz.getEnclosingClass(); +227 } +228 Collections.reverse(subList); +229 return ACFUtil.join(subList, " "); +230 } +231 +232 private void register(String name, BaseCommand cmd) { +233 String nameLower = name.toLowerCase(); +234 RootCommand rootCommand = manager.obtainRootCommand(nameLower); +235 rootCommand.addChild(cmd); +236 +237 this.registeredCommands.put(nameLower, rootCommand); +238 } +239 +240 private void registerSubcommand(Method method, String subCommand) { +241 subCommand = manager.getCommandReplacements().replace(subCommand.toLowerCase()); +242 final String[] subCommandParts = ACFPatterns.SPACE.split(subCommand); +243 // Must run getSubcommandPossibility BEFORE we rewrite it just after this. +244 Set<String> cmdList = getSubCommandPossibilityList(subCommandParts); +245 +246 // Strip pipes off for auto complete addition +247 for (int i = 0; i < subCommandParts.length; i++) { +248 subCommandParts[i] = ACFPatterns.PIPE.split(subCommandParts[i])[0]; +249 } +250 String prefSubCommand = ApacheCommonsLangUtil.join(subCommandParts, " "); +251 final CommandAlias cmdAlias = method.getAnnotation(CommandAlias.class); +252 +253 final String[] aliasNames = cmdAlias != null ? ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(cmdAlias.value().toLowerCase())) : null; +254 String cmdName = aliasNames != null ? aliasNames[0] : this.commandName + " "; +255 RegisteredCommand cmd = manager.createRegisteredCommand(this, cmdName, method, prefSubCommand); 256 -257 final String[] aliasNames = cmdAlias != null ? ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(cmdAlias.value().toLowerCase())) : null; -258 String cmdName = aliasNames != null ? aliasNames[0] : this.commandName + " "; -259 RegisteredCommand cmd = manager.createRegisteredCommand(this, cmdName, method, prefSubCommand); -260 -261 for (String subcmd : cmdList) { -262 subCommands.put(subcmd, cmd); -263 } -264 cmd.addSubcommands(cmdList); -265 -266 if (aliasNames != null) { -267 for (String name : aliasNames) { -268 register(name, new ForwardingCommand(this, subCommandParts)); -269 } -270 } -271 } -272 -273 /** -274 * Takes a string like "foo|bar baz|qux" and generates a list of -275 * - foo baz -276 * - foo qux -277 * - bar baz -278 * - bar qux -279 * -280 * For every possible sub command combination -281 * -282 * @param subCommandParts -283 * @return List of all sub command possibilities -284 */ -285 private static Set<String> getSubCommandPossibilityList(String[] subCommandParts) { -286 int i = 0; -287 Set<String> current = null; -288 while (true) { -289 Set<String> newList = new HashSet<>(); -290 -291 if (i < subCommandParts.length) { -292 for (String s1 : ACFPatterns.PIPE.split(subCommandParts[i])) { -293 if (current != null) { -294 newList.addAll(current.stream().map(s -> s + " " + s1).collect(Collectors.toList())); -295 } else { -296 newList.add(s1); -297 } -298 } -299 } -300 -301 if (i + 1 < subCommandParts.length) { -302 current = newList; -303 i = i + 1; -304 continue; -305 } +257 for (String subcmd : cmdList) { +258 subCommands.put(subcmd, cmd); +259 } +260 cmd.addSubcommands(cmdList); +261 +262 if (aliasNames != null) { +263 for (String name : aliasNames) { +264 register(name, new ForwardingCommand(this, subCommandParts)); +265 } +266 } +267 } +268 +269 /** +270 * Takes a string like "foo|bar baz|qux" and generates a list of +271 * - foo baz +272 * - foo qux +273 * - bar baz +274 * - bar qux +275 * +276 * For every possible sub command combination +277 * +278 * @param subCommandParts +279 * @return List of all sub command possibilities +280 */ +281 private static Set<String> getSubCommandPossibilityList(String[] subCommandParts) { +282 int i = 0; +283 Set<String> current = null; +284 while (true) { +285 Set<String> newList = new HashSet<>(); +286 +287 if (i < subCommandParts.length) { +288 for (String s1 : ACFPatterns.PIPE.split(subCommandParts[i])) { +289 if (current != null) { +290 newList.addAll(current.stream().map(s -> s + " " + s1).collect(Collectors.toList())); +291 } else { +292 newList.add(s1); +293 } +294 } +295 } +296 +297 if (i + 1 < subCommandParts.length) { +298 current = newList; +299 i = i + 1; +300 continue; +301 } +302 +303 return newList; +304 } +305 } 306 -307 return newList; -308 } -309 } -310 -311 public void execute(CommandIssuer issuer, String commandLabel, String[] args) { -312 commandLabel = commandLabel.toLowerCase(); -313 try { -314 CommandOperationContext commandContext = preCommandOperation(issuer, commandLabel, args); -315 -316 if (args.length > 0) { -317 CommandSearch cmd = findSubCommand(args); -318 if (cmd != null) { -319 execSubcommand = cmd.getCheckSub(); -320 final String[] execargs = Arrays.copyOfRange(args, cmd.argIndex, args.length); -321 executeCommand(commandContext, issuer, execargs, cmd.cmd); -322 return; -323 } -324 } -325 -326 -327 if (subCommands.get(DEFAULT) != null && args.length == 0) { -328 executeSubcommand(commandContext, DEFAULT, issuer, args); -329 } else if (subCommands.get(UNKNOWN) != null) { -330 if (!executeSubcommand(commandContext, UNKNOWN, issuer, args)) { -331 help(issuer, args); -332 } -333 } else if (subCommands.get(DEFAULT) != null) { -334 executeSubcommand(commandContext, DEFAULT, issuer, args); -335 } -336 -337 } finally { -338 postCommandOperation(); -339 } -340 } -341 -342 private void postCommandOperation() { -343 CommandManager.commandOperationContext.get().pop(); -344 execSubcommand = null; -345 execLabel = null; -346 origArgs = new String[]{}; -347 } -348 -349 private CommandOperationContext preCommandOperation(CommandIssuer issuer, String commandLabel, String[] args) { -350 Stack<CommandOperationContext> contexts = CommandManager.commandOperationContext.get(); -351 CommandOperationContext context = this.manager.createCommandOperationContext(this, issuer, commandLabel, args); -352 contexts.push(context); -353 lastCommandOperationContext = context; -354 execSubcommand = null; -355 execLabel = commandLabel; -356 origArgs = args; -357 return context; +307 public void execute(CommandIssuer issuer, String commandLabel, String[] args) { +308 commandLabel = commandLabel.toLowerCase(); +309 try { +310 CommandOperationContext commandContext = preCommandOperation(issuer, commandLabel, args); +311 +312 if (args.length > 0) { +313 CommandSearch cmd = findSubCommand(args); +314 if (cmd != null) { +315 execSubcommand = cmd.getCheckSub(); +316 final String[] execargs = Arrays.copyOfRange(args, cmd.argIndex, args.length); +317 executeCommand(commandContext, issuer, execargs, cmd.cmd); +318 return; +319 } +320 } +321 +322 +323 if (subCommands.get(DEFAULT) != null && args.length == 0) { +324 executeSubcommand(commandContext, DEFAULT, issuer, args); +325 } else if (subCommands.get(UNKNOWN) != null) { +326 if (!executeSubcommand(commandContext, UNKNOWN, issuer, args)) { +327 help(issuer, args); +328 } +329 } else if (subCommands.get(DEFAULT) != null) { +330 executeSubcommand(commandContext, DEFAULT, issuer, args); +331 } +332 +333 } finally { +334 postCommandOperation(); +335 } +336 } +337 +338 private void postCommandOperation() { +339 CommandManager.commandOperationContext.get().pop(); +340 execSubcommand = null; +341 execLabel = null; +342 origArgs = new String[]{}; +343 } +344 +345 private CommandOperationContext preCommandOperation(CommandIssuer issuer, String commandLabel, String[] args) { +346 Stack<CommandOperationContext> contexts = CommandManager.commandOperationContext.get(); +347 CommandOperationContext context = this.manager.createCommandOperationContext(this, issuer, commandLabel, args); +348 contexts.push(context); +349 lastCommandOperationContext = context; +350 execSubcommand = null; +351 execLabel = commandLabel; +352 origArgs = args; +353 return context; +354 } +355 +356 public CommandIssuer getCurrentCommandIssuer() { +357 return CommandManager.getCurrentCommandIssuer(); 358 } -359 -360 public CommandIssuer getCurrentCommandIssuer() { -361 return CommandManager.getCurrentCommandIssuer(); -362 } -363 public CommandManager getCurrentCommandManager() { -364 return CommandManager.getCurrentCommandManager(); +359 public CommandManager getCurrentCommandManager() { +360 return CommandManager.getCurrentCommandManager(); +361 } +362 +363 private CommandSearch findSubCommand(String[] args) { +364 return findSubCommand(args, false); 365 } -366 -367 private CommandSearch findSubCommand(String[] args) { -368 return findSubCommand(args, false); -369 } -370 private CommandSearch findSubCommand(String[] args, boolean completion) { -371 for (int i = args.length; i >= 0; i--) { -372 String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase(); -373 Set<RegisteredCommand> cmds = subCommands.get(checkSub); -374 -375 final int extraArgs = args.length - i; -376 if (!cmds.isEmpty()) { -377 RegisteredCommand cmd = null; -378 if (cmds.size() == 1) { -379 cmd = Iterables.getOnlyElement(cmds); -380 } else { -381 Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> { -382 int required = c.requiredResolvers; -383 int optional = c.optionalResolvers; -384 return extraArgs <= required + optional && (completion || extraArgs >= required); -385 }).sorted((c1, c2) -> { -386 int a = c1.requiredResolvers + c1.optionalResolvers; -387 int b = c2.requiredResolvers + c2.optionalResolvers; -388 -389 if (a == b) { -390 return 0; -391 } -392 return a < b ? 1 : -1; -393 }).findFirst(); -394 if (optCmd.isPresent()) { -395 cmd = optCmd.get(); -396 } -397 } -398 if (cmd != null) { -399 return new CommandSearch(cmd, i, checkSub); -400 } -401 } -402 } -403 return null; -404 } -405 -406 private void executeCommand(CommandOperationContext commandOperationContext, -407 CommandIssuer issuer, String[] args, RegisteredCommand cmd) { -408 if (cmd.hasPermission(issuer)) { -409 commandOperationContext.setRegisteredCommand(cmd); -410 if (checkPrecommand(commandOperationContext, cmd, issuer, args)) { -411 return; -412 } -413 List<String> sargs = Lists.newArrayList(args); -414 cmd.invoke(issuer, sargs); -415 } else { -416 issuer.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED); -417 } +366 private CommandSearch findSubCommand(String[] args, boolean completion) { +367 for (int i = args.length; i >= 0; i--) { +368 String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase(); +369 Set<RegisteredCommand> cmds = subCommands.get(checkSub); +370 +371 final int extraArgs = args.length - i; +372 if (!cmds.isEmpty()) { +373 RegisteredCommand cmd = null; +374 if (cmds.size() == 1) { +375 cmd = Iterables.getOnlyElement(cmds); +376 } else { +377 Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> { +378 int required = c.requiredResolvers; +379 int optional = c.optionalResolvers; +380 return extraArgs <= required + optional && (completion || extraArgs >= required); +381 }).sorted((c1, c2) -> { +382 int a = c1.requiredResolvers + c1.optionalResolvers; +383 int b = c2.requiredResolvers + c2.optionalResolvers; +384 +385 if (a == b) { +386 return 0; +387 } +388 return a < b ? 1 : -1; +389 }).findFirst(); +390 if (optCmd.isPresent()) { +391 cmd = optCmd.get(); +392 } +393 } +394 if (cmd != null) { +395 return new CommandSearch(cmd, i, checkSub); +396 } +397 } +398 } +399 return null; +400 } +401 +402 private void executeCommand(CommandOperationContext commandOperationContext, +403 CommandIssuer issuer, String[] args, RegisteredCommand cmd) { +404 if (cmd.hasPermission(issuer)) { +405 commandOperationContext.setRegisteredCommand(cmd); +406 if (checkPrecommand(commandOperationContext, cmd, issuer, args)) { +407 return; +408 } +409 List<String> sargs = Lists.newArrayList(args); +410 cmd.invoke(issuer, sargs); +411 } else { +412 issuer.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED); +413 } +414 } +415 +416 public boolean canExecute(CommandIssuer issuer, RegisteredCommand<?> cmd) { +417 return true; 418 } 419 -420 public boolean canExecute(CommandIssuer issuer, RegisteredCommand<?> cmd) { -421 return true; -422 } -423 -424 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args) -425 throws IllegalArgumentException { +420 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args) +421 throws IllegalArgumentException { +422 +423 commandLabel = commandLabel.toLowerCase(); +424 try { +425 CommandOperationContext commandOperationContext = preCommandOperation(issuer, commandLabel, args); 426 -427 commandLabel = commandLabel.toLowerCase(); -428 try { -429 CommandOperationContext commandOperationContext = preCommandOperation(issuer, commandLabel, args); +427 final CommandSearch search = findSubCommand(args, true); +428 +429 String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); 430 -431 final CommandSearch search = findSubCommand(args, true); +431 final List<String> cmds = new ArrayList<>(); 432 -433 String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); -434 -435 final List<String> cmds = new ArrayList<>(); -436 -437 if (search != null) { -438 cmds.addAll(completeCommand(commandOperationContext, issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel)); -439 } else if (subCommands.get(UNKNOWN).size() == 1) { -440 cmds.addAll(completeCommand(commandOperationContext, issuer, Iterables.getOnlyElement(subCommands.get(UNKNOWN)), args, commandLabel)); -441 } -442 -443 for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) { -444 final String key = entry.getKey(); -445 if (key.startsWith(argString) && !UNKNOWN.equals(key) && !DEFAULT.equals(key)) { -446 final RegisteredCommand value = entry.getValue(); -447 if (!value.hasPermission(issuer)) { -448 continue; -449 } -450 String prefCommand = value.prefSubCommand; -451 -452 final String[] psplit = ACFPatterns.SPACE.split(prefCommand); -453 cmds.add(psplit[args.length - 1]); -454 } -455 } -456 -457 return filterTabComplete(args[args.length - 1], cmds); -458 } finally { -459 postCommandOperation(); -460 } -461 } -462 -463 private List<String> completeCommand(CommandOperationContext commandOperationContext, CommandIssuer issuer, RegisteredCommand cmd, String[] args, String commandLabel) { -464 if (!cmd.hasPermission(issuer) || args.length > cmd.requiredResolvers + cmd.optionalResolvers || args.length == 0 -465 || cmd.complete == null) { -466 return ImmutableList.of(); -467 } -468 -469 String[] completions = ACFPatterns.SPACE.split(cmd.complete); +433 if (search != null) { +434 cmds.addAll(completeCommand(commandOperationContext, issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel)); +435 } else if (subCommands.get(UNKNOWN).size() == 1) { +436 cmds.addAll(completeCommand(commandOperationContext, issuer, Iterables.getOnlyElement(subCommands.get(UNKNOWN)), args, commandLabel)); +437 } +438 +439 for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) { +440 final String key = entry.getKey(); +441 if (key.startsWith(argString) && !UNKNOWN.equals(key) && !DEFAULT.equals(key)) { +442 final RegisteredCommand value = entry.getValue(); +443 if (!value.hasPermission(issuer)) { +444 continue; +445 } +446 String prefCommand = value.prefSubCommand; +447 +448 final String[] psplit = ACFPatterns.SPACE.split(prefCommand); +449 cmds.add(psplit[args.length - 1]); +450 } +451 } +452 +453 return filterTabComplete(args[args.length - 1], cmds); +454 } finally { +455 postCommandOperation(); +456 } +457 } +458 +459 private List<String> completeCommand(CommandOperationContext commandOperationContext, CommandIssuer issuer, RegisteredCommand cmd, String[] args, String commandLabel) { +460 if (!cmd.hasPermission(issuer) || args.length > cmd.requiredResolvers + cmd.optionalResolvers || args.length == 0 +461 || cmd.complete == null) { +462 return ImmutableList.of(); +463 } +464 +465 String[] completions = ACFPatterns.SPACE.split(cmd.complete); +466 +467 List<String> cmds = manager.getCommandCompletions().of(commandOperationContext, cmd, issuer, completions, args); +468 return filterTabComplete(args[args.length-1], cmds); +469 } 470 -471 List<String> cmds = manager.getCommandCompletions().of(commandOperationContext, cmd, issuer, completions, args); -472 return filterTabComplete(args[args.length-1], cmds); -473 } -474 -475 private static List<String> filterTabComplete(String arg, List<String> cmds) { -476 return cmds.stream() -477 .distinct() -478 .filter(cmd -> cmd != null && (arg.isEmpty() || ApacheCommonsLangUtil.startsWithIgnoreCase(cmd, arg))) -479 .collect(Collectors.toList()); +471 private static List<String> filterTabComplete(String arg, List<String> cmds) { +472 return cmds.stream() +473 .distinct() +474 .filter(cmd -> cmd != null && (arg.isEmpty() || ApacheCommonsLangUtil.startsWithIgnoreCase(cmd, arg))) +475 .collect(Collectors.toList()); +476 } +477 +478 RegisteredCommand getSubcommand(String subcommand) { +479 return getSubcommand(subcommand, false); 480 } 481 -482 RegisteredCommand getSubcommand(String subcommand) { -483 return getSubcommand(subcommand, false); -484 } -485 -486 RegisteredCommand getSubcommand(String subcommand, boolean requireOne) { -487 final Set<RegisteredCommand> commands = subCommands.get(subcommand); -488 if (!commands.isEmpty() && (!requireOne || commands.size() == 1)) { -489 return commands.iterator().next(); -490 } -491 return null; -492 } -493 -494 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { -495 final RegisteredCommand cmd = this.getSubcommand(subcommand); -496 if (cmd != null) { -497 executeCommand(commandContext, issuer, args, cmd); -498 return true; -499 } -500 -501 return false; -502 } -503 -504 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { -505 Method pre = this.preCommandHandler; -506 if (pre != null) { -507 try { -508 Class<?>[] types = pre.getParameterTypes(); -509 Object[] parameters = new Object[pre.getParameterCount()]; -510 for (int i = 0; i < parameters.length; i++) { -511 Class<?> type = types[i]; -512 Object issuerObject = issuer.getIssuer(); -513 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { -514 parameters[i] = issuerObject; -515 } else if (CommandIssuer.class.isAssignableFrom(type)) { -516 parameters[i] = issuer; -517 } else if (RegisteredCommand.class.isAssignableFrom(type)) { -518 parameters[i] = cmd; -519 } else if (String[].class.isAssignableFrom((type))) { -520 parameters[i] = args; -521 } else { -522 parameters[i] = null; -523 } -524 } -525 -526 return (boolean) pre.invoke(this, parameters); -527 } catch (IllegalAccessException | InvocationTargetException e) { -528 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); -529 } -530 } -531 return false; -532 } -533 -534 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -535 public CommandHelp getCommandHelp() { -536 return manager.generateCommandHelp(); -537 } -538 -539 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -540 public void showCommandHelp() { -541 getCommandHelp().showHelp(); +482 RegisteredCommand getSubcommand(String subcommand, boolean requireOne) { +483 final Set<RegisteredCommand> commands = subCommands.get(subcommand); +484 if (!commands.isEmpty() && (!requireOne || commands.size() == 1)) { +485 return commands.iterator().next(); +486 } +487 return null; +488 } +489 +490 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { +491 final RegisteredCommand cmd = this.getSubcommand(subcommand); +492 if (cmd != null) { +493 executeCommand(commandContext, issuer, args, cmd); +494 return true; +495 } +496 +497 return false; +498 } +499 +500 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { +501 Method pre = this.preCommandHandler; +502 if (pre != null) { +503 try { +504 Class<?>[] types = pre.getParameterTypes(); +505 Object[] parameters = new Object[pre.getParameterCount()]; +506 for (int i = 0; i < parameters.length; i++) { +507 Class<?> type = types[i]; +508 Object issuerObject = issuer.getIssuer(); +509 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { +510 parameters[i] = issuerObject; +511 } else if (CommandIssuer.class.isAssignableFrom(type)) { +512 parameters[i] = issuer; +513 } else if (RegisteredCommand.class.isAssignableFrom(type)) { +514 parameters[i] = cmd; +515 } else if (String[].class.isAssignableFrom((type))) { +516 parameters[i] = args; +517 } else { +518 parameters[i] = null; +519 } +520 } +521 +522 return (boolean) pre.invoke(this, parameters); +523 } catch (IllegalAccessException | InvocationTargetException e) { +524 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); +525 } +526 } +527 return false; +528 } +529 +530 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +531 public CommandHelp getCommandHelp() { +532 return manager.generateCommandHelp(); +533 } +534 +535 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +536 public void showCommandHelp() { +537 getCommandHelp().showHelp(); +538 } +539 +540 public void help(Object issuer, String[] args) { +541 help(manager.getCommandIssuer(issuer), args); 542 } -543 -544 public void help(Object issuer, String[] args) { -545 help(manager.getCommandIssuer(issuer), args); -546 } -547 public void help(CommandIssuer issuer, String[] args) { -548 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); -549 } -550 public void doHelp(Object issuer, String... args) { -551 doHelp(manager.getCommandIssuer(issuer), args); -552 } -553 public void doHelp(CommandIssuer issuer, String... args) { -554 help(issuer, args); -555 } -556 -557 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { -558 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, -559 "{command}", "/" + cmd.command, -560 "{syntax}", cmd.syntaxText -561 ); +543 public void help(CommandIssuer issuer, String[] args) { +544 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); +545 } +546 public void doHelp(Object issuer, String... args) { +547 doHelp(manager.getCommandIssuer(issuer), args); +548 } +549 public void doHelp(CommandIssuer issuer, String... args) { +550 help(issuer, args); +551 } +552 +553 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { +554 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, +555 "{command}", "/" + cmd.command, +556 "{syntax}", cmd.syntaxText +557 ); +558 } +559 +560 public boolean hasPermission(Object issuer) { +561 return hasPermission(manager.getCommandIssuer(issuer)); 562 } 563 -564 public boolean hasPermission(Object issuer) { -565 return hasPermission(manager.getCommandIssuer(issuer)); +564 public boolean hasPermission(CommandIssuer issuer) { +565 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); 566 } 567 -568 public boolean hasPermission(CommandIssuer issuer) { -569 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); -570 } -571 -572 public String getName() { -573 return commandName; +568 +569 public Set<String> getRequiredPermissions() { +570 if (this.permission == null || this.permission.isEmpty()) { +571 return ImmutableSet.of(); +572 } +573 return Sets.newHashSet(ACFPatterns.COMMA.split(this.permission)); 574 } 575 -576 public ExceptionHandler getExceptionHandler() { -577 return exceptionHandler; +576 public boolean requiresPermission(String permission) { +577 return getRequiredPermissions().contains(permission) || this.parentCommand != null && parentCommand.requiresPermission(permission); 578 } 579 -580 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { -581 this.exceptionHandler = exceptionHandler; -582 return this; -583 } -584 -585 public RegisteredCommand getDefaultRegisteredCommand() { -586 return this.getSubcommand(DEFAULT); -587 } -588 -589 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; -590 -591 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { -592 this.cmd = cmd; -593 this.argIndex = argIndex; -594 this.checkSub = checkSub; -595 } +580 public String getName() { +581 return commandName; +582 } +583 +584 public ExceptionHandler getExceptionHandler() { +585 return exceptionHandler; +586 } +587 +588 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { +589 this.exceptionHandler = exceptionHandler; +590 return this; +591 } +592 +593 public RegisteredCommand getDefaultRegisteredCommand() { +594 return this.getSubcommand(DEFAULT); +595 } 596 -597 String getCheckSub() { -598 return this.checkSub; -599 } -600 -601 @Override -602 public boolean equals(Object o) { -603 if (this == o) return true; -604 if (o == null || getClass() != o.getClass()) return false; -605 CommandSearch that = (CommandSearch) o; -606 return argIndex == that.argIndex && -607 Objects.equals(cmd, that.cmd) && -608 Objects.equals(checkSub, that.checkSub); -609 } -610 -611 @Override -612 public int hashCode() { -613 return Objects.hash(cmd, argIndex, checkSub); -614 } -615 } -616} +597 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; +598 +599 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { +600 this.cmd = cmd; +601 this.argIndex = argIndex; +602 this.checkSub = checkSub; +603 } +604 +605 String getCheckSub() { +606 return this.checkSub; +607 } +608 +609 @Override +610 public boolean equals(Object o) { +611 if (this == o) return true; +612 if (o == null || getClass() != o.getClass()) return false; +613 CommandSearch that = (CommandSearch) o; +614 return argIndex == that.argIndex && +615 Objects.equals(cmd, that.cmd) && +616 Objects.equals(checkSub, that.checkSub); +617 } +618 +619 @Override +620 public int hashCode() { +621 return Objects.hash(cmd, argIndex, checkSub); +622 } +623 } +624} diff --git a/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html b/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html index 4842a9ae..357982e7 100644 --- a/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html +++ b/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html @@ -249,7 +249,7 @@ 241 242 243 /** -244 * @see #getPermissions() +244 * @see #getRequiredPermissions() 245 * @deprecated 246 */ 247 @Deprecated @@ -260,7 +260,7 @@ 252 return ACFPatterns.COMMA.split(this.permission)[0]; 253 } 254 -255 public Set<String> getPermissions() { +255 public Set<String> getRequiredPermissions() { 256 if (this.permission == null || this.permission.isEmpty()) { 257 return ImmutableSet.of(); 258 } @@ -268,7 +268,7 @@ 260 } 261 262 public boolean requiresPermission(String permission) { -263 return getPermissions().contains(permission); +263 return getRequiredPermissions().contains(permission) || scope.requiresPermission(permission); 264 } 265 266 public String getPrefSubCommand() { diff --git a/docs/acf-sponge/co/aikar/commands/SpongeRegisteredCommand.html b/docs/acf-sponge/co/aikar/commands/SpongeRegisteredCommand.html index 4ed20eda..8c5cf7af 100644 --- a/docs/acf-sponge/co/aikar/commands/SpongeRegisteredCommand.html +++ b/docs/acf-sponge/co/aikar/commands/SpongeRegisteredCommand.html @@ -148,7 +148,7 @@ extends co.aikar.commands.RegisteredCommand<