From 8f68acd3249c82889d5434ce3c7dfdb9c2afe6b2 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 17 Mar 2018 23:56:07 -0400 Subject: [PATCH] (DEPLOYED ACF) Updated JavaDocs --- .../BukkitCommandExecutionContext.html | 2 +- .../commands/BukkitRegisteredCommand.html | 19 +- .../co/aikar/commands/BukkitRootCommand.html | 54 +- docs/acf-bukkit/index-all.html | 4 - .../co/aikar/commands/BukkitRootCommand.html | 33 +- .../BungeeCommandExecutionContext.html | 2 +- .../commands/BungeeRegisteredCommand.html | 19 +- .../co/aikar/commands/BungeeRootCommand.html | 38 +- .../co/aikar/commands/BaseCommand.html | 62 +- .../commands/CommandConditions.Condition.html | 4 +- .../CommandConditions.ParameterCondition.html | 4 +- .../commands/CommandExecutionContext.html | 135 +- .../co/aikar/commands/CommandManager.html | 130 +- .../commands/CommandOperationContext.html | 63 +- .../co/aikar/commands/CommandParameter.html | 142 +- .../acf-core/co/aikar/commands/HelpEntry.html | 14 +- .../co/aikar/commands/RegisteredCommand.html | 66 +- docs/acf-core/deprecated-list.html | 23 +- docs/acf-core/index-all.html | 28 +- .../co/aikar/commands/BaseCommand.html | 1310 +++++++++-------- .../commands/CommandConditions.Condition.html | 172 ++- .../CommandConditions.ParameterCondition.html | 172 ++- .../co/aikar/commands/CommandConditions.html | 172 ++- .../co/aikar/commands/CommandContexts.html | 12 +- .../commands/CommandExecutionContext.html | 103 +- .../co/aikar/commands/CommandManager.html | 878 +++++------ .../commands/CommandOperationContext.html | 31 +- .../co/aikar/commands/CommandParameter.html | 459 +++--- .../src-html/co/aikar/commands/HelpEntry.html | 81 +- .../co/aikar/commands/RegisteredCommand.html | 511 +++---- .../commands/JDACommandExecutionContext.html | 2 +- .../co/aikar/commands/JDARootCommand.html | 36 +- .../co/aikar/commands/JDACommandContexts.html | 2 +- .../SpongeCommandExecutionContext.html | 2 +- .../SpongeCommandOperationContext.html | 2 +- .../commands/SpongeRegisteredCommand.html | 19 +- .../co/aikar/commands/SpongeRootCommand.html | 62 +- .../co/aikar/commands/SpongeRootCommand.html | 92 +- 38 files changed, 2626 insertions(+), 2334 deletions(-) diff --git a/docs/acf-bukkit/co/aikar/commands/BukkitCommandExecutionContext.html b/docs/acf-bukkit/co/aikar/commands/BukkitCommandExecutionContext.html index 834ba0f3..bba54892 100644 --- a/docs/acf-bukkit/co/aikar/commands/BukkitCommandExecutionContext.html +++ b/docs/acf-bukkit/co/aikar/commands/BukkitCommandExecutionContext.html @@ -164,7 +164,7 @@ extends co.aikar.commands.CommandExecutionContext<
  • diff --git a/docs/acf-bukkit/co/aikar/commands/BukkitRegisteredCommand.html b/docs/acf-bukkit/co/aikar/commands/BukkitRegisteredCommand.html index fb8ddee8..b8c2da8f 100644 --- a/docs/acf-bukkit/co/aikar/commands/BukkitRegisteredCommand.html +++ b/docs/acf-bukkit/co/aikar/commands/BukkitRegisteredCommand.html @@ -74,7 +74,7 @@ var activeTableTab = "activeTableTab"; @@ -121,6 +121,21 @@ extends co.aikar.commands.RegisteredCommand< - - - - - - - - @@ -424,12 +398,30 @@ extends org.bukkit.command.Command -
  • diff --git a/docs/acf-bukkit/index-all.html b/docs/acf-bukkit/index-all.html index b8e6b26a..20881916 100644 --- a/docs/acf-bukkit/index-all.html +++ b/docs/acf-bukkit/index-all.html @@ -209,8 +209,6 @@
     
    getDefCommand() - Method in class co.aikar.commands.BukkitRootCommand
     
    -
    getDescription() - Method in class co.aikar.commands.BukkitRootCommand
    -
     
    getIssuer() - Method in class co.aikar.commands.BukkitCommandIssuer
     
    getLocales() - Method in class co.aikar.commands.BukkitCommandManager
    @@ -261,8 +259,6 @@
     
    getUniqueId() - Method in class co.aikar.commands.BukkitCommandIssuer
     
    -
    getUsage() - Method in class co.aikar.commands.BukkitRootCommand
    -
     
    diff --git a/docs/acf-bukkit/src-html/co/aikar/commands/BukkitRootCommand.html b/docs/acf-bukkit/src-html/co/aikar/commands/BukkitRootCommand.html index 63420748..20f7e2cf 100644 --- a/docs/acf-bukkit/src-html/co/aikar/commands/BukkitRootCommand.html +++ b/docs/acf-bukkit/src-html/co/aikar/commands/BukkitRootCommand.html @@ -102,38 +102,7 @@ 094 return defCommand; 095 } 096 -097 @Override -098 public String getDescription() { -099 final RegisteredCommand cmd = this.getDefaultRegisteredCommand(); -100 if (cmd != null) { -101 return cmd.helpText; -102 } -103 BaseCommand defCommand = getDefCommand(); -104 if (defCommand != null) { -105 Description descAnno = defCommand.getClass().getAnnotation(Description.class); -106 if (descAnno != null) { -107 return descAnno.value(); -108 } -109 } -110 return ""; -111 } -112 -113 @Override -114 public String getUsage() { -115 final RegisteredCommand cmd = this.getDefaultRegisteredCommand(); -116 if (cmd != null) { -117 return cmd.syntaxText; -118 } -119 BaseCommand defCommand = getDefCommand(); -120 if (defCommand != null) { -121 Syntax syntaxAnno = defCommand.getClass().getAnnotation(Syntax.class); -122 if (syntaxAnno != null) { -123 return syntaxAnno.value(); -124 } -125 } -126 return ""; -127 } -128} +097} diff --git a/docs/acf-bungee/co/aikar/commands/BungeeCommandExecutionContext.html b/docs/acf-bungee/co/aikar/commands/BungeeCommandExecutionContext.html index d2d8b943..00c4b863 100644 --- a/docs/acf-bungee/co/aikar/commands/BungeeCommandExecutionContext.html +++ b/docs/acf-bungee/co/aikar/commands/BungeeCommandExecutionContext.html @@ -162,7 +162,7 @@ extends co.aikar.commands.CommandExecutionContext<
  • diff --git a/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html b/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html index 0ff84280..3bb7e0d7 100644 --- a/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html +++ b/docs/acf-bungee/co/aikar/commands/BungeeRegisteredCommand.html @@ -74,7 +74,7 @@ var activeTableTab = "activeTableTab"; @@ -121,6 +121,21 @@ extends co.aikar.commands.RegisteredCommand< @@ -335,7 +335,7 @@ extends
  • CATCHUNKNOWN

    -
    public static final String CATCHUNKNOWN
    +
    public static final String CATCHUNKNOWN
    See Also:
    Constant Field Values
    @@ -348,7 +348,7 @@ extends
  • DEFAULT

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

    -
    public BaseCommand()
    +
    public BaseCommand()
  • @@ -378,7 +378,7 @@ extends
  • BaseCommand

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

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

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

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

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

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

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

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

    -
    public List<StringtabComplete(CommandIssuer issuer,
    +
    public List<StringtabComplete(CommandIssuer issuer,
                                     String commandLabel,
                                     String[] args)
  • @@ -487,7 +487,7 @@ extends
  • tabComplete

    -
    public List<StringtabComplete(CommandIssuer issuer,
    +
    public List<StringtabComplete(CommandIssuer issuer,
                                     String commandLabel,
                                     String[] args,
                                     boolean isAsync)
    @@ -505,7 +505,7 @@ extends 
     

    getCommandHelp

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

    showCommandHelp

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

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

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

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

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

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

    -
    public boolean hasPermission(Object issuer)
    +
    public boolean hasPermission(Object issuer)
  • @@ -585,7 +585,7 @@ public void 
  • hasPermission

    -
    public boolean hasPermission(CommandIssuer issuer)
    +
    public boolean hasPermission(CommandIssuer issuer)
  • @@ -594,7 +594,7 @@ public void 
  • getRequiredPermissions

    -
    public Set<StringgetRequiredPermissions()
    +
    public Set<StringgetRequiredPermissions()
  • @@ -603,7 +603,7 @@ public void 
  • requiresPermission

    -
    public boolean requiresPermission(String permission)
    +
    public boolean requiresPermission(String permission)
  • @@ -612,7 +612,7 @@ public void 
  • getName

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

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

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

    -
    public RegisteredCommand getDefaultRegisteredCommand()
    +
    public RegisteredCommand getDefaultRegisteredCommand()
  • @@ -648,7 +648,7 @@ public void 
  • setContextFlags

    -
    public String setContextFlags(Class<?> cls,
    +
    public String setContextFlags(Class<?> cls,
                                   String flags)
  • @@ -658,7 +658,7 @@ public void 
  • getContextFlags

    -
    public String getContextFlags(Class<?> cls)
    +
    public String getContextFlags(Class<?> cls)
  • diff --git a/docs/acf-core/co/aikar/commands/CommandConditions.Condition.html b/docs/acf-core/co/aikar/commands/CommandConditions.Condition.html index c9cc6583..9da239ee 100644 --- a/docs/acf-core/co/aikar/commands/CommandConditions.Condition.html +++ b/docs/acf-core/co/aikar/commands/CommandConditions.Condition.html @@ -104,7 +104,7 @@ var activeTableTab = "activeTableTab";


    -
    public static interface CommandConditions.Condition<I extends CommandIssuer>
    +
    public static interface CommandConditions.Condition<I extends CommandIssuer>
  • @@ -148,7 +148,7 @@ var activeTableTab = "activeTableTab"; @@ -152,7 +152,7 @@ var activeTableTab = "activeTableTab"; + + + + + + + + @@ -581,7 +618,7 @@ extends
  • hasAnnotation

    -
    public <T extends Annotation> boolean hasAnnotation(Class<T> cls)
    +
    public <T extends Annotation> boolean hasAnnotation(Class<T> cls)
  • @@ -590,7 +627,7 @@ extends
  • getCmd

    -
    public RegisteredCommand getCmd()
    +
    public RegisteredCommand getCmd()
  • @@ -599,7 +636,9 @@ extends
  • getParam

    -
    public Parameter getParam()
    +
    @Deprecated
    +public Parameter getParam()
    +
    Deprecated. 
  • @@ -608,7 +647,7 @@ extends
  • getIssuer

    -
    public I getIssuer()
    +
    public I getIssuer()
  • @@ -617,7 +656,7 @@ extends
  • getArgs

    -
    public List<StringgetArgs()
    +
    public List<StringgetArgs()
  • @@ -626,7 +665,7 @@ extends
  • getIndex

    -
    public int getIndex()
    +
    public int getIndex()
  • @@ -635,7 +674,7 @@ extends
  • getPassedArgs

    -
    public Map<String,ObjectgetPassedArgs()
    +
    public Map<String,ObjectgetPassedArgs()
  • @@ -644,7 +683,7 @@ extends
  • getFlags

    -
    public Map<String,StringgetFlags()
    +
    public Map<String,StringgetFlags()
  • @@ -653,7 +692,7 @@ extends
  • joinArgs

    -
    public String joinArgs()
    +
    public String joinArgs()
  • @@ -662,7 +701,7 @@ extends
  • joinArgs

    -
    public String joinArgs(String sep)
    +
    public String joinArgs(String sep)
  • diff --git a/docs/acf-core/co/aikar/commands/CommandManager.html b/docs/acf-core/co/aikar/commands/CommandManager.html index 2606130b..22582368 100644 --- a/docs/acf-core/co/aikar/commands/CommandManager.html +++ b/docs/acf-core/co/aikar/commands/CommandManager.html @@ -108,7 +108,7 @@ var activeTableTab = "activeTableTab";


  • -
    public abstract class CommandManager<IT,I extends CommandIssuer,FT,MF extends MessageFormatter<FT>,CEC extends CommandExecutionContext<CEC,I>,CC extends ConditionContext<I>>
    +
    public abstract class CommandManager<IT,I extends CommandIssuer,FT,MF extends MessageFormatter<FT>,CEC extends CommandExecutionContext<CEC,I>,CC extends ConditionContext<I>>
     extends Object
  • @@ -538,7 +538,7 @@ extends
  • rootCommands

    -
    protected Map<String,co.aikar.commands.RootCommand> rootCommands
    +
    protected Map<String,co.aikar.commands.RootCommand> rootCommands
  • @@ -547,7 +547,7 @@ extends
  • replacements

    -
    protected final CommandReplacements replacements
    +
    protected final CommandReplacements replacements
  • @@ -556,7 +556,7 @@ extends
  • conditions

    -
    protected final CommandConditions<I extends CommandIssuer,CEC extends CommandExecutionContext<CEC,I>,CC extends ConditionContext<I>> conditions
    +
    protected final CommandConditions<I extends CommandIssuer,CEC extends CommandExecutionContext<CEC,I>,CC extends ConditionContext<I>> conditions
  • @@ -565,7 +565,7 @@ extends
  • defaultExceptionHandler

    -
    protected ExceptionHandler defaultExceptionHandler
    +
    protected ExceptionHandler defaultExceptionHandler
  • @@ -574,7 +574,7 @@ extends
  • dependencies

    -
    protected com.google.common.collect.Table<Class<?>,String,Object> dependencies
    +
    protected com.google.common.collect.Table<Class<?>,String,Object> dependencies
  • @@ -583,7 +583,7 @@ extends
  • usePerIssuerLocale

    -
    protected boolean usePerIssuerLocale
    +
    protected boolean usePerIssuerLocale
  • @@ -592,7 +592,7 @@ extends
  • localeChangedCallbacks

    -
    protected List<IssuerLocaleChangedCallback<I extends CommandIssuer>> localeChangedCallbacks
    +
    protected List<IssuerLocaleChangedCallback<I extends CommandIssuer>> localeChangedCallbacks
  • @@ -601,7 +601,7 @@ extends
  • supportedLanguages

    -
    protected Set<Locale> supportedLanguages
    +
    protected Set<Locale> supportedLanguages
  • @@ -610,7 +610,7 @@ extends
  • formatters

    -
    protected Map<MessageType,MF extends MessageFormatter<FT>> formatters
    +
    protected Map<MessageType,MF extends MessageFormatter<FT>> formatters
  • @@ -619,7 +619,7 @@ extends
  • defaultFormatter

    -
    protected MF extends MessageFormatter<FT> defaultFormatter
    +
    protected MF extends MessageFormatter<FT> defaultFormatter
  • @@ -628,7 +628,7 @@ extends
  • defaultHelpPerPage

    -
    protected int defaultHelpPerPage
    +
    protected int defaultHelpPerPage
  • @@ -637,7 +637,7 @@ extends
  • issuersLocale

    -
    protected Map<UUID,Locale> issuersLocale
    +
    protected Map<UUID,Locale> issuersLocale
  • @@ -654,7 +654,7 @@ extends
  • CommandManager

    -
    public CommandManager()
    +
    public CommandManager()
  • @@ -671,7 +671,7 @@ extends
  • getCurrentCommandOperationContext

    -
    public static CommandOperationContext getCurrentCommandOperationContext()
    +
    public static CommandOperationContext getCurrentCommandOperationContext()
  • @@ -680,7 +680,7 @@ extends
  • getCurrentCommandIssuer

    -
    public static CommandIssuer getCurrentCommandIssuer()
    +
    public static CommandIssuer getCurrentCommandIssuer()
  • @@ -689,7 +689,7 @@ extends
  • getCurrentCommandManager

    -
    public static CommandManager getCurrentCommandManager()
    +
    public static CommandManager getCurrentCommandManager()
  • @@ -700,7 +700,7 @@ extends
  • setFormat

    -
    public MF setFormat(MessageType type,
    +
    public MF setFormat(MessageType type,
                         MF formatter)
  • @@ -710,7 +710,7 @@ extends
  • getFormat

    -
    public MF getFormat(MessageType type)
    +
    public MF getFormat(MessageType type)
  • @@ -721,7 +721,7 @@ extends
  • setFormat

    -
    public void setFormat(MessageType type,
    +
    public void setFormat(MessageType type,
                           FT... colors)
  • @@ -733,7 +733,7 @@ extends
  • setFormat

    -
    public void setFormat(MessageType type,
    +
    public void setFormat(MessageType type,
                           int i,
                           FT color)
  • @@ -744,7 +744,7 @@ extends
  • getDefaultFormatter

    -
    public MF getDefaultFormatter()
    +
    public MF getDefaultFormatter()
  • @@ -755,7 +755,7 @@ extends
  • setDefaultFormatter

    -
    public void setDefaultFormatter(MF defaultFormatter)
    +
    public void setDefaultFormatter(MF defaultFormatter)
  • @@ -764,7 +764,7 @@ extends
  • getCommandConditions

    -
    public CommandConditions<I,CEC,CCgetCommandConditions()
    +
    public CommandConditions<I,CEC,CCgetCommandConditions()
  • @@ -773,7 +773,7 @@ extends
  • getCommandContexts

    -
    public abstract CommandContexts<?> getCommandContexts()
    +
    public abstract CommandContexts<?> getCommandContexts()
    Gets the command contexts manager
    Returns:
    @@ -787,7 +787,7 @@ extends
  • getCommandCompletions

    -
    public abstract CommandCompletions<?> getCommandCompletions()
    +
    public abstract CommandCompletions<?> getCommandCompletions()
    Gets the command completions manager
    Returns:
    @@ -802,7 +802,7 @@ extends

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp(@NotNull
    +public CommandHelp generateCommandHelp(@NotNull
                                                        @NotNull String command)
    Deprecated. Unstable API
  • @@ -814,7 +814,7 @@ public 

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp(CommandIssuer issuer,
    +public CommandHelp generateCommandHelp(CommandIssuer issuer,
                                                        @NotNull
                                                        @NotNull String command)
    Deprecated. Unstable API
    @@ -827,7 +827,7 @@ public 

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp()
    +public CommandHelp generateCommandHelp()
    Deprecated. Unstable API
  • @@ -838,7 +838,7 @@ public 

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp(CommandIssuer issuer,
    +public CommandHelp generateCommandHelp(CommandIssuer issuer,
                                                        co.aikar.commands.RootCommand rootCommand)
    Deprecated. Unstable API
    @@ -850,7 +850,7 @@ public 

    getDefaultHelpPerPage

    @Deprecated
    -public int getDefaultHelpPerPage()
    +public int getDefaultHelpPerPage()
    Deprecated. Unstable API
    @@ -861,7 +861,7 @@ public int 

    setDefaultHelpPerPage

    @Deprecated
    -public void setDefaultHelpPerPage(int defaultHelpPerPage)
    +public void setDefaultHelpPerPage(int defaultHelpPerPage)
    Deprecated. Unstable API
    @@ -871,7 +871,7 @@ public void 
  • registerCommand

    -
    public abstract void registerCommand(BaseCommand command)
    +
    public abstract void registerCommand(BaseCommand command)
    Registers a command with ACF
    Parameters:
    @@ -885,7 +885,7 @@ public void 
  • hasRegisteredCommands

    -
    public abstract boolean hasRegisteredCommands()
    +
    public abstract boolean hasRegisteredCommands()
  • @@ -894,7 +894,7 @@ public void 
  • isCommandIssuer

    -
    public abstract boolean isCommandIssuer(Class<?> type)
    +
    public abstract boolean isCommandIssuer(Class<?> type)
  • @@ -903,7 +903,7 @@ public void 
  • getCommandIssuer

    -
    public abstract I getCommandIssuer(Object issuer)
    +
    public abstract I getCommandIssuer(Object issuer)
  • @@ -912,7 +912,7 @@ public void 
  • createRootCommand

    -
    public abstract co.aikar.commands.RootCommand createRootCommand(String cmd)
    +
    public abstract co.aikar.commands.RootCommand createRootCommand(String cmd)
  • @@ -921,7 +921,7 @@ public void 
  • getLocales

    -
    public abstract Locales getLocales()
    +
    public abstract Locales getLocales()
    Returns a Locales Manager to add and modify language tables for your commands.
    Returns:
    @@ -934,7 +934,7 @@ public void 
  • usingPerIssuerLocale

    -
    public boolean usingPerIssuerLocale()
    +
    public boolean usingPerIssuerLocale()
  • @@ -943,7 +943,7 @@ public void 
  • usePerIssuerLocale

    -
    public boolean usePerIssuerLocale(boolean setting)
    +
    public boolean usePerIssuerLocale(boolean setting)
  • @@ -952,7 +952,7 @@ public void 
  • createConditionContext

    -
    public ConditionContext createConditionContext(CommandIssuer issuer,
    +
    public ConditionContext createConditionContext(CommandIssuer issuer,
                                                    String config)
  • @@ -962,7 +962,7 @@ public void 
  • createCommandContext

    -
    public abstract CommandExecutionContext createCommandContext(RegisteredCommand command,
    +
    public abstract CommandExecutionContext createCommandContext(RegisteredCommand command,
                                                                  CommandParameter parameter,
                                                                  CommandIssuer sender,
                                                                  List<String> args,
    @@ -976,7 +976,7 @@ public void 
     
  • createCompletionContext

    -
    public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command,
    +
    public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command,
                                                                      CommandIssuer sender,
                                                                      String input,
                                                                      String config,
    @@ -989,7 +989,7 @@ public void 
     
  • log

    -
    public abstract void log(co.aikar.commands.LogLevel level,
    +
    public abstract void log(co.aikar.commands.LogLevel level,
                              String message,
                              Throwable throwable)
  • @@ -1000,7 +1000,7 @@ public void 
  • log

    -
    public void log(co.aikar.commands.LogLevel level,
    +
    public void log(co.aikar.commands.LogLevel level,
                     String message)
  • @@ -1010,7 +1010,7 @@ public void 
  • getCommandReplacements

    -
    public CommandReplacements getCommandReplacements()
    +
    public CommandReplacements getCommandReplacements()
    Lets you add custom string replacements that can be applied to annotation values, to reduce duplication/repetition of common values such as permission nodes and command prefixes. @@ -1029,7 +1029,7 @@ public void 
  • hasPermission

    -
    public boolean hasPermission(CommandIssuer issuer,
    +
    public boolean hasPermission(CommandIssuer issuer,
                                  String permission)
  • @@ -1039,7 +1039,7 @@ public void 
  • getRootCommand

    -
    public co.aikar.commands.RootCommand getRootCommand(@NotNull
    +
    public co.aikar.commands.RootCommand getRootCommand(@NotNull
                                                         @NotNull String cmd)
  • @@ -1049,7 +1049,7 @@ public void 
  • obtainRootCommand

    -
    public co.aikar.commands.RootCommand obtainRootCommand(@NotNull
    +
    public co.aikar.commands.RootCommand obtainRootCommand(@NotNull
                                                            @NotNull String cmd)
  • @@ -1059,7 +1059,7 @@ public void 
  • createRegisteredCommand

    -
    public RegisteredCommand createRegisteredCommand(BaseCommand command,
    +
    public RegisteredCommand createRegisteredCommand(BaseCommand command,
                                                      String cmdName,
                                                      Method method,
                                                      String prefSubCommand)
    @@ -1071,7 +1071,7 @@ public void 
  • setDefaultExceptionHandler

    -
    public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler)
    +
    public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler)
    Sets the default ExceptionHandler that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered.
    Parameters:
    @@ -1085,7 +1085,7 @@ public void 
  • getDefaultExceptionHandler

    -
    public ExceptionHandler getDefaultExceptionHandler()
    +
    public ExceptionHandler getDefaultExceptionHandler()
    Gets the current default exception handler, might be null.
    Returns:
    @@ -1099,7 +1099,7 @@ public void 
  • handleUncaughtException

    -
    protected boolean handleUncaughtException(BaseCommand scope,
    +
    protected boolean handleUncaughtException(BaseCommand scope,
                                               RegisteredCommand registeredCommand,
                                               CommandIssuer sender,
                                               List<String> args,
    @@ -1114,7 +1114,7 @@ public void 
     
  • sendMessage

    -
    public void sendMessage(IT issuerArg,
    +
    public void sendMessage(IT issuerArg,
                             MessageType type,
                             co.aikar.locales.MessageKeyProvider key,
                             String... replacements)
    @@ -1126,7 +1126,7 @@ public void 
  • sendMessage

    -
    public void sendMessage(CommandIssuer issuer,
    +
    public void sendMessage(CommandIssuer issuer,
                             MessageType type,
                             co.aikar.locales.MessageKeyProvider key,
                             String... replacements)
    @@ -1138,7 +1138,7 @@ public void 
  • formatMessage

    -
    public String formatMessage(CommandIssuer issuer,
    +
    public String formatMessage(CommandIssuer issuer,
                                 MessageType type,
                                 co.aikar.locales.MessageKeyProvider key,
                                 String... replacements)
    @@ -1150,7 +1150,7 @@ public void 
  • onLocaleChange

    -
    public void onLocaleChange(IssuerLocaleChangedCallback<I> onChange)
    +
    public void onLocaleChange(IssuerLocaleChangedCallback<I> onChange)
  • @@ -1161,7 +1161,7 @@ public void 
  • notifyLocaleChange

    -
    public void notifyLocaleChange(I issuer,
    +
    public void notifyLocaleChange(I issuer,
                                    Locale oldLocale,
                                    Locale newLocale)
  • @@ -1174,7 +1174,7 @@ public void 
  • setIssuerLocale

    -
    public Locale setIssuerLocale(IT issuer,
    +
    public Locale setIssuerLocale(IT issuer,
                                   Locale locale)
  • @@ -1184,7 +1184,7 @@ public void 
  • getIssuerLocale

    -
    public Locale getIssuerLocale(CommandIssuer issuer)
    +
    public Locale getIssuerLocale(CommandIssuer issuer)
  • @@ -1193,7 +1193,7 @@ public void 
  • getSupportedLanguages

    -
    public Set<LocalegetSupportedLanguages()
    +
    public Set<LocalegetSupportedLanguages()
    Gets a list of all currently supported languages for this manager. These locales will be automatically loaded from
    @@ -1207,7 +1207,7 @@ public void 
  • addSupportedLanguage

    -
    public void addSupportedLanguage(Locale locale)
    +
    public void addSupportedLanguage(Locale locale)
    Adds a new locale to the list of automatic Locales to load Message Bundles for. All bundles loaded under the previous supported languages will now automatically load for this new locale too.
    @@ -1224,7 +1224,7 @@ public void 
  • registerDependency

    -
    public <T> void registerDependency(Class<? extends T> clazz,
    +
    public <T> void registerDependency(Class<? extends T> clazz,
                                        T instance)
    Registers an instance of a class to be registered as an injectable dependency.
    The command manager will attempt to inject all fields in a command class that are annotated with @@ -1246,7 +1246,7 @@ public void 
  • registerDependency

    -
    public <T> void registerDependency(Class<? extends T> clazz,
    +
    public <T> void registerDependency(Class<? extends T> clazz,
                                        String key,
                                        T instance)
    Registers an instance of a class to be registered as an injectable dependency.
    @@ -1269,7 +1269,7 @@ public void 

    enableUnstableAPI

    @Deprecated
    -public void enableUnstableAPI(String api)
    +public void enableUnstableAPI(String api)
    Deprecated. Use this with caution! If you enable and use Unstable API's, your next compile using ACF may require you to update your implementation to those unstable API's
  • diff --git a/docs/acf-core/co/aikar/commands/CommandOperationContext.html b/docs/acf-core/co/aikar/commands/CommandOperationContext.html index 9da78ab6..0570d8f0 100644 --- a/docs/acf-core/co/aikar/commands/CommandOperationContext.html +++ b/docs/acf-core/co/aikar/commands/CommandOperationContext.html @@ -18,8 +18,8 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10}; -var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; +var methods = {"i0":42,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":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"; var tableTab = "tableTab"; @@ -124,48 +124,61 @@ extends -All Methods Instance Methods Concrete Methods  +All Methods Instance Methods Concrete Methods Deprecated Methods  Modifier and Type Method and Description <T extends Annotation>
    T
    -getAnnotation(Class<T> anno)  +getAnnotation(Class<T> anno) +
    Deprecated.  + +
    + +<T extends Annotation>
    String
    +getAnnotationValue(Class<T> cls)  + + +<T extends Annotation>
    String
    +getAnnotationValue(Class<T> cls, + int options)  + + String[] getArgs()  - + BaseCommand getCommand()  - + I getCommandIssuer()  - + String getCommandLabel()  - + CommandManager getCommandManager()  - + RegisteredCommand getRegisteredCommand()  - + boolean hasAnnotation(Class<? extends Annotation> anno)  - + boolean isAsync()  - + void setRegisteredCommand(RegisteredCommand registeredCommand)  @@ -269,7 +282,29 @@ extends
  • getAnnotation

    -
    public <T extends Annotation> T getAnnotation(Class<T> anno)
    +
    @Deprecated
    +public <T extends Annotation> T getAnnotation(Class<T> anno)
    +
    Deprecated. Use getAnnotationValue(Class)
    +
    This method will not support annotation processors!! use getAnnotationValue or hasAnnotation
    +
  • + + + + + + + + + @@ -278,7 +313,7 @@ extends
  • hasAnnotation

    -
    public boolean hasAnnotation(Class<? extends Annotation> anno)
    +
    public boolean hasAnnotation(Class<? extends Annotation> anno)
  • diff --git a/docs/acf-core/co/aikar/commands/CommandParameter.html b/docs/acf-core/co/aikar/commands/CommandParameter.html index 75ccc01b..508f9c34 100644 --- a/docs/acf-core/co/aikar/commands/CommandParameter.html +++ b/docs/acf-core/co/aikar/commands/CommandParameter.html @@ -18,7 +18,7 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"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":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10}; +var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"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":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10}; var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; @@ -108,7 +108,7 @@ var activeTableTab = "activeTableTab";


  • -
    public class CommandParameter<CEC extends CommandExecutionContext<CEC,? extends CommandIssuer>>
    +
    public class CommandParameter<CEC extends CommandExecutionContext<CEC,? extends CommandIssuer>>
     extends Object
  • @@ -153,106 +153,114 @@ extends String -getDefaultValue()  +getConditions()  String -getDescription()  +getDefaultValue()  +String +getDescription()  + + Map<String,String> getFlags()  - + CommandManager getManager()  - + String getName()  - + Parameter getParameter()  - + int getParamIndex()  - + ContextResolver<?,CEC> getResolver()  - + String getSyntax()  - + Class<?> getType()  - + String[] getValues()  - + boolean isCommandIssuer()  - + boolean isOptional()  - + boolean isOptionalResolver()  - + boolean requiresInput()  - + void setCanConsumeInput(boolean canConsumeInput)  - + void setCommandIssuer(boolean commandIssuer)  - -void -setDefaultValue(String defaultValue)  - void -setDescription(String description)  +setConditions(String conditions)  void -setFlags(Map<String,String> flags)  +setDefaultValue(String defaultValue)  void -setOptional(boolean optional)  +setDescription(String description)  void -setOptionalResolver(boolean optionalResolver)  +setFlags(Map<String,String> flags)  void -setRequiresInput(boolean requiresInput)  +setOptional(boolean optional)  void -setResolver(ContextResolver<?,CEC> resolver)  +setOptionalResolver(boolean optionalResolver)  void -setSyntax(String syntax)  +setRequiresInput(boolean requiresInput)  void +setResolver(ContextResolver<?,CEC> resolver)  + + +void +setSyntax(String syntax)  + + +void setValues(String[] values)  @@ -283,7 +291,7 @@ extends
  • CommandParameter

    -
    public CommandParameter(RegisteredCommand<CEC> command,
    +
    public CommandParameter(RegisteredCommand<CEC> command,
                             Parameter param,
                             int paramIndex)
  • @@ -302,7 +310,7 @@ extends
  • getParameter

    -
    public Parameter getParameter()
    +
    public Parameter getParameter()
  • @@ -311,7 +319,7 @@ extends
  • getType

    -
    public Class<?> getType()
    +
    public Class<?> getType()
  • @@ -320,7 +328,7 @@ extends
  • getName

    -
    public String getName()
    +
    public String getName()
  • @@ -329,7 +337,7 @@ extends
  • getManager

    -
    public CommandManager getManager()
    +
    public CommandManager getManager()
  • @@ -338,7 +346,7 @@ extends
  • getParamIndex

    -
    public int getParamIndex()
    +
    public int getParamIndex()
  • @@ -347,7 +355,7 @@ extends
  • getResolver

    -
    public ContextResolver<?,CECgetResolver()
    +
    public ContextResolver<?,CECgetResolver()
  • @@ -356,7 +364,7 @@ extends
  • setResolver

    -
    public void setResolver(ContextResolver<?,CEC> resolver)
    +
    public void setResolver(ContextResolver<?,CEC> resolver)
  • @@ -365,7 +373,7 @@ extends
  • isOptional

    -
    public boolean isOptional()
    +
    public boolean isOptional()
  • @@ -374,7 +382,7 @@ extends
  • setOptional

    -
    public void setOptional(boolean optional)
    +
    public void setOptional(boolean optional)
  • @@ -383,7 +391,7 @@ extends
  • getDescription

    -
    public String getDescription()
    +
    public String getDescription()
  • @@ -392,7 +400,7 @@ extends
  • setDescription

    -
    public void setDescription(String description)
    +
    public void setDescription(String description)
  • @@ -401,7 +409,7 @@ extends
  • getDefaultValue

    -
    public String getDefaultValue()
    +
    public String getDefaultValue()
  • @@ -410,7 +418,7 @@ extends
  • setDefaultValue

    -
    public void setDefaultValue(String defaultValue)
    +
    public void setDefaultValue(String defaultValue)
  • @@ -419,7 +427,7 @@ extends
  • isCommandIssuer

    -
    public boolean isCommandIssuer()
    +
    public boolean isCommandIssuer()
  • @@ -428,7 +436,7 @@ extends
  • setCommandIssuer

    -
    public void setCommandIssuer(boolean commandIssuer)
    +
    public void setCommandIssuer(boolean commandIssuer)
  • @@ -437,7 +445,7 @@ extends
  • getValues

    -
    public String[] getValues()
    +
    public String[] getValues()
  • @@ -446,7 +454,7 @@ extends
  • setValues

    -
    public void setValues(String[] values)
    +
    public void setValues(String[] values)
  • @@ -455,7 +463,7 @@ extends
  • getFlags

    -
    public Map<String,StringgetFlags()
    +
    public Map<String,StringgetFlags()
  • @@ -464,7 +472,7 @@ extends
  • setFlags

    -
    public void setFlags(Map<String,String> flags)
    +
    public void setFlags(Map<String,String> flags)
  • @@ -473,7 +481,7 @@ extends
  • canConsumeInput

    -
    public boolean canConsumeInput()
    +
    public boolean canConsumeInput()
  • @@ -482,7 +490,7 @@ extends
  • setCanConsumeInput

    -
    public void setCanConsumeInput(boolean canConsumeInput)
    +
    public void setCanConsumeInput(boolean canConsumeInput)
  • @@ -491,7 +499,7 @@ extends
  • setOptionalResolver

    -
    public void setOptionalResolver(boolean optionalResolver)
    +
    public void setOptionalResolver(boolean optionalResolver)
  • @@ -500,7 +508,7 @@ extends
  • isOptionalResolver

    -
    public boolean isOptionalResolver()
    +
    public boolean isOptionalResolver()
  • @@ -509,7 +517,7 @@ extends
  • requiresInput

    -
    public boolean requiresInput()
    +
    public boolean requiresInput()
  • @@ -518,7 +526,7 @@ extends
  • setRequiresInput

    -
    public void setRequiresInput(boolean requiresInput)
    +
    public void setRequiresInput(boolean requiresInput)
  • @@ -527,16 +535,34 @@ extends
  • getSyntax

    -
    public String getSyntax()
    +
    public String getSyntax()
  • - @@ -193,7 +193,7 @@ extends
  • getParameterSyntax

    -
    public String getParameterSyntax()
    +
    public String getParameterSyntax()
  • @@ -202,7 +202,7 @@ extends
  • getDescription

    -
    public String getDescription()
    +
    public String getDescription()
  • @@ -211,7 +211,7 @@ extends
  • setSearchScore

    -
    public void setSearchScore(int searchScore)
    +
    public void setSearchScore(int searchScore)
  • @@ -220,7 +220,7 @@ extends
  • shouldShow

    -
    public boolean shouldShow()
    +
    public boolean shouldShow()
  • @@ -229,7 +229,7 @@ extends
  • getSearchScore

    -
    public int getSearchScore()
    +
    public int getSearchScore()
  • @@ -238,7 +238,7 @@ extends
  • getSearchTags

    -
    public String getSearchTags()
    +
    public String getSearchTags()
  • diff --git a/docs/acf-core/co/aikar/commands/RegisteredCommand.html b/docs/acf-core/co/aikar/commands/RegisteredCommand.html index 75bc52f4..7b2c7058 100644 --- a/docs/acf-core/co/aikar/commands/RegisteredCommand.html +++ b/docs/acf-core/co/aikar/commands/RegisteredCommand.html @@ -74,13 +74,13 @@ var activeTableTab = "activeTableTab"; @@ -108,7 +108,7 @@ var activeTableTab = "activeTableTab";


  • -
    public class RegisteredCommand<CEC extends CommandExecutionContext<CEC,? extends CommandIssuer>>
    +
    public class RegisteredCommand<CEC extends CommandExecutionContext<CEC,? extends CommandIssuer>>
     extends Object
  • @@ -116,6 +116,25 @@ extends
  • Deprecated. 
    See Also:
    @@ -231,7 +267,7 @@ public 
  • getRequiredPermissions

    -
    public Set<StringgetRequiredPermissions()
    +
    public Set<StringgetRequiredPermissions()
  • @@ -240,7 +276,7 @@ public 
  • requiresPermission

    -
    public boolean requiresPermission(String permission)
    +
    public boolean requiresPermission(String permission)
  • @@ -249,7 +285,7 @@ public 
  • getPrefSubCommand

    -
    public String getPrefSubCommand()
    +
    public String getPrefSubCommand()
  • @@ -258,7 +294,7 @@ public 
  • getSyntaxText

    -
    public String getSyntaxText()
    +
    public String getSyntaxText()
  • @@ -267,7 +303,7 @@ public 
  • getCommand

    -
    public String getCommand()
    +
    public String getCommand()
  • @@ -276,7 +312,7 @@ public 
  • addSubcommand

    -
    public void addSubcommand(String cmd)
    +
    public void addSubcommand(String cmd)
  • @@ -285,7 +321,7 @@ public 
  • addSubcommands

    -
    public void addSubcommands(Collection<String> cmd)
    +
    public void addSubcommands(Collection<String> cmd)
  • @@ -341,13 +377,13 @@ public 
  • Summary: 
  • Nested | 
  • -
  • Field | 
  • +
  • Field | 
  • Constr | 
  • Method
  • diff --git a/docs/acf-core/deprecated-list.html b/docs/acf-core/deprecated-list.html index 82a28d1c..5881f90a 100644 --- a/docs/acf-core/deprecated-list.html +++ b/docs/acf-core/deprecated-list.html @@ -185,6 +185,16 @@ +co.aikar.commands.CommandOperationContext.getAnnotation(Class<T>) + + + + +co.aikar.commands.CommandExecutionContext.getAnnotation(Class<T>) + + + + co.aikar.commands.BaseCommand.getCommandHelp()
    Unstable API
    @@ -195,28 +205,31 @@ -co.aikar.commands.RegisteredCommand.getPermission()  +co.aikar.commands.CommandExecutionContext.getParam() -co.aikar.commands.ACFUtil.random(Class<? extends T>) +co.aikar.commands.RegisteredCommand.getPermission()  +co.aikar.commands.ACFUtil.random(Class<? extends T>) + + co.aikar.commands.CommandContexts.registerSenderAwareContext(Class<T>, IssuerAwareContextResolver<T, R>)
    Please switch to CommandContexts.registerIssuerAwareContext(Class, IssuerAwareContextResolver) as the core wants to use the platform agnostic term of "Issuer" instead of Sender
    - + co.aikar.commands.CommandIssuer.sendMessageInternal(String)
    Do not call this, for internal use. Not considered part of the API and may break.
    - + co.aikar.commands.CommandManager.setDefaultHelpPerPage(int)
    Unstable API
    - + co.aikar.commands.BaseCommand.showCommandHelp()
    Unstable API
    diff --git a/docs/acf-core/index-all.html b/docs/acf-core/index-all.html index 462dace6..ac1f733b 100644 --- a/docs/acf-core/index-all.html +++ b/docs/acf-core/index-all.html @@ -447,8 +447,24 @@
    GERMAN - Static variable in class co.aikar.commands.Locales
     
    getAnnotation(Class<T>) - Method in class co.aikar.commands.CommandExecutionContext
    -
     
    +
    + +
    getAnnotation(Class<T>) - Method in class co.aikar.commands.CommandOperationContext
    +
    + +
    +
    getAnnotationValue(Class<T>) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    +
    getAnnotationValue(Class<T>, int) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    +
    getAnnotationValue(Class<T>) - Method in class co.aikar.commands.CommandOperationContext
    +
     
    +
    getAnnotationValue(Class<T>, int) - Method in class co.aikar.commands.CommandOperationContext
     
    getApplicableParameters() - Method in interface co.aikar.commands.AnnotationProcessor
    @@ -516,6 +532,8 @@
    getCompletions(C) - Method in interface co.aikar.commands.CommandCompletions.CommandCompletionHandler
     
    +
    getConditions() - Method in class co.aikar.commands.CommandParameter
    +
     
    getConfig(String) - Method in class co.aikar.commands.CommandCompletionContext
     
    getConfig(String, String) - Method in class co.aikar.commands.CommandCompletionContext
    @@ -684,7 +702,9 @@
    Gets the actual args in string form the user typed
    getParam() - Method in class co.aikar.commands.CommandExecutionContext
    -
     
    +
    +
    Deprecated.
    +
    getParameter() - Method in class co.aikar.commands.CommandParameter
     
    getParameterSyntax() - Method in class co.aikar.commands.HelpEntry
    @@ -826,6 +846,8 @@
     
    HelpSearchTags - Annotation Type in co.aikar.commands.annotation
     
    +
    helpSearchTags - Variable in class co.aikar.commands.RegisteredCommand
    +
     
    HINDI - Static variable in class co.aikar.commands.Locales
     
  • @@ -1489,6 +1511,8 @@
     
    setCommandIssuer(boolean) - Method in class co.aikar.commands.CommandParameter
     
    +
    setConditions(String) - Method in class co.aikar.commands.CommandParameter
    +
     
    setContextFlags(Class<?>, String) - Method in class co.aikar.commands.BaseCommand
     
    setDefaultExceptionHandler(ExceptionHandler) - Method in class co.aikar.commands.CommandManager
    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 682e1fee..22ba3f62 100644 --- a/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html +++ b/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html @@ -35,666 +35,680 @@ 027import co.aikar.commands.annotation.CatchUnknown; 028import co.aikar.commands.annotation.CommandAlias; 029import co.aikar.commands.annotation.CommandPermission; -030import co.aikar.commands.annotation.Default; -031import co.aikar.commands.annotation.HelpCommand; -032import co.aikar.commands.annotation.PreCommand; -033import co.aikar.commands.annotation.Subcommand; -034import co.aikar.commands.annotation.UnknownHandler; -035import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil; -036import com.google.common.collect.HashMultimap; -037import com.google.common.collect.ImmutableList; -038import com.google.common.collect.ImmutableSet; -039import com.google.common.collect.Iterables; -040import com.google.common.collect.Lists; -041import com.google.common.collect.Maps; -042import com.google.common.collect.SetMultimap; -043import com.google.common.collect.Sets; -044 -045import java.lang.reflect.Constructor; -046import java.lang.reflect.InvocationTargetException; -047import java.lang.reflect.Method; -048import java.lang.reflect.Parameter; -049import java.util.ArrayList; -050import java.util.Arrays; -051import java.util.Collections; -052import java.util.HashMap; -053import java.util.HashSet; -054import java.util.List; -055import java.util.Map; -056import java.util.Objects; -057import java.util.Optional; -058import java.util.Set; -059import java.util.Stack; -060import java.util.stream.Collectors; -061import java.util.stream.Stream; -062 -063@SuppressWarnings("unused") -064public abstract class BaseCommand { -065 -066 public static final String CATCHUNKNOWN = "__catchunknown"; -067 public static final String DEFAULT = "__default"; -068 final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create(); -069 final Map<Class<?>, String> contextFlags = Maps.newHashMap(); -070 private Method preCommandHandler; -071 -072 @SuppressWarnings("WeakerAccess") -073 private String execLabel; -074 @SuppressWarnings("WeakerAccess") -075 private String execSubcommand; -076 @SuppressWarnings("WeakerAccess") -077 private String[] origArgs; -078 CommandManager<?, ?, ?, ?, ?, ?> manager = null; -079 BaseCommand parentCommand; -080 Map<String, RootCommand> registeredCommands = new HashMap<>(); -081 String description; -082 String commandName; -083 String usageMessage; -084 String permission; -085 -086 private ExceptionHandler exceptionHandler = null; -087 CommandOperationContext lastCommandOperationContext; -088 private String parentSubcommand; -089 -090 public BaseCommand() {} -091 public BaseCommand(String cmd) { -092 this.commandName = cmd; -093 } -094 -095 /** -096 * Gets the root command name that the user actually typed -097 * @return Name -098 */ -099 public String getExecCommandLabel() { -100 return execLabel; -101 } -102 -103 /** -104 * Gets the actual sub command name the user typed -105 * @return Name -106 */ -107 public String getExecSubcommand() { -108 return execSubcommand; -109 } -110 -111 /** -112 * Gets the actual args in string form the user typed -113 * @return Args -114 */ -115 public String[] getOrigArgs() { -116 return origArgs; -117 } -118 -119 void setParentCommand(BaseCommand command) { -120 this.parentCommand = command; -121 } -122 void onRegister(CommandManager manager) { -123 onRegister(manager, this.commandName); -124 } -125 void onRegister(CommandManager manager, String cmd) { -126 manager.injectDependencies(this); -127 this.manager = manager; -128 final Class<? extends BaseCommand> self = this.getClass(); -129 CommandAlias rootCmdAliasAnno = self.getAnnotation(CommandAlias.class); -130 String rootCmdAlias = rootCmdAliasAnno != null ? manager.getCommandReplacements().replace(rootCmdAliasAnno.value()).toLowerCase() : null; -131 if (cmd == null && rootCmdAlias != null) { -132 cmd = ACFPatterns.PIPE.split(rootCmdAlias)[0]; -133 } -134 this.commandName = cmd != null ? cmd : self.getSimpleName().toLowerCase(); +030import co.aikar.commands.annotation.Conditions; +031import co.aikar.commands.annotation.Default; +032import co.aikar.commands.annotation.HelpCommand; +033import co.aikar.commands.annotation.PreCommand; +034import co.aikar.commands.annotation.Subcommand; +035import co.aikar.commands.annotation.UnknownHandler; +036import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil; +037import com.google.common.collect.HashMultimap; +038import com.google.common.collect.ImmutableList; +039import com.google.common.collect.ImmutableSet; +040import com.google.common.collect.Iterables; +041import com.google.common.collect.Lists; +042import com.google.common.collect.Maps; +043import com.google.common.collect.SetMultimap; +044import com.google.common.collect.Sets; +045 +046import java.lang.reflect.Constructor; +047import java.lang.reflect.InvocationTargetException; +048import java.lang.reflect.Method; +049import java.lang.reflect.Parameter; +050import java.util.ArrayList; +051import java.util.Arrays; +052import java.util.Collections; +053import java.util.HashMap; +054import java.util.HashSet; +055import java.util.List; +056import java.util.Map; +057import java.util.Objects; +058import java.util.Optional; +059import java.util.Set; +060import java.util.Stack; +061import java.util.stream.Collectors; +062import java.util.stream.Stream; +063 +064@SuppressWarnings("unused") +065public abstract class BaseCommand { +066 +067 public static final String CATCHUNKNOWN = "__catchunknown"; +068 public static final String DEFAULT = "__default"; +069 final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create(); +070 final Map<Class<?>, String> contextFlags = Maps.newHashMap(); +071 private Method preCommandHandler; +072 +073 @SuppressWarnings("WeakerAccess") +074 private String execLabel; +075 @SuppressWarnings("WeakerAccess") +076 private String execSubcommand; +077 @SuppressWarnings("WeakerAccess") +078 private String[] origArgs; +079 CommandManager<?, ?, ?, ?, ?, ?> manager = null; +080 BaseCommand parentCommand; +081 Map<String, RootCommand> registeredCommands = new HashMap<>(); +082 String description; +083 String commandName; +084 String usageMessage; +085 String permission; +086 String conditions; +087 +088 private ExceptionHandler exceptionHandler = null; +089 CommandOperationContext lastCommandOperationContext; +090 private String parentSubcommand; +091 +092 public BaseCommand() {} +093 public BaseCommand(String cmd) { +094 this.commandName = cmd; +095 } +096 +097 /** +098 * Gets the root command name that the user actually typed +099 * @return Name +100 */ +101 public String getExecCommandLabel() { +102 return execLabel; +103 } +104 +105 /** +106 * Gets the actual sub command name the user typed +107 * @return Name +108 */ +109 public String getExecSubcommand() { +110 return execSubcommand; +111 } +112 +113 /** +114 * Gets the actual args in string form the user typed +115 * @return Args +116 */ +117 public String[] getOrigArgs() { +118 return origArgs; +119 } +120 +121 void setParentCommand(BaseCommand command) { +122 this.parentCommand = command; +123 } +124 void onRegister(CommandManager manager) { +125 onRegister(manager, this.commandName); +126 } +127 void onRegister(CommandManager manager, String cmd) { +128 manager.injectDependencies(this); +129 this.manager = manager; +130 +131 final Annotations annotations = manager.getAnnotations(); +132 final Class<? extends BaseCommand> self = this.getClass(); +133 +134 String[] cmdAliases = annotations.getAnnotationValues(self, CommandAlias.class, Annotations.REPLACEMENTS | Annotations.LOWERCASE | Annotations.NO_EMPTY); 135 -136 this.description = this.commandName + " commands"; -137 this.usageMessage = "/" + this.commandName; -138 this.parentSubcommand = getParentSubcommand(this.getClass()); +136 if (cmd == null && cmdAliases != null) { +137 cmd = cmdAliases[0]; +138 } 139 -140 final CommandPermission perm = self.getAnnotation(CommandPermission.class); -141 if (perm != null) { -142 this.permission = manager.getCommandReplacements().replace(perm.value()); -143 } -144 -145 boolean foundDefault = false; -146 boolean foundCatchUnknown = false; -147 boolean isParentEmpty = parentSubcommand.isEmpty(); -148 for (Method method : self.getMethods()) { -149 method.setAccessible(true); -150 String sublist = null; -151 String sub = getSubcommandValue(method); -152 final Default def = method.getAnnotation(Default.class); -153 final HelpCommand helpCommand = method.getAnnotation(HelpCommand.class); -154 final CommandAlias commandAliases = method.getAnnotation(CommandAlias.class); -155 -156 if (!isParentEmpty && def != null) { -157 sub = parentSubcommand; -158 } -159 if (isParentEmpty && (def != null || (!foundDefault && helpCommand != null))) { -160 if (!foundDefault) { -161 if (def != null) { -162 this.subCommands.get(DEFAULT).clear(); -163 foundDefault = true; -164 } -165 registerSubcommand(method, DEFAULT); -166 } else { -167 ACFUtil.sneaky(new IllegalStateException("Multiple @Default/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); -168 } -169 } -170 -171 if (sub != null) { -172 sublist = sub; -173 } else if (commandAliases != null) { -174 sublist = commandAliases.value(); -175 } else if (helpCommand != null) { -176 sublist = helpCommand.value(); -177 } -178 -179 PreCommand preCommand = method.getAnnotation(PreCommand.class); -180 boolean hasCatchUnknown = method.isAnnotationPresent(CatchUnknown.class) || method.isAnnotationPresent(CatchAll.class) || method.isAnnotationPresent(UnknownHandler.class); -181 if (hasCatchUnknown || (!foundCatchUnknown && helpCommand != null)) { -182 if (!foundCatchUnknown) { -183 if (hasCatchUnknown) { -184 this.subCommands.get(CATCHUNKNOWN).clear(); -185 foundCatchUnknown = true; -186 } -187 registerSubcommand(method, CATCHUNKNOWN); -188 } else { -189 ACFUtil.sneaky(new IllegalStateException("Multiple @UnknownHandler/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); -190 } -191 } else if (preCommand != null) { -192 if (this.preCommandHandler == null) { -193 this.preCommandHandler = method; -194 } else { -195 ACFUtil.sneaky(new IllegalStateException("Multiple @PreCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); -196 } -197 } -198 if (Objects.equals(method.getDeclaringClass(), this.getClass()) && sublist != null) { -199 registerSubcommand(method, sublist); -200 } -201 } -202 -203 if (rootCmdAlias != null) { -204 Set<String> cmdList = new HashSet<>(); -205 Collections.addAll(cmdList, ACFPatterns.PIPE.split(rootCmdAlias)); -206 cmdList.remove(cmd); -207 for (String cmdAlias : cmdList) { -208 register(cmdAlias, this); -209 } -210 } -211 -212 if (cmd != null) { -213 register(cmd, this); -214 } -215 for (Class<?> clazz : this.getClass().getDeclaredClasses()) { -216 if (BaseCommand.class.isAssignableFrom(clazz)) { -217 try { -218 BaseCommand subCommand = null; -219 Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); -220 for (Constructor<?> declaredConstructor : declaredConstructors) { -221 -222 declaredConstructor.setAccessible(true); -223 Parameter[] parameters = declaredConstructor.getParameters(); -224 if (parameters.length == 1) { -225 subCommand = (BaseCommand) declaredConstructor.newInstance(this); -226 } else { -227 manager.log(LogLevel.INFO, "Found unusable constructor: " + declaredConstructor.getName() + "(" + Stream.of(parameters).map(p -> p.getType().getSimpleName() + " " + p.getName()).collect(Collectors.joining("<c2>,</c2> ")) + ")"); -228 } -229 } -230 if (subCommand != null) { -231 subCommand.setParentCommand(this); -232 subCommand.onRegister(manager, cmd); -233 this.subCommands.putAll(subCommand.subCommands); -234 this.registeredCommands.putAll(subCommand.registeredCommands); -235 } else { -236 this.manager.log(LogLevel.ERROR, "Could not find a subcommand ctor for " + clazz.getName()); -237 } -238 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { -239 e.printStackTrace(); -240 } -241 } -242 } -243 -244 } -245 -246 private String getSubcommandValue(Method method) { -247 final Subcommand sub = method.getAnnotation(Subcommand.class); -248 if (sub == null) { -249 return null; -250 } -251 Class<?> clazz = method.getDeclaringClass(); -252 String parent = getParentSubcommand(clazz); -253 return parent == null || parent.isEmpty() ? sub.value() : parent + " " + sub.value(); -254 } -255 -256 private String getParentSubcommand(Class<?> clazz) { -257 List<String> subList = new ArrayList<>(); -258 while (clazz != null) { -259 Subcommand classSub = clazz.getAnnotation(Subcommand.class); -260 if (classSub != null) { -261 subList.add(classSub.value()); -262 } -263 clazz = clazz.getEnclosingClass(); -264 } -265 Collections.reverse(subList); -266 return ACFUtil.join(subList, " "); -267 } -268 -269 private void register(String name, BaseCommand cmd) { -270 String nameLower = name.toLowerCase(); -271 RootCommand rootCommand = manager.obtainRootCommand(nameLower); -272 rootCommand.addChild(cmd); -273 -274 this.registeredCommands.put(nameLower, rootCommand); -275 } -276 -277 private void registerSubcommand(Method method, String subCommand) { -278 subCommand = manager.getCommandReplacements().replace(subCommand.toLowerCase()); -279 final String[] subCommandParts = ACFPatterns.SPACE.split(subCommand); -280 // Must run getSubcommandPossibility BEFORE we rewrite it just after this. -281 Set<String> cmdList = getSubCommandPossibilityList(subCommandParts); -282 -283 // Strip pipes off for auto complete addition -284 for (int i = 0; i < subCommandParts.length; i++) { -285 String[] split = ACFPatterns.PIPE.split(subCommandParts[i]); -286 if (split.length == 0 || split[0].isEmpty()) { -287 throw new IllegalArgumentException("Invalid @Subcommand configuration for " + method.getName() + " - parts can not start with | or be empty"); -288 } -289 subCommandParts[i] = split[0]; -290 } -291 String prefSubCommand = ApacheCommonsLangUtil.join(subCommandParts, " "); -292 final CommandAlias cmdAlias = method.getAnnotation(CommandAlias.class); -293 -294 final String[] aliasNames = cmdAlias != null ? ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(cmdAlias.value().toLowerCase())) : null; -295 String cmdName = aliasNames != null ? aliasNames[0] : this.commandName + " "; -296 RegisteredCommand cmd = manager.createRegisteredCommand(this, cmdName, method, prefSubCommand); +140 this.commandName = cmd != null ? cmd : self.getSimpleName().toLowerCase(); +141 this.permission = annotations.getAnnotationValue(self, CommandPermission.class, Annotations.REPLACEMENTS); +142 this.description = this.commandName + " commands"; +143 this.usageMessage = "/" + this.commandName; +144 this.parentSubcommand = getParentSubcommand(self); +145 this.conditions = annotations.getAnnotationValue(self, Conditions.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY); +146 +147 registerSubcommands(); +148 +149 if (cmdAliases != null) { +150 Set<String> cmdList = new HashSet<>(); +151 Collections.addAll(cmdList, cmdAliases); +152 cmdList.remove(cmd); +153 for (String cmdAlias : cmdList) { +154 register(cmdAlias, this); +155 } +156 } +157 +158 if (cmd != null) { +159 register(cmd, this); +160 } +161 registerSubclasses(cmd); +162 +163 } +164 +165 private void registerSubclasses(String cmd) { +166 for (Class<?> clazz : this.getClass().getDeclaredClasses()) { +167 if (BaseCommand.class.isAssignableFrom(clazz)) { +168 try { +169 BaseCommand subCommand = null; +170 Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); +171 for (Constructor<?> declaredConstructor : declaredConstructors) { +172 +173 declaredConstructor.setAccessible(true); +174 Parameter[] parameters = declaredConstructor.getParameters(); +175 if (parameters.length == 1) { +176 subCommand = (BaseCommand) declaredConstructor.newInstance(this); +177 } else { +178 manager.log(LogLevel.INFO, "Found unusable constructor: " + declaredConstructor.getName() + "(" + Stream.of(parameters).map(p -> p.getType().getSimpleName() + " " + p.getName()).collect(Collectors.joining("<c2>,</c2> ")) + ")"); +179 } +180 } +181 if (subCommand != null) { +182 subCommand.setParentCommand(this); +183 subCommand.onRegister(manager, cmd); +184 this.subCommands.putAll(subCommand.subCommands); +185 this.registeredCommands.putAll(subCommand.registeredCommands); +186 } else { +187 this.manager.log(LogLevel.ERROR, "Could not find a subcommand ctor for " + clazz.getName()); +188 } +189 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { +190 this.manager.log(LogLevel.ERROR, "Error registering subclass", e); +191 } +192 } +193 } +194 } +195 +196 private void registerSubcommands() { +197 final Annotations annotations = manager.getAnnotations(); +198 boolean foundDefault = false; +199 boolean foundCatchUnknown = false; +200 boolean isParentEmpty = parentSubcommand.isEmpty(); +201 +202 for (Method method : this.getClass().getMethods()) { +203 method.setAccessible(true); +204 String sublist = null; +205 String sub = getSubcommandValue(method); +206 final boolean def = annotations.hasAnnotation(method, Default.class); +207 final String helpCommand = annotations.getAnnotationValue(method, HelpCommand.class, Annotations.NOTHING); +208 final String commandAliases = annotations.getAnnotationValue(method, CommandAlias.class, Annotations.NOTHING); +209 +210 if (!isParentEmpty && def) { +211 sub = parentSubcommand; +212 } +213 if (isParentEmpty && (def || (!foundDefault && helpCommand != null))) { +214 if (!foundDefault) { +215 if (def) { +216 this.subCommands.get(DEFAULT).clear(); +217 foundDefault = true; +218 } +219 registerSubcommand(method, DEFAULT); +220 } else { +221 ACFUtil.sneaky(new IllegalStateException("Multiple @Default/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); +222 } +223 } +224 +225 if (sub != null) { +226 sublist = sub; +227 } else if (commandAliases != null) { +228 sublist = commandAliases; +229 } else if (helpCommand != null) { +230 sublist = helpCommand; +231 } +232 +233 boolean preCommand = annotations.hasAnnotation(method, PreCommand.class); +234 boolean hasCatchUnknown = annotations.hasAnnotation(method, CatchUnknown.class) || +235 annotations.hasAnnotation(method, CatchAll.class) || +236 annotations.hasAnnotation(method, UnknownHandler.class); +237 +238 if (hasCatchUnknown || (!foundCatchUnknown && helpCommand != null)) { +239 if (!foundCatchUnknown) { +240 if (hasCatchUnknown) { +241 this.subCommands.get(CATCHUNKNOWN).clear(); +242 foundCatchUnknown = true; +243 } +244 registerSubcommand(method, CATCHUNKNOWN); +245 } else { +246 ACFUtil.sneaky(new IllegalStateException("Multiple @UnknownHandler/@HelpCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); +247 } +248 } else if (preCommand) { +249 if (this.preCommandHandler == null) { +250 this.preCommandHandler = method; +251 } else { +252 ACFUtil.sneaky(new IllegalStateException("Multiple @PreCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); +253 } +254 } +255 if (Objects.equals(method.getDeclaringClass(), this.getClass()) && sublist != null) { +256 registerSubcommand(method, sublist); +257 } +258 } +259 } +260 +261 private String getSubcommandValue(Method method) { +262 final String sub = manager.getAnnotations().getAnnotationValue(method, Subcommand.class, Annotations.NOTHING); +263 if (sub == null) { +264 return null; +265 } +266 Class<?> clazz = method.getDeclaringClass(); +267 String parent = getParentSubcommand(clazz); +268 return parent == null || parent.isEmpty() ? sub : parent + " " + sub; +269 } +270 +271 private String getParentSubcommand(Class<?> clazz) { +272 List<String> subList = new ArrayList<>(); +273 while (clazz != null) { +274 String sub = manager.getAnnotations().getAnnotationValue(clazz, Subcommand.class, Annotations.NOTHING); +275 if (sub != null) { +276 subList.add(sub); +277 } +278 clazz = clazz.getEnclosingClass(); +279 } +280 Collections.reverse(subList); +281 return ACFUtil.join(subList, " "); +282 } +283 +284 private void register(String name, BaseCommand cmd) { +285 String nameLower = name.toLowerCase(); +286 RootCommand rootCommand = manager.obtainRootCommand(nameLower); +287 rootCommand.addChild(cmd); +288 +289 this.registeredCommands.put(nameLower, rootCommand); +290 } +291 +292 private void registerSubcommand(Method method, String subCommand) { +293 subCommand = manager.getCommandReplacements().replace(subCommand.toLowerCase()); +294 final String[] subCommandParts = ACFPatterns.SPACE.split(subCommand); +295 // Must run getSubcommandPossibility BEFORE we rewrite it just after this. +296 Set<String> cmdList = getSubCommandPossibilityList(subCommandParts); 297 -298 for (String subcmd : cmdList) { -299 subCommands.put(subcmd, cmd); -300 } -301 cmd.addSubcommands(cmdList); -302 -303 if (aliasNames != null) { -304 for (String name : aliasNames) { -305 register(name, new ForwardingCommand(this, subCommandParts)); -306 } -307 } -308 } -309 -310 /** -311 * Takes a string like "foo|bar baz|qux" and generates a list of -312 * - foo baz -313 * - foo qux -314 * - bar baz -315 * - bar qux -316 * -317 * For every possible sub command combination -318 * -319 * @param subCommandParts -320 * @return List of all sub command possibilities -321 */ -322 private static Set<String> getSubCommandPossibilityList(String[] subCommandParts) { -323 int i = 0; -324 Set<String> current = null; -325 while (true) { -326 Set<String> newList = new HashSet<>(); -327 -328 if (i < subCommandParts.length) { -329 for (String s1 : ACFPatterns.PIPE.split(subCommandParts[i])) { -330 if (current != null) { -331 newList.addAll(current.stream().map(s -> s + " " + s1).collect(Collectors.toList())); -332 } else { -333 newList.add(s1); -334 } -335 } -336 } -337 -338 if (i + 1 < subCommandParts.length) { -339 current = newList; -340 i = i + 1; -341 continue; -342 } -343 -344 return newList; -345 } -346 } -347 -348 public void execute(CommandIssuer issuer, String commandLabel, String[] args) { -349 commandLabel = commandLabel.toLowerCase(); -350 try { -351 CommandOperationContext commandContext = preCommandOperation(issuer, commandLabel, args, false); -352 -353 if (args.length > 0) { -354 CommandSearch cmd = findSubCommand(args); -355 if (cmd != null) { -356 execSubcommand = cmd.getCheckSub(); -357 final String[] execargs = Arrays.copyOfRange(args, cmd.argIndex, args.length); -358 executeCommand(commandContext, issuer, execargs, cmd.cmd); -359 return; -360 } -361 } -362 -363 if (subCommands.get(DEFAULT) != null && args.length == 0) { -364 executeSubcommand(commandContext, DEFAULT, issuer, args); -365 } else if (subCommands.get(CATCHUNKNOWN) != null) { -366 if (!executeSubcommand(commandContext, CATCHUNKNOWN, issuer, args)) { -367 help(issuer, args); -368 } -369 } else if (subCommands.get(DEFAULT) != null) { -370 executeSubcommand(commandContext, DEFAULT, issuer, args); -371 } -372 -373 } finally { -374 postCommandOperation(); -375 } -376 } -377 -378 RegisteredCommand<?> getRegisteredCommand(String[] args) { -379 final CommandSearch cmd = findSubCommand(args); -380 return cmd != null ? cmd.cmd : null; -381 } -382 -383 private void postCommandOperation() { -384 CommandManager.commandOperationContext.get().pop(); -385 execSubcommand = null; -386 execLabel = null; -387 origArgs = new String[]{}; -388 } -389 -390 private CommandOperationContext preCommandOperation(CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) { -391 Stack<CommandOperationContext> contexts = CommandManager.commandOperationContext.get(); -392 CommandOperationContext context = this.manager.createCommandOperationContext(this, issuer, commandLabel, args, isAsync); -393 contexts.push(context); -394 lastCommandOperationContext = context; -395 execSubcommand = null; -396 execLabel = commandLabel; -397 origArgs = args; -398 return context; -399 } -400 -401 public CommandIssuer getCurrentCommandIssuer() { -402 return CommandManager.getCurrentCommandIssuer(); -403 } -404 public CommandManager getCurrentCommandManager() { -405 return CommandManager.getCurrentCommandManager(); -406 } -407 -408 private CommandSearch findSubCommand(String[] args) { -409 return findSubCommand(args, false); -410 } -411 private CommandSearch findSubCommand(String[] args, boolean completion) { -412 for (int i = args.length; i >= 0; i--) { -413 String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase(); -414 Set<RegisteredCommand> cmds = subCommands.get(checkSub); -415 -416 final int extraArgs = args.length - i; -417 if (!cmds.isEmpty()) { -418 RegisteredCommand cmd = null; -419 if (cmds.size() == 1) { -420 cmd = Iterables.getOnlyElement(cmds); -421 } else { -422 Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> { -423 int required = c.requiredResolvers; -424 int optional = c.optionalResolvers; -425 return extraArgs <= required + optional && (completion || extraArgs >= required); -426 }).sorted((c1, c2) -> { -427 int a = c1.requiredResolvers + c1.optionalResolvers; -428 int b = c2.requiredResolvers + c2.optionalResolvers; +298 // Strip pipes off for auto complete addition +299 for (int i = 0; i < subCommandParts.length; i++) { +300 String[] split = ACFPatterns.PIPE.split(subCommandParts[i]); +301 if (split.length == 0 || split[0].isEmpty()) { +302 throw new IllegalArgumentException("Invalid @Subcommand configuration for " + method.getName() + " - parts can not start with | or be empty"); +303 } +304 subCommandParts[i] = split[0]; +305 } +306 String prefSubCommand = ApacheCommonsLangUtil.join(subCommandParts, " "); +307 final String[] aliasNames = manager.getAnnotations().getAnnotationValues(method, CommandAlias.class, Annotations.REPLACEMENTS | Annotations.LOWERCASE); +308 +309 String cmdName = aliasNames != null ? aliasNames[0] : this.commandName + " "; +310 RegisteredCommand cmd = manager.createRegisteredCommand(this, cmdName, method, prefSubCommand); +311 +312 for (String subcmd : cmdList) { +313 subCommands.put(subcmd, cmd); +314 } +315 cmd.addSubcommands(cmdList); +316 +317 if (aliasNames != null) { +318 for (String name : aliasNames) { +319 register(name, new ForwardingCommand(this, subCommandParts)); +320 } +321 } +322 } +323 +324 /** +325 * Takes a string like "foo|bar baz|qux" and generates a list of +326 * - foo baz +327 * - foo qux +328 * - bar baz +329 * - bar qux +330 * +331 * For every possible sub command combination +332 * +333 * @param subCommandParts +334 * @return List of all sub command possibilities +335 */ +336 private static Set<String> getSubCommandPossibilityList(String[] subCommandParts) { +337 int i = 0; +338 Set<String> current = null; +339 while (true) { +340 Set<String> newList = new HashSet<>(); +341 +342 if (i < subCommandParts.length) { +343 for (String s1 : ACFPatterns.PIPE.split(subCommandParts[i])) { +344 if (current != null) { +345 newList.addAll(current.stream().map(s -> s + " " + s1).collect(Collectors.toList())); +346 } else { +347 newList.add(s1); +348 } +349 } +350 } +351 +352 if (i + 1 < subCommandParts.length) { +353 current = newList; +354 i = i + 1; +355 continue; +356 } +357 +358 return newList; +359 } +360 } +361 +362 public void execute(CommandIssuer issuer, String commandLabel, String[] args) { +363 commandLabel = commandLabel.toLowerCase(); +364 try { +365 CommandOperationContext commandContext = preCommandOperation(issuer, commandLabel, args, false); +366 +367 if (args.length > 0) { +368 CommandSearch cmd = findSubCommand(args); +369 if (cmd != null) { +370 execSubcommand = cmd.getCheckSub(); +371 final String[] execargs = Arrays.copyOfRange(args, cmd.argIndex, args.length); +372 executeCommand(commandContext, issuer, execargs, cmd.cmd); +373 return; +374 } +375 } +376 +377 if (subCommands.get(DEFAULT) != null && args.length == 0) { +378 executeSubcommand(commandContext, DEFAULT, issuer, args); +379 } else if (subCommands.get(CATCHUNKNOWN) != null) { +380 if (!executeSubcommand(commandContext, CATCHUNKNOWN, issuer, args)) { +381 help(issuer, args); +382 } +383 } else if (subCommands.get(DEFAULT) != null) { +384 executeSubcommand(commandContext, DEFAULT, issuer, args); +385 } +386 +387 } finally { +388 postCommandOperation(); +389 } +390 } +391 +392 RegisteredCommand<?> getRegisteredCommand(String[] args) { +393 final CommandSearch cmd = findSubCommand(args); +394 return cmd != null ? cmd.cmd : null; +395 } +396 +397 private void postCommandOperation() { +398 CommandManager.commandOperationContext.get().pop(); +399 execSubcommand = null; +400 execLabel = null; +401 origArgs = new String[]{}; +402 } +403 +404 private CommandOperationContext preCommandOperation(CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) { +405 Stack<CommandOperationContext> contexts = CommandManager.commandOperationContext.get(); +406 CommandOperationContext context = this.manager.createCommandOperationContext(this, issuer, commandLabel, args, isAsync); +407 contexts.push(context); +408 lastCommandOperationContext = context; +409 execSubcommand = null; +410 execLabel = commandLabel; +411 origArgs = args; +412 return context; +413 } +414 +415 public CommandIssuer getCurrentCommandIssuer() { +416 return CommandManager.getCurrentCommandIssuer(); +417 } +418 public CommandManager getCurrentCommandManager() { +419 return CommandManager.getCurrentCommandManager(); +420 } +421 +422 private CommandSearch findSubCommand(String[] args) { +423 return findSubCommand(args, false); +424 } +425 private CommandSearch findSubCommand(String[] args, boolean completion) { +426 for (int i = args.length; i >= 0; i--) { +427 String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase(); +428 Set<RegisteredCommand> cmds = subCommands.get(checkSub); 429 -430 if (a == b) { -431 return 0; -432 } -433 return a < b ? 1 : -1; -434 }).findFirst(); -435 if (optCmd.isPresent()) { -436 cmd = optCmd.get(); -437 } -438 } -439 if (cmd != null) { -440 return new CommandSearch(cmd, i, checkSub); -441 } -442 } -443 } -444 return null; -445 } -446 -447 private void executeCommand(CommandOperationContext commandOperationContext, -448 CommandIssuer issuer, String[] args, RegisteredCommand cmd) { -449 if (cmd.hasPermission(issuer)) { -450 commandOperationContext.setRegisteredCommand(cmd); -451 if (checkPrecommand(commandOperationContext, cmd, issuer, args)) { -452 return; -453 } -454 List<String> sargs = Lists.newArrayList(args); -455 cmd.invoke(issuer, sargs, commandOperationContext); -456 } else { -457 issuer.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED); -458 } +430 final int extraArgs = args.length - i; +431 if (!cmds.isEmpty()) { +432 RegisteredCommand cmd = null; +433 if (cmds.size() == 1) { +434 cmd = Iterables.getOnlyElement(cmds); +435 } else { +436 Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> { +437 int required = c.requiredResolvers; +438 int optional = c.optionalResolvers; +439 return extraArgs <= required + optional && (completion || extraArgs >= required); +440 }).sorted((c1, c2) -> { +441 int a = c1.requiredResolvers + c1.optionalResolvers; +442 int b = c2.requiredResolvers + c2.optionalResolvers; +443 +444 if (a == b) { +445 return 0; +446 } +447 return a < b ? 1 : -1; +448 }).findFirst(); +449 if (optCmd.isPresent()) { +450 cmd = optCmd.get(); +451 } +452 } +453 if (cmd != null) { +454 return new CommandSearch(cmd, i, checkSub); +455 } +456 } +457 } +458 return null; 459 } 460 -461 public boolean canExecute(CommandIssuer issuer, RegisteredCommand<?> cmd) { -462 return true; -463 } -464 -465 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args) { -466 return tabComplete(issuer, commandLabel, args, false); -467 } -468 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) -469 throws IllegalArgumentException { -470 -471 commandLabel = commandLabel.toLowerCase(); -472 if (args.length == 0) { -473 args = new String[]{""}; -474 } -475 try { -476 CommandOperationContext commandOperationContext = preCommandOperation(issuer, commandLabel, args, isAsync); -477 -478 final CommandSearch search = findSubCommand(args, true); -479 -480 -481 final List<String> cmds = new ArrayList<>(); -482 -483 if (search != null) { -484 cmds.addAll(completeCommand(issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel, isAsync)); -485 } else if (subCommands.get(CATCHUNKNOWN).size() == 1) { -486 cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(CATCHUNKNOWN)), args, commandLabel, isAsync)); -487 } else if (subCommands.get(DEFAULT).size() == 1) { -488 cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(DEFAULT)), args, commandLabel, isAsync)); -489 } -490 -491 return filterTabComplete(args[args.length - 1], cmds); -492 } finally { -493 postCommandOperation(); -494 } -495 } +461 private void executeCommand(CommandOperationContext commandOperationContext, +462 CommandIssuer issuer, String[] args, RegisteredCommand cmd) { +463 if (cmd.hasPermission(issuer)) { +464 commandOperationContext.setRegisteredCommand(cmd); +465 if (checkPrecommand(commandOperationContext, cmd, issuer, args)) { +466 return; +467 } +468 List<String> sargs = Lists.newArrayList(args); +469 cmd.invoke(issuer, sargs, commandOperationContext); +470 } else { +471 issuer.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED); +472 } +473 } +474 +475 public boolean canExecute(CommandIssuer issuer, RegisteredCommand<?> cmd) { +476 return true; +477 } +478 +479 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args) { +480 return tabComplete(issuer, commandLabel, args, false); +481 } +482 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) +483 throws IllegalArgumentException { +484 +485 commandLabel = commandLabel.toLowerCase(); +486 if (args.length == 0) { +487 args = new String[]{""}; +488 } +489 try { +490 CommandOperationContext commandOperationContext = preCommandOperation(issuer, commandLabel, args, isAsync); +491 +492 final CommandSearch search = findSubCommand(args, true); +493 +494 +495 final List<String> cmds = new ArrayList<>(); 496 -497 List<String> getCommandsForCompletion(CommandIssuer issuer, String[] args) { -498 final Set<String> cmds = new HashSet<>(); -499 final int cmdIndex = Math.max(0, args.length - 1); -500 String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); -501 for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) { -502 final String key = entry.getKey(); -503 if (key.startsWith(argString) && !CATCHUNKNOWN.equals(key) && !DEFAULT.equals(key)) { -504 final RegisteredCommand value = entry.getValue(); -505 if (!value.hasPermission(issuer)) { -506 continue; -507 } -508 -509 String[] split = ACFPatterns.SPACE.split(value.prefSubCommand); -510 cmds.add(split[cmdIndex]); -511 } -512 } -513 return new ArrayList<>(cmds); -514 } -515 -516 private List<String> completeCommand(CommandIssuer issuer, RegisteredCommand cmd, String[] args, String commandLabel, boolean isAsync) { -517 if (!cmd.hasPermission(issuer) || args.length > cmd.requiredResolvers + cmd.optionalResolvers || args.length == 0 -518 || cmd.complete == null) { -519 return ImmutableList.of(); -520 } -521 -522 String[] completions = ACFPatterns.SPACE.split(cmd.complete); -523 -524 List<String> cmds = manager.getCommandCompletions().of(cmd, issuer, completions, args, isAsync); -525 return filterTabComplete(args[args.length-1], cmds); -526 } -527 -528 private static List<String> filterTabComplete(String arg, List<String> cmds) { -529 return cmds.stream() -530 .distinct() -531 .filter(cmd -> cmd != null && (arg.isEmpty() || ApacheCommonsLangUtil.startsWithIgnoreCase(cmd, arg))) -532 .collect(Collectors.toList()); -533 } -534 -535 RegisteredCommand getSubcommand(String subcommand) { -536 return getSubcommand(subcommand, false); -537 } -538 -539 RegisteredCommand getSubcommand(String subcommand, boolean requireOne) { -540 final Set<RegisteredCommand> commands = subCommands.get(subcommand); -541 if (!commands.isEmpty() && (!requireOne || commands.size() == 1)) { -542 return commands.iterator().next(); -543 } -544 return null; -545 } -546 -547 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { -548 final RegisteredCommand cmd = this.getSubcommand(subcommand); -549 if (cmd != null) { -550 executeCommand(commandContext, issuer, args, cmd); -551 return true; -552 } -553 -554 return false; -555 } -556 -557 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { -558 Method pre = this.preCommandHandler; -559 if (pre != null) { -560 try { -561 Class<?>[] types = pre.getParameterTypes(); -562 Object[] parameters = new Object[pre.getParameterCount()]; -563 for (int i = 0; i < parameters.length; i++) { -564 Class<?> type = types[i]; -565 Object issuerObject = issuer.getIssuer(); -566 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { -567 parameters[i] = issuerObject; -568 } else if (CommandIssuer.class.isAssignableFrom(type)) { -569 parameters[i] = issuer; -570 } else if (RegisteredCommand.class.isAssignableFrom(type)) { -571 parameters[i] = cmd; -572 } else if (String[].class.isAssignableFrom((type))) { -573 parameters[i] = args; -574 } else { -575 parameters[i] = null; -576 } -577 } -578 -579 return (boolean) pre.invoke(this, parameters); -580 } catch (IllegalAccessException | InvocationTargetException e) { -581 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); -582 } -583 } -584 return false; -585 } -586 -587 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -588 public CommandHelp getCommandHelp() { -589 return manager.generateCommandHelp(); -590 } -591 -592 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -593 public void showCommandHelp() { -594 getCommandHelp().showHelp(); -595 } -596 -597 public void help(Object issuer, String[] args) { -598 help(manager.getCommandIssuer(issuer), args); +497 if (search != null) { +498 cmds.addAll(completeCommand(issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel, isAsync)); +499 } else if (subCommands.get(CATCHUNKNOWN).size() == 1) { +500 cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(CATCHUNKNOWN)), args, commandLabel, isAsync)); +501 } else if (subCommands.get(DEFAULT).size() == 1) { +502 cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(DEFAULT)), args, commandLabel, isAsync)); +503 } +504 +505 return filterTabComplete(args[args.length - 1], cmds); +506 } finally { +507 postCommandOperation(); +508 } +509 } +510 +511 List<String> getCommandsForCompletion(CommandIssuer issuer, String[] args) { +512 final Set<String> cmds = new HashSet<>(); +513 final int cmdIndex = Math.max(0, args.length - 1); +514 String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); +515 for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) { +516 final String key = entry.getKey(); +517 if (key.startsWith(argString) && !CATCHUNKNOWN.equals(key) && !DEFAULT.equals(key)) { +518 final RegisteredCommand value = entry.getValue(); +519 if (!value.hasPermission(issuer)) { +520 continue; +521 } +522 +523 String[] split = ACFPatterns.SPACE.split(value.prefSubCommand); +524 cmds.add(split[cmdIndex]); +525 } +526 } +527 return new ArrayList<>(cmds); +528 } +529 +530 private List<String> completeCommand(CommandIssuer issuer, RegisteredCommand cmd, String[] args, String commandLabel, boolean isAsync) { +531 if (!cmd.hasPermission(issuer) || args.length > cmd.requiredResolvers + cmd.optionalResolvers || args.length == 0 +532 || cmd.complete == null) { +533 return ImmutableList.of(); +534 } +535 +536 String[] completions = ACFPatterns.SPACE.split(cmd.complete); +537 +538 List<String> cmds = manager.getCommandCompletions().of(cmd, issuer, completions, args, isAsync); +539 return filterTabComplete(args[args.length-1], cmds); +540 } +541 +542 private static List<String> filterTabComplete(String arg, List<String> cmds) { +543 return cmds.stream() +544 .distinct() +545 .filter(cmd -> cmd != null && (arg.isEmpty() || ApacheCommonsLangUtil.startsWithIgnoreCase(cmd, arg))) +546 .collect(Collectors.toList()); +547 } +548 +549 RegisteredCommand getSubcommand(String subcommand) { +550 return getSubcommand(subcommand, false); +551 } +552 +553 RegisteredCommand getSubcommand(String subcommand, boolean requireOne) { +554 final Set<RegisteredCommand> commands = subCommands.get(subcommand); +555 if (!commands.isEmpty() && (!requireOne || commands.size() == 1)) { +556 return commands.iterator().next(); +557 } +558 return null; +559 } +560 +561 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { +562 final RegisteredCommand cmd = this.getSubcommand(subcommand); +563 if (cmd != null) { +564 executeCommand(commandContext, issuer, args, cmd); +565 return true; +566 } +567 +568 return false; +569 } +570 +571 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { +572 Method pre = this.preCommandHandler; +573 if (pre != null) { +574 try { +575 Class<?>[] types = pre.getParameterTypes(); +576 Object[] parameters = new Object[pre.getParameterCount()]; +577 for (int i = 0; i < parameters.length; i++) { +578 Class<?> type = types[i]; +579 Object issuerObject = issuer.getIssuer(); +580 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { +581 parameters[i] = issuerObject; +582 } else if (CommandIssuer.class.isAssignableFrom(type)) { +583 parameters[i] = issuer; +584 } else if (RegisteredCommand.class.isAssignableFrom(type)) { +585 parameters[i] = cmd; +586 } else if (String[].class.isAssignableFrom((type))) { +587 parameters[i] = args; +588 } else { +589 parameters[i] = null; +590 } +591 } +592 +593 return (boolean) pre.invoke(this, parameters); +594 } catch (IllegalAccessException | InvocationTargetException e) { +595 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); +596 } +597 } +598 return false; 599 } -600 public void help(CommandIssuer issuer, String[] args) { -601 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); -602 } -603 public void doHelp(Object issuer, String... args) { -604 doHelp(manager.getCommandIssuer(issuer), args); -605 } -606 public void doHelp(CommandIssuer issuer, String... args) { -607 help(issuer, args); -608 } -609 -610 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { -611 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, -612 "{command}", "/" + cmd.command, -613 "{syntax}", cmd.syntaxText -614 ); -615 } -616 -617 public boolean hasPermission(Object issuer) { -618 return hasPermission(manager.getCommandIssuer(issuer)); +600 +601 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +602 public CommandHelp getCommandHelp() { +603 return manager.generateCommandHelp(); +604 } +605 +606 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +607 public void showCommandHelp() { +608 getCommandHelp().showHelp(); +609 } +610 +611 public void help(Object issuer, String[] args) { +612 help(manager.getCommandIssuer(issuer), args); +613 } +614 public void help(CommandIssuer issuer, String[] args) { +615 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); +616 } +617 public void doHelp(Object issuer, String... args) { +618 doHelp(manager.getCommandIssuer(issuer), args); 619 } -620 -621 public boolean hasPermission(CommandIssuer issuer) { -622 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); -623 } -624 -625 -626 public Set<String> getRequiredPermissions() { -627 if (this.permission == null || this.permission.isEmpty()) { -628 return ImmutableSet.of(); -629 } -630 return Sets.newHashSet(ACFPatterns.COMMA.split(this.permission)); -631 } -632 -633 public boolean requiresPermission(String permission) { -634 return getRequiredPermissions().contains(permission) || this.parentCommand != null && parentCommand.requiresPermission(permission); -635 } -636 -637 public String getName() { -638 return commandName; -639 } -640 -641 public ExceptionHandler getExceptionHandler() { -642 return exceptionHandler; -643 } -644 -645 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { -646 this.exceptionHandler = exceptionHandler; -647 return this; -648 } -649 -650 public RegisteredCommand getDefaultRegisteredCommand() { -651 return this.getSubcommand(DEFAULT); -652 } -653 -654 public String setContextFlags(Class<?> cls, String flags) { -655 return this.contextFlags.put(cls, flags); -656 } -657 -658 public String getContextFlags(Class<?> cls) { -659 return this.contextFlags.get(cls); -660 } -661 -662 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; +620 public void doHelp(CommandIssuer issuer, String... args) { +621 help(issuer, args); +622 } +623 +624 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { +625 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, +626 "{command}", "/" + cmd.command, +627 "{syntax}", cmd.syntaxText +628 ); +629 } +630 +631 public boolean hasPermission(Object issuer) { +632 return hasPermission(manager.getCommandIssuer(issuer)); +633 } +634 +635 public boolean hasPermission(CommandIssuer issuer) { +636 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); +637 } +638 +639 +640 public Set<String> getRequiredPermissions() { +641 if (this.permission == null || this.permission.isEmpty()) { +642 return ImmutableSet.of(); +643 } +644 return Sets.newHashSet(ACFPatterns.COMMA.split(this.permission)); +645 } +646 +647 public boolean requiresPermission(String permission) { +648 return getRequiredPermissions().contains(permission) || this.parentCommand != null && parentCommand.requiresPermission(permission); +649 } +650 +651 public String getName() { +652 return commandName; +653 } +654 +655 public ExceptionHandler getExceptionHandler() { +656 return exceptionHandler; +657 } +658 +659 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { +660 this.exceptionHandler = exceptionHandler; +661 return this; +662 } 663 -664 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { -665 this.cmd = cmd; -666 this.argIndex = argIndex; -667 this.checkSub = checkSub; -668 } -669 -670 String getCheckSub() { -671 return this.checkSub; -672 } -673 -674 @Override -675 public boolean equals(Object o) { -676 if (this == o) return true; -677 if (o == null || getClass() != o.getClass()) return false; -678 CommandSearch that = (CommandSearch) o; -679 return argIndex == that.argIndex && -680 Objects.equals(cmd, that.cmd) && -681 Objects.equals(checkSub, that.checkSub); +664 public RegisteredCommand getDefaultRegisteredCommand() { +665 return this.getSubcommand(DEFAULT); +666 } +667 +668 public String setContextFlags(Class<?> cls, String flags) { +669 return this.contextFlags.put(cls, flags); +670 } +671 +672 public String getContextFlags(Class<?> cls) { +673 return this.contextFlags.get(cls); +674 } +675 +676 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; +677 +678 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { +679 this.cmd = cmd; +680 this.argIndex = argIndex; +681 this.checkSub = checkSub; 682 } 683 -684 @Override -685 public int hashCode() { -686 return Objects.hash(cmd, argIndex, checkSub); -687 } -688 } -689} +684 String getCheckSub() { +685 return this.checkSub; +686 } +687 +688 @Override +689 public boolean equals(Object o) { +690 if (this == o) return true; +691 if (o == null || getClass() != o.getClass()) return false; +692 CommandSearch that = (CommandSearch) o; +693 return argIndex == that.argIndex && +694 Objects.equals(cmd, that.cmd) && +695 Objects.equals(checkSub, that.checkSub); +696 } +697 +698 @Override +699 public int hashCode() { +700 return Objects.hash(cmd, argIndex, checkSub); +701 } +702 } +703} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandConditions.Condition.html b/docs/acf-core/src-html/co/aikar/commands/CommandConditions.Condition.html index 289a3b0c..6ff13c3a 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandConditions.Condition.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandConditions.Condition.html @@ -62,96 +62,90 @@ 054 return this.paramConditions.put(clazz, id.toLowerCase(), handler); 055 } 056 -057 void validateConditions(CEC cec, Object value) throws InvalidCommandArgument { -058 Conditions conditions = cec.getParam().getAnnotation(Conditions.class); -059 validateConditions(conditions, cec, value); -060 } -061 -062 void validateConditions(CommandOperationContext context) throws InvalidCommandArgument { -063 RegisteredCommand cmd = context.getRegisteredCommand(); -064 Conditions conditions = cmd.method.getAnnotation(Conditions.class); -065 validateConditions(conditions, context); -066 validateConditions(cmd.scope, context); -067 } -068 -069 -070 private void validateConditions(BaseCommand scope, CommandOperationContext operationContext) throws InvalidCommandArgument { -071 Conditions conditions = scope.getClass().getAnnotation(Conditions.class); -072 validateConditions(conditions, operationContext); -073 -074 if (scope.parentCommand != null) { -075 validateConditions(scope.parentCommand, operationContext); -076 } -077 } -078 -079 private void validateConditions(Conditions condAnno, CommandOperationContext context) throws InvalidCommandArgument { -080 if (condAnno == null) { -081 return; -082 } -083 -084 String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); -085 CommandIssuer issuer = context.getCommandIssuer(); -086 for (String cond : ACFPatterns.PIPE.split(conditions)) { -087 String[] split = ACFPatterns.COLON.split(cond, 2); -088 String id = split[0].toLowerCase(); -089 Condition<I> condition = this.conditions.get(id); -090 if (condition == null) { -091 RegisteredCommand cmd = context.getRegisteredCommand(); -092 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName()); -093 continue; -094 } -095 -096 String config = split.length == 2 ? split[1] : null; -097 //noinspection unchecked -098 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); -099 //noinspection unchecked -100 condition.validateCondition(conditionContext); +057 void validateConditions(CommandOperationContext context) throws InvalidCommandArgument { +058 RegisteredCommand cmd = context.getRegisteredCommand(); +059 +060 validateConditions(cmd.conditions, context); +061 validateConditions(cmd.scope, context); +062 } +063 +064 private void validateConditions(BaseCommand scope, CommandOperationContext operationContext) throws InvalidCommandArgument { +065 validateConditions(scope.conditions, operationContext); +066 +067 if (scope.parentCommand != null) { +068 validateConditions(scope.parentCommand, operationContext); +069 } +070 } +071 +072 private void validateConditions(String conditions, CommandOperationContext context) throws InvalidCommandArgument { +073 if (conditions == null) { +074 return; +075 } +076 +077 conditions = this.manager.getCommandReplacements().replace(conditions); +078 CommandIssuer issuer = context.getCommandIssuer(); +079 for (String cond : ACFPatterns.PIPE.split(conditions)) { +080 String[] split = ACFPatterns.COLON.split(cond, 2); +081 String id = split[0].toLowerCase(); +082 Condition<I> condition = this.conditions.get(id); +083 if (condition == null) { +084 RegisteredCommand cmd = context.getRegisteredCommand(); +085 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName()); +086 continue; +087 } +088 +089 String config = split.length == 2 ? split[1] : null; +090 //noinspection unchecked +091 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); +092 //noinspection unchecked +093 condition.validateCondition(conditionContext); +094 } +095 } +096 +097 void validateConditions(CEC execContext, Object value) throws InvalidCommandArgument { +098 String conditions = execContext.getCommandParameter().getConditions(); +099 if (conditions == null) { +100 return; 101 } -102 } -103 -104 private void validateConditions(Conditions condAnno, CEC execContext, Object value) throws InvalidCommandArgument { -105 if (condAnno == null) { -106 return; -107 } -108 String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); -109 I issuer = execContext.getIssuer(); -110 for (String cond : ACFPatterns.PIPE.split(conditions)) { -111 String[] split = ACFPatterns.COLON.split(cond, 2); -112 ParameterCondition condition; -113 Class<?> cls = execContext.getParam().getType(); -114 String id = split[0].toLowerCase(); -115 do { -116 condition = this.paramConditions.get(cls, id); -117 if (condition == null && cls.getSuperclass() != null && cls.getSuperclass() != Object.class) { -118 cls = cls.getSuperclass(); -119 } else { -120 break; -121 } -122 } while (cls != null); -123 -124 -125 if (condition == null) { -126 RegisteredCommand cmd = execContext.getCmd(); -127 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName() + "::" +execContext.getParam().getName()); -128 continue; -129 } -130 String config = split.length == 2 ? split[1] : null; -131 //noinspection unchecked -132 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); -133 -134 //noinspection unchecked -135 condition.validateCondition(conditionContext, execContext, value); -136 } -137 } -138 -139 public interface Condition <I extends CommandIssuer> { -140 void validateCondition(ConditionContext<I> context) throws InvalidCommandArgument; -141 } -142 -143 public interface ParameterCondition <P, CEC extends CommandExecutionContext, I extends CommandIssuer> { -144 void validateCondition(ConditionContext<I> context, CEC execContext, P value) throws InvalidCommandArgument; -145 } -146} +102 conditions = this.manager.getCommandReplacements().replace(conditions); +103 I issuer = execContext.getIssuer(); +104 for (String cond : ACFPatterns.PIPE.split(conditions)) { +105 String[] split = ACFPatterns.COLON.split(cond, 2); +106 ParameterCondition condition; +107 Class<?> cls = execContext.getParam().getType(); +108 String id = split[0].toLowerCase(); +109 do { +110 condition = this.paramConditions.get(cls, id); +111 if (condition == null && cls.getSuperclass() != null && cls.getSuperclass() != Object.class) { +112 cls = cls.getSuperclass(); +113 } else { +114 break; +115 } +116 } while (cls != null); +117 +118 +119 if (condition == null) { +120 RegisteredCommand cmd = execContext.getCmd(); +121 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName() + "::" +execContext.getParam().getName()); +122 continue; +123 } +124 String config = split.length == 2 ? split[1] : null; +125 //noinspection unchecked +126 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); +127 +128 //noinspection unchecked +129 condition.validateCondition(conditionContext, execContext, value); +130 } +131 } +132 +133 public interface Condition <I extends CommandIssuer> { +134 void validateCondition(ConditionContext<I> context) throws InvalidCommandArgument; +135 } +136 +137 public interface ParameterCondition <P, CEC extends CommandExecutionContext, I extends CommandIssuer> { +138 void validateCondition(ConditionContext<I> context, CEC execContext, P value) throws InvalidCommandArgument; +139 } +140} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandConditions.ParameterCondition.html b/docs/acf-core/src-html/co/aikar/commands/CommandConditions.ParameterCondition.html index 289a3b0c..6ff13c3a 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandConditions.ParameterCondition.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandConditions.ParameterCondition.html @@ -62,96 +62,90 @@ 054 return this.paramConditions.put(clazz, id.toLowerCase(), handler); 055 } 056 -057 void validateConditions(CEC cec, Object value) throws InvalidCommandArgument { -058 Conditions conditions = cec.getParam().getAnnotation(Conditions.class); -059 validateConditions(conditions, cec, value); -060 } -061 -062 void validateConditions(CommandOperationContext context) throws InvalidCommandArgument { -063 RegisteredCommand cmd = context.getRegisteredCommand(); -064 Conditions conditions = cmd.method.getAnnotation(Conditions.class); -065 validateConditions(conditions, context); -066 validateConditions(cmd.scope, context); -067 } -068 -069 -070 private void validateConditions(BaseCommand scope, CommandOperationContext operationContext) throws InvalidCommandArgument { -071 Conditions conditions = scope.getClass().getAnnotation(Conditions.class); -072 validateConditions(conditions, operationContext); -073 -074 if (scope.parentCommand != null) { -075 validateConditions(scope.parentCommand, operationContext); -076 } -077 } -078 -079 private void validateConditions(Conditions condAnno, CommandOperationContext context) throws InvalidCommandArgument { -080 if (condAnno == null) { -081 return; -082 } -083 -084 String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); -085 CommandIssuer issuer = context.getCommandIssuer(); -086 for (String cond : ACFPatterns.PIPE.split(conditions)) { -087 String[] split = ACFPatterns.COLON.split(cond, 2); -088 String id = split[0].toLowerCase(); -089 Condition<I> condition = this.conditions.get(id); -090 if (condition == null) { -091 RegisteredCommand cmd = context.getRegisteredCommand(); -092 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName()); -093 continue; -094 } -095 -096 String config = split.length == 2 ? split[1] : null; -097 //noinspection unchecked -098 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); -099 //noinspection unchecked -100 condition.validateCondition(conditionContext); +057 void validateConditions(CommandOperationContext context) throws InvalidCommandArgument { +058 RegisteredCommand cmd = context.getRegisteredCommand(); +059 +060 validateConditions(cmd.conditions, context); +061 validateConditions(cmd.scope, context); +062 } +063 +064 private void validateConditions(BaseCommand scope, CommandOperationContext operationContext) throws InvalidCommandArgument { +065 validateConditions(scope.conditions, operationContext); +066 +067 if (scope.parentCommand != null) { +068 validateConditions(scope.parentCommand, operationContext); +069 } +070 } +071 +072 private void validateConditions(String conditions, CommandOperationContext context) throws InvalidCommandArgument { +073 if (conditions == null) { +074 return; +075 } +076 +077 conditions = this.manager.getCommandReplacements().replace(conditions); +078 CommandIssuer issuer = context.getCommandIssuer(); +079 for (String cond : ACFPatterns.PIPE.split(conditions)) { +080 String[] split = ACFPatterns.COLON.split(cond, 2); +081 String id = split[0].toLowerCase(); +082 Condition<I> condition = this.conditions.get(id); +083 if (condition == null) { +084 RegisteredCommand cmd = context.getRegisteredCommand(); +085 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName()); +086 continue; +087 } +088 +089 String config = split.length == 2 ? split[1] : null; +090 //noinspection unchecked +091 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); +092 //noinspection unchecked +093 condition.validateCondition(conditionContext); +094 } +095 } +096 +097 void validateConditions(CEC execContext, Object value) throws InvalidCommandArgument { +098 String conditions = execContext.getCommandParameter().getConditions(); +099 if (conditions == null) { +100 return; 101 } -102 } -103 -104 private void validateConditions(Conditions condAnno, CEC execContext, Object value) throws InvalidCommandArgument { -105 if (condAnno == null) { -106 return; -107 } -108 String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); -109 I issuer = execContext.getIssuer(); -110 for (String cond : ACFPatterns.PIPE.split(conditions)) { -111 String[] split = ACFPatterns.COLON.split(cond, 2); -112 ParameterCondition condition; -113 Class<?> cls = execContext.getParam().getType(); -114 String id = split[0].toLowerCase(); -115 do { -116 condition = this.paramConditions.get(cls, id); -117 if (condition == null && cls.getSuperclass() != null && cls.getSuperclass() != Object.class) { -118 cls = cls.getSuperclass(); -119 } else { -120 break; -121 } -122 } while (cls != null); -123 -124 -125 if (condition == null) { -126 RegisteredCommand cmd = execContext.getCmd(); -127 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName() + "::" +execContext.getParam().getName()); -128 continue; -129 } -130 String config = split.length == 2 ? split[1] : null; -131 //noinspection unchecked -132 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); -133 -134 //noinspection unchecked -135 condition.validateCondition(conditionContext, execContext, value); -136 } -137 } -138 -139 public interface Condition <I extends CommandIssuer> { -140 void validateCondition(ConditionContext<I> context) throws InvalidCommandArgument; -141 } -142 -143 public interface ParameterCondition <P, CEC extends CommandExecutionContext, I extends CommandIssuer> { -144 void validateCondition(ConditionContext<I> context, CEC execContext, P value) throws InvalidCommandArgument; -145 } -146} +102 conditions = this.manager.getCommandReplacements().replace(conditions); +103 I issuer = execContext.getIssuer(); +104 for (String cond : ACFPatterns.PIPE.split(conditions)) { +105 String[] split = ACFPatterns.COLON.split(cond, 2); +106 ParameterCondition condition; +107 Class<?> cls = execContext.getParam().getType(); +108 String id = split[0].toLowerCase(); +109 do { +110 condition = this.paramConditions.get(cls, id); +111 if (condition == null && cls.getSuperclass() != null && cls.getSuperclass() != Object.class) { +112 cls = cls.getSuperclass(); +113 } else { +114 break; +115 } +116 } while (cls != null); +117 +118 +119 if (condition == null) { +120 RegisteredCommand cmd = execContext.getCmd(); +121 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName() + "::" +execContext.getParam().getName()); +122 continue; +123 } +124 String config = split.length == 2 ? split[1] : null; +125 //noinspection unchecked +126 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); +127 +128 //noinspection unchecked +129 condition.validateCondition(conditionContext, execContext, value); +130 } +131 } +132 +133 public interface Condition <I extends CommandIssuer> { +134 void validateCondition(ConditionContext<I> context) throws InvalidCommandArgument; +135 } +136 +137 public interface ParameterCondition <P, CEC extends CommandExecutionContext, I extends CommandIssuer> { +138 void validateCondition(ConditionContext<I> context, CEC execContext, P value) throws InvalidCommandArgument; +139 } +140} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandConditions.html b/docs/acf-core/src-html/co/aikar/commands/CommandConditions.html index 289a3b0c..6ff13c3a 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandConditions.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandConditions.html @@ -62,96 +62,90 @@ 054 return this.paramConditions.put(clazz, id.toLowerCase(), handler); 055 } 056 -057 void validateConditions(CEC cec, Object value) throws InvalidCommandArgument { -058 Conditions conditions = cec.getParam().getAnnotation(Conditions.class); -059 validateConditions(conditions, cec, value); -060 } -061 -062 void validateConditions(CommandOperationContext context) throws InvalidCommandArgument { -063 RegisteredCommand cmd = context.getRegisteredCommand(); -064 Conditions conditions = cmd.method.getAnnotation(Conditions.class); -065 validateConditions(conditions, context); -066 validateConditions(cmd.scope, context); -067 } -068 -069 -070 private void validateConditions(BaseCommand scope, CommandOperationContext operationContext) throws InvalidCommandArgument { -071 Conditions conditions = scope.getClass().getAnnotation(Conditions.class); -072 validateConditions(conditions, operationContext); -073 -074 if (scope.parentCommand != null) { -075 validateConditions(scope.parentCommand, operationContext); -076 } -077 } -078 -079 private void validateConditions(Conditions condAnno, CommandOperationContext context) throws InvalidCommandArgument { -080 if (condAnno == null) { -081 return; -082 } -083 -084 String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); -085 CommandIssuer issuer = context.getCommandIssuer(); -086 for (String cond : ACFPatterns.PIPE.split(conditions)) { -087 String[] split = ACFPatterns.COLON.split(cond, 2); -088 String id = split[0].toLowerCase(); -089 Condition<I> condition = this.conditions.get(id); -090 if (condition == null) { -091 RegisteredCommand cmd = context.getRegisteredCommand(); -092 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName()); -093 continue; -094 } -095 -096 String config = split.length == 2 ? split[1] : null; -097 //noinspection unchecked -098 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); -099 //noinspection unchecked -100 condition.validateCondition(conditionContext); +057 void validateConditions(CommandOperationContext context) throws InvalidCommandArgument { +058 RegisteredCommand cmd = context.getRegisteredCommand(); +059 +060 validateConditions(cmd.conditions, context); +061 validateConditions(cmd.scope, context); +062 } +063 +064 private void validateConditions(BaseCommand scope, CommandOperationContext operationContext) throws InvalidCommandArgument { +065 validateConditions(scope.conditions, operationContext); +066 +067 if (scope.parentCommand != null) { +068 validateConditions(scope.parentCommand, operationContext); +069 } +070 } +071 +072 private void validateConditions(String conditions, CommandOperationContext context) throws InvalidCommandArgument { +073 if (conditions == null) { +074 return; +075 } +076 +077 conditions = this.manager.getCommandReplacements().replace(conditions); +078 CommandIssuer issuer = context.getCommandIssuer(); +079 for (String cond : ACFPatterns.PIPE.split(conditions)) { +080 String[] split = ACFPatterns.COLON.split(cond, 2); +081 String id = split[0].toLowerCase(); +082 Condition<I> condition = this.conditions.get(id); +083 if (condition == null) { +084 RegisteredCommand cmd = context.getRegisteredCommand(); +085 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName()); +086 continue; +087 } +088 +089 String config = split.length == 2 ? split[1] : null; +090 //noinspection unchecked +091 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); +092 //noinspection unchecked +093 condition.validateCondition(conditionContext); +094 } +095 } +096 +097 void validateConditions(CEC execContext, Object value) throws InvalidCommandArgument { +098 String conditions = execContext.getCommandParameter().getConditions(); +099 if (conditions == null) { +100 return; 101 } -102 } -103 -104 private void validateConditions(Conditions condAnno, CEC execContext, Object value) throws InvalidCommandArgument { -105 if (condAnno == null) { -106 return; -107 } -108 String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); -109 I issuer = execContext.getIssuer(); -110 for (String cond : ACFPatterns.PIPE.split(conditions)) { -111 String[] split = ACFPatterns.COLON.split(cond, 2); -112 ParameterCondition condition; -113 Class<?> cls = execContext.getParam().getType(); -114 String id = split[0].toLowerCase(); -115 do { -116 condition = this.paramConditions.get(cls, id); -117 if (condition == null && cls.getSuperclass() != null && cls.getSuperclass() != Object.class) { -118 cls = cls.getSuperclass(); -119 } else { -120 break; -121 } -122 } while (cls != null); -123 -124 -125 if (condition == null) { -126 RegisteredCommand cmd = execContext.getCmd(); -127 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName() + "::" +execContext.getParam().getName()); -128 continue; -129 } -130 String config = split.length == 2 ? split[1] : null; -131 //noinspection unchecked -132 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); -133 -134 //noinspection unchecked -135 condition.validateCondition(conditionContext, execContext, value); -136 } -137 } -138 -139 public interface Condition <I extends CommandIssuer> { -140 void validateCondition(ConditionContext<I> context) throws InvalidCommandArgument; -141 } -142 -143 public interface ParameterCondition <P, CEC extends CommandExecutionContext, I extends CommandIssuer> { -144 void validateCondition(ConditionContext<I> context, CEC execContext, P value) throws InvalidCommandArgument; -145 } -146} +102 conditions = this.manager.getCommandReplacements().replace(conditions); +103 I issuer = execContext.getIssuer(); +104 for (String cond : ACFPatterns.PIPE.split(conditions)) { +105 String[] split = ACFPatterns.COLON.split(cond, 2); +106 ParameterCondition condition; +107 Class<?> cls = execContext.getParam().getType(); +108 String id = split[0].toLowerCase(); +109 do { +110 condition = this.paramConditions.get(cls, id); +111 if (condition == null && cls.getSuperclass() != null && cls.getSuperclass() != Object.class) { +112 cls = cls.getSuperclass(); +113 } else { +114 break; +115 } +116 } while (cls != null); +117 +118 +119 if (condition == null) { +120 RegisteredCommand cmd = execContext.getCmd(); +121 this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName() + "::" +execContext.getParam().getName()); +122 continue; +123 } +124 String config = split.length == 2 ? split[1] : null; +125 //noinspection unchecked +126 CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); +127 +128 //noinspection unchecked +129 condition.validateCondition(conditionContext, execContext, value); +130 } +131 } +132 +133 public interface Condition <I extends CommandIssuer> { +134 void validateCondition(ConditionContext<I> context) throws InvalidCommandArgument; +135 } +136 +137 public interface ParameterCondition <P, CEC extends CommandExecutionContext, I extends CommandIssuer> { +138 void validateCondition(ConditionContext<I> context, CEC execContext, P value) throws InvalidCommandArgument; +139 } +140} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html b/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html index 428bfac0..5f696747 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html @@ -158,11 +158,11 @@ 150 return s.charAt(0); 151 }); 152 registerContext(String.class, (c) -> { -153 final Values values = c.getParam().getAnnotation(Values.class); -154 if (values != null) { +153 // This will fail fast, its either in the values or its not +154 if (c.hasAnnotation(Values.class)) { 155 return c.popFirstArg(); 156 } -157 String ret = (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) ? +157 String ret = (c.isLastArg() && !c.hasAnnotation(Single.class)) ? 158 ACFUtil.join(c.getArgs()) 159 : 160 c.popFirstArg(); @@ -187,17 +187,17 @@ 179 // Go home IDEA, you're drunk 180 //noinspection unchecked 181 List<String> args = c.getArgs(); -182 if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) { +182 if (c.isLastArg() && !c.hasAnnotation(Single.class)) { 183 val = ACFUtil.join(args); 184 } else { 185 val = c.popFirstArg(); 186 } -187 Split split = c.getParam().getAnnotation(Split.class); +187 String split = c.getAnnotationValue(Split.class, Annotations.NOTHING | Annotations.NO_EMPTY); 188 if (split != null) { 189 if (val.isEmpty()) { 190 throw new InvalidCommandArgument(); 191 } -192 return ACFPatterns.getPattern(split.value()).split(val); +192 return ACFPatterns.getPattern(split).split(val); 193 } else if (!c.isLastArg()) { 194 ACFUtil.sneaky(new IllegalStateException("Weird Command signature... String[] should be last or @Split")); 195 } diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandExecutionContext.html b/docs/acf-core/src-html/co/aikar/commands/CommandExecutionContext.html index 1eb64bda..e6a1d341 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandExecutionContext.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandExecutionContext.html @@ -178,49 +178,68 @@ 170 return ACFUtil.parseDouble(this.flags.get(flag), def != null ? def.doubleValue() : null); 171 } 172 -173 public <T extends Annotation> T getAnnotation(Class<T> cls) { -174 return param.getParameter().getAnnotation(cls); -175 } -176 -177 public <T extends Annotation> boolean hasAnnotation(Class<T> cls) { -178 return param.getParameter().isAnnotationPresent(cls); -179 } -180 -181 public RegisteredCommand getCmd() { -182 return this.cmd; -183 } -184 -185 public Parameter getParam() { -186 return this.param.getParameter(); -187 } -188 -189 public I getIssuer() { -190 return this.issuer; -191 } -192 -193 public List<String> getArgs() { -194 return this.args; -195 } -196 -197 public int getIndex() { -198 return this.index; -199 } -200 -201 public Map<String, Object> getPassedArgs() { -202 return this.passedArgs; -203 } -204 -205 public Map<String, String> getFlags() { -206 return this.flags; -207 } -208 -209 public String joinArgs() { -210 return ACFUtil.join(args, " "); -211 } -212 public String joinArgs(String sep) { -213 return ACFUtil.join(args, sep); +173 /** +174 * This method will not support annotation processors!! use getAnnotationValue or hasAnnotation +175 * @deprecated Use {@link #getAnnotationValue(Class)} +176 */ +177 @Deprecated +178 public <T extends Annotation> T getAnnotation(Class<T> cls) { +179 return param.getParameter().getAnnotation(cls); +180 } +181 +182 public <T extends Annotation> String getAnnotationValue(Class<T> cls) { +183 return manager.getAnnotations().getAnnotationValue(param.getParameter(), cls); +184 } +185 +186 public <T extends Annotation> String getAnnotationValue(Class<T> cls, int options) { +187 return manager.getAnnotations().getAnnotationValue(param.getParameter(), cls, options); +188 } +189 +190 public <T extends Annotation> boolean hasAnnotation(Class<T> cls) { +191 return manager.getAnnotations().hasAnnotation(param.getParameter(), cls); +192 } +193 +194 public RegisteredCommand getCmd() { +195 return this.cmd; +196 } +197 +198 @UnstableAPI +199 CommandParameter getCommandParameter() { +200 return this.param; +201 } +202 +203 @Deprecated +204 public Parameter getParam() { +205 return this.param.getParameter(); +206 } +207 +208 public I getIssuer() { +209 return this.issuer; +210 } +211 +212 public List<String> getArgs() { +213 return this.args; 214 } -215} +215 +216 public int getIndex() { +217 return this.index; +218 } +219 +220 public Map<String, Object> getPassedArgs() { +221 return this.passedArgs; +222 } +223 +224 public Map<String, String> getFlags() { +225 return this.flags; +226 } +227 +228 public String joinArgs() { +229 return ACFUtil.join(args, " "); +230 } +231 public String joinArgs(String sep) { +232 return ACFUtil.join(args, sep); +233 } +234} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandManager.html b/docs/acf-core/src-html/co/aikar/commands/CommandManager.html index dc79274a..32c77313 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandManager.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandManager.html @@ -32,469 +32,477 @@ 024package co.aikar.commands; 025 026import co.aikar.commands.annotation.Dependency; -027import co.aikar.locales.MessageKeyProvider; -028import com.google.common.collect.HashBasedTable; -029import com.google.common.collect.Lists; -030import com.google.common.collect.Maps; -031import com.google.common.collect.Sets; -032import com.google.common.collect.Table; -033import org.jetbrains.annotations.NotNull; -034 -035import java.lang.reflect.Field; -036import java.lang.reflect.InvocationTargetException; -037import java.lang.reflect.Method; -038import java.util.HashMap; -039import java.util.IdentityHashMap; -040import java.util.List; -041import java.util.Locale; -042import java.util.Map; -043import java.util.Objects; -044import java.util.Set; -045import java.util.Stack; -046import java.util.UUID; -047 -048 -049@SuppressWarnings("WeakerAccess") -050public abstract class CommandManager < -051 IT, -052 I extends CommandIssuer, -053 FT, -054 MF extends MessageFormatter<FT>, -055 CEC extends CommandExecutionContext<CEC, I>, -056 CC extends ConditionContext<I> -057 > { -058 -059 /** -060 * This is a stack incase a command calls a command -061 */ -062 static ThreadLocal<Stack<CommandOperationContext>> commandOperationContext = ThreadLocal.withInitial(() -> new Stack<CommandOperationContext>() { -063 @Override -064 public synchronized CommandOperationContext peek() { -065 return super.size() == 0 ? null : super.peek(); -066 } -067 }); -068 protected Map<String, RootCommand> rootCommands = new HashMap<>(); -069 protected final CommandReplacements replacements = new CommandReplacements(this); -070 protected final CommandConditions<I, CEC, CC> conditions = new CommandConditions<>(this); -071 protected ExceptionHandler defaultExceptionHandler = null; -072 protected Table<Class<?>, String, Object> dependencies = HashBasedTable.create(); -073 -074 protected boolean usePerIssuerLocale = false; -075 protected List<IssuerLocaleChangedCallback<I>> localeChangedCallbacks = Lists.newArrayList(); -076 protected Set<Locale> supportedLanguages = Sets.newHashSet(Locales.ENGLISH, Locales.GERMAN, Locales.SPANISH, Locales.CZECH, Locales.PORTUGUESE); -077 protected Map<MessageType, MF> formatters = new IdentityHashMap<>(); -078 protected MF defaultFormatter; -079 protected int defaultHelpPerPage = 10; -080 -081 protected Map<UUID, Locale> issuersLocale = Maps.newConcurrentMap(); +027import co.aikar.commands.annotation.HelpCommand; +028import co.aikar.locales.MessageKeyProvider; +029import com.google.common.collect.HashBasedTable; +030import com.google.common.collect.Lists; +031import com.google.common.collect.Maps; +032import com.google.common.collect.Sets; +033import com.google.common.collect.Table; +034import org.jetbrains.annotations.NotNull; +035 +036import java.lang.annotation.Annotation; +037import java.lang.reflect.Field; +038import java.lang.reflect.InvocationTargetException; +039import java.lang.reflect.Method; +040import java.util.HashMap; +041import java.util.IdentityHashMap; +042import java.util.List; +043import java.util.Locale; +044import java.util.Map; +045import java.util.Objects; +046import java.util.Set; +047import java.util.Stack; +048import java.util.UUID; +049 +050 +051@SuppressWarnings("WeakerAccess") +052public abstract class CommandManager < +053 IT, +054 I extends CommandIssuer, +055 FT, +056 MF extends MessageFormatter<FT>, +057 CEC extends CommandExecutionContext<CEC, I>, +058 CC extends ConditionContext<I> +059 > { +060 +061 /** +062 * This is a stack incase a command calls a command +063 */ +064 static ThreadLocal<Stack<CommandOperationContext>> commandOperationContext = ThreadLocal.withInitial(() -> new Stack<CommandOperationContext>() { +065 @Override +066 public synchronized CommandOperationContext peek() { +067 return super.size() == 0 ? null : super.peek(); +068 } +069 }); +070 protected Map<String, RootCommand> rootCommands = new HashMap<>(); +071 protected final CommandReplacements replacements = new CommandReplacements(this); +072 protected final CommandConditions<I, CEC, CC> conditions = new CommandConditions<>(this); +073 protected ExceptionHandler defaultExceptionHandler = null; +074 protected Table<Class<?>, String, Object> dependencies = HashBasedTable.create(); +075 +076 protected boolean usePerIssuerLocale = false; +077 protected List<IssuerLocaleChangedCallback<I>> localeChangedCallbacks = Lists.newArrayList(); +078 protected Set<Locale> supportedLanguages = Sets.newHashSet(Locales.ENGLISH, Locales.GERMAN, Locales.SPANISH, Locales.CZECH, Locales.PORTUGUESE); +079 protected Map<MessageType, MF> formatters = new IdentityHashMap<>(); +080 protected MF defaultFormatter; +081 protected int defaultHelpPerPage = 10; 082 -083 private Set<String> unstableAPIs = Sets.newHashSet(); +083 protected Map<UUID, Locale> issuersLocale = Maps.newConcurrentMap(); 084 -085 public static CommandOperationContext getCurrentCommandOperationContext() { -086 return commandOperationContext.get().peek(); -087 } +085 private Set<String> unstableAPIs = Sets.newHashSet(); +086 +087 private Annotations annotations = new Annotations<>(this); 088 -089 public static CommandIssuer getCurrentCommandIssuer() { -090 CommandOperationContext context = commandOperationContext.get().peek(); -091 return context != null ? context.getCommandIssuer() : null; -092 } -093 -094 public static CommandManager getCurrentCommandManager() { -095 CommandOperationContext context = commandOperationContext.get().peek(); -096 return context != null ? context.getCommandManager() : null; -097 } -098 -099 public MF setFormat(MessageType type, MF formatter) { -100 return formatters.put(type, formatter); +089 public static CommandOperationContext getCurrentCommandOperationContext() { +090 return commandOperationContext.get().peek(); +091 } +092 +093 public static CommandIssuer getCurrentCommandIssuer() { +094 CommandOperationContext context = commandOperationContext.get().peek(); +095 return context != null ? context.getCommandIssuer() : null; +096 } +097 +098 public static CommandManager getCurrentCommandManager() { +099 CommandOperationContext context = commandOperationContext.get().peek(); +100 return context != null ? context.getCommandManager() : null; 101 } 102 -103 public MF getFormat(MessageType type) { -104 return formatters.getOrDefault(type, defaultFormatter); +103 public MF setFormat(MessageType type, MF formatter) { +104 return formatters.put(type, formatter); 105 } 106 -107 public void setFormat(MessageType type, FT... colors) { -108 MF format = getFormat(type); -109 for (int i = 1; i <= colors.length; i++) { -110 format.setColor(i, colors[i-1]); -111 } -112 } -113 -114 public void setFormat(MessageType type, int i, FT color) { -115 MF format = getFormat(type); -116 format.setColor(i, color); -117 } -118 -119 public MF getDefaultFormatter() { -120 return defaultFormatter; +107 public MF getFormat(MessageType type) { +108 return formatters.getOrDefault(type, defaultFormatter); +109 } +110 +111 public void setFormat(MessageType type, FT... colors) { +112 MF format = getFormat(type); +113 for (int i = 1; i <= colors.length; i++) { +114 format.setColor(i, colors[i-1]); +115 } +116 } +117 +118 public void setFormat(MessageType type, int i, FT color) { +119 MF format = getFormat(type); +120 format.setColor(i, color); 121 } 122 -123 public void setDefaultFormatter(MF defaultFormatter) { -124 this.defaultFormatter = defaultFormatter; +123 public MF getDefaultFormatter() { +124 return defaultFormatter; 125 } 126 -127 public CommandConditions<I, CEC, CC> getCommandConditions() { -128 return conditions; +127 public void setDefaultFormatter(MF defaultFormatter) { +128 this.defaultFormatter = defaultFormatter; 129 } 130 -131 /** -132 * Gets the command contexts manager -133 * @return Command Contexts -134 */ -135 public abstract CommandContexts<?> getCommandContexts(); -136 -137 /** -138 * Gets the command completions manager -139 * @return Command Completions -140 */ -141 public abstract CommandCompletions<?> getCommandCompletions(); -142 -143 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -144 public CommandHelp generateCommandHelp(@NotNull String command) { -145 verifyUnstableAPI("help"); -146 CommandOperationContext context = getCurrentCommandOperationContext(); -147 if (context == null) { -148 throw new IllegalStateException("This method can only be called as part of a command execution."); -149 } -150 return generateCommandHelp(context.getCommandIssuer(), command); -151 } -152 -153 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -154 public CommandHelp generateCommandHelp(CommandIssuer issuer, @NotNull String command) { -155 verifyUnstableAPI("help"); -156 return generateCommandHelp(issuer, obtainRootCommand(command)); -157 } -158 -159 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -160 public CommandHelp generateCommandHelp() { -161 verifyUnstableAPI("help"); -162 CommandOperationContext context = getCurrentCommandOperationContext(); -163 if (context == null) { -164 throw new IllegalStateException("This method can only be called as part of a command execution."); -165 } -166 String commandLabel = context.getCommandLabel(); -167 return generateCommandHelp(context.getCommandIssuer(), this.obtainRootCommand(commandLabel)); -168 } -169 -170 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -171 public CommandHelp generateCommandHelp(CommandIssuer issuer, RootCommand rootCommand) { -172 verifyUnstableAPI("help"); -173 return new CommandHelp(this, rootCommand, issuer); -174 } -175 -176 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -177 public int getDefaultHelpPerPage() { -178 verifyUnstableAPI("help"); -179 return defaultHelpPerPage; -180 } -181 -182 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -183 public void setDefaultHelpPerPage(int defaultHelpPerPage) { -184 verifyUnstableAPI("help"); -185 this.defaultHelpPerPage = defaultHelpPerPage; -186 } -187 -188 /** -189 * Registers a command with ACF -190 * -191 * @param command The command to register -192 * @return boolean -193 */ -194 public abstract void registerCommand(BaseCommand command); -195 public abstract boolean hasRegisteredCommands(); -196 public abstract boolean isCommandIssuer(Class<?> type); -197 -198 // TODO: Change this to IT if we make a breaking change -199 public abstract I getCommandIssuer(Object issuer); -200 -201 public abstract RootCommand createRootCommand(String cmd); -202 -203 /** -204 * Returns a Locales Manager to add and modify language tables for your commands. -205 * @return -206 */ -207 public abstract Locales getLocales(); -208 -209 public boolean usingPerIssuerLocale() { -210 return usePerIssuerLocale; -211 } +131 public CommandConditions<I, CEC, CC> getCommandConditions() { +132 return conditions; +133 } +134 +135 /** +136 * Gets the command contexts manager +137 * @return Command Contexts +138 */ +139 public abstract CommandContexts<?> getCommandContexts(); +140 +141 /** +142 * Gets the command completions manager +143 * @return Command Completions +144 */ +145 public abstract CommandCompletions<?> getCommandCompletions(); +146 +147 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +148 public CommandHelp generateCommandHelp(@NotNull String command) { +149 verifyUnstableAPI("help"); +150 CommandOperationContext context = getCurrentCommandOperationContext(); +151 if (context == null) { +152 throw new IllegalStateException("This method can only be called as part of a command execution."); +153 } +154 return generateCommandHelp(context.getCommandIssuer(), command); +155 } +156 +157 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +158 public CommandHelp generateCommandHelp(CommandIssuer issuer, @NotNull String command) { +159 verifyUnstableAPI("help"); +160 return generateCommandHelp(issuer, obtainRootCommand(command)); +161 } +162 +163 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +164 public CommandHelp generateCommandHelp() { +165 verifyUnstableAPI("help"); +166 CommandOperationContext context = getCurrentCommandOperationContext(); +167 if (context == null) { +168 throw new IllegalStateException("This method can only be called as part of a command execution."); +169 } +170 String commandLabel = context.getCommandLabel(); +171 return generateCommandHelp(context.getCommandIssuer(), this.obtainRootCommand(commandLabel)); +172 } +173 +174 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +175 public CommandHelp generateCommandHelp(CommandIssuer issuer, RootCommand rootCommand) { +176 verifyUnstableAPI("help"); +177 return new CommandHelp(this, rootCommand, issuer); +178 } +179 +180 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +181 public int getDefaultHelpPerPage() { +182 verifyUnstableAPI("help"); +183 return defaultHelpPerPage; +184 } +185 +186 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +187 public void setDefaultHelpPerPage(int defaultHelpPerPage) { +188 verifyUnstableAPI("help"); +189 this.defaultHelpPerPage = defaultHelpPerPage; +190 } +191 +192 /** +193 * Registers a command with ACF +194 * +195 * @param command The command to register +196 * @return boolean +197 */ +198 public abstract void registerCommand(BaseCommand command); +199 public abstract boolean hasRegisteredCommands(); +200 public abstract boolean isCommandIssuer(Class<?> type); +201 +202 // TODO: Change this to IT if we make a breaking change +203 public abstract I getCommandIssuer(Object issuer); +204 +205 public abstract RootCommand createRootCommand(String cmd); +206 +207 /** +208 * Returns a Locales Manager to add and modify language tables for your commands. +209 * @return +210 */ +211 public abstract Locales getLocales(); 212 -213 public boolean usePerIssuerLocale(boolean setting) { -214 boolean old = usePerIssuerLocale; -215 usePerIssuerLocale = setting; -216 return old; -217 } -218 -219 public ConditionContext createConditionContext(CommandIssuer issuer, String config) { -220 //noinspection unchecked -221 return new ConditionContext(issuer, config); -222 } -223 -224 public abstract CommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs); -225 -226 public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args); +213 public boolean usingPerIssuerLocale() { +214 return usePerIssuerLocale; +215 } +216 +217 public boolean usePerIssuerLocale(boolean setting) { +218 boolean old = usePerIssuerLocale; +219 usePerIssuerLocale = setting; +220 return old; +221 } +222 +223 public ConditionContext createConditionContext(CommandIssuer issuer, String config) { +224 //noinspection unchecked +225 return new ConditionContext(issuer, config); +226 } 227 -228 public abstract void log(final LogLevel level, final String message, final Throwable throwable); +228 public abstract CommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs); 229 -230 public void log(final LogLevel level, final String message) { -231 log(level, message, null); -232 } +230 public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args); +231 +232 public abstract void log(final LogLevel level, final String message, final Throwable throwable); 233 -234 /** -235 * Lets you add custom string replacements that can be applied to annotation values, -236 * to reduce duplication/repetition of common values such as permission nodes and command prefixes. -237 * -238 * Any replacement registered starts with a % -239 * -240 * So for ex @CommandPermission("%staff") -241 * @return Replacements Manager -242 */ -243 public CommandReplacements getCommandReplacements() { -244 return replacements; -245 } -246 -247 public boolean hasPermission(CommandIssuer issuer, String permission) { -248 if (permission == null || permission.isEmpty()) { -249 return true; -250 } -251 for (String perm : ACFPatterns.COMMA.split(permission)) { -252 if (!perm.isEmpty() && !issuer.hasPermission(perm)) { -253 return false; -254 } -255 } -256 return true; -257 } -258 -259 BaseCommand getBaseCommand(String commandLabel, @NotNull String[] args) { -260 RootCommand rootCommand = obtainRootCommand(commandLabel); -261 if (rootCommand == null) { -262 return null; -263 } -264 return rootCommand.getBaseCommand(args); -265 } -266 -267 public synchronized RootCommand getRootCommand(@NotNull String cmd) { -268 return rootCommands.get(ACFPatterns.SPACE.split(cmd.toLowerCase(), 2)[0]); +234 public void log(final LogLevel level, final String message) { +235 log(level, message, null); +236 } +237 +238 /** +239 * Lets you add custom string replacements that can be applied to annotation values, +240 * to reduce duplication/repetition of common values such as permission nodes and command prefixes. +241 * +242 * Any replacement registered starts with a % +243 * +244 * So for ex @CommandPermission("%staff") +245 * @return Replacements Manager +246 */ +247 public CommandReplacements getCommandReplacements() { +248 return replacements; +249 } +250 +251 public boolean hasPermission(CommandIssuer issuer, String permission) { +252 if (permission == null || permission.isEmpty()) { +253 return true; +254 } +255 for (String perm : ACFPatterns.COMMA.split(permission)) { +256 if (!perm.isEmpty() && !issuer.hasPermission(perm)) { +257 return false; +258 } +259 } +260 return true; +261 } +262 +263 BaseCommand getBaseCommand(String commandLabel, @NotNull String[] args) { +264 RootCommand rootCommand = obtainRootCommand(commandLabel); +265 if (rootCommand == null) { +266 return null; +267 } +268 return rootCommand.getBaseCommand(args); 269 } 270 -271 public synchronized RootCommand obtainRootCommand(@NotNull String cmd) { -272 return rootCommands.computeIfAbsent(ACFPatterns.SPACE.split(cmd.toLowerCase(), 2)[0], this::createRootCommand); +271 public synchronized RootCommand getRootCommand(@NotNull String cmd) { +272 return rootCommands.get(ACFPatterns.SPACE.split(cmd.toLowerCase(), 2)[0]); 273 } 274 -275 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { -276 return new RegisteredCommand(command, cmdName, method, prefSubCommand); +275 public synchronized RootCommand obtainRootCommand(@NotNull String cmd) { +276 return rootCommands.computeIfAbsent(ACFPatterns.SPACE.split(cmd.toLowerCase(), 2)[0], this::createRootCommand); 277 } 278 -279 /** -280 * Sets the default {@link ExceptionHandler} that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered. -281 * -282 * @param exceptionHandler the handler that should handle uncaught exceptions -283 */ -284 public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler) { -285 defaultExceptionHandler = exceptionHandler; -286 } -287 -288 /** -289 * Gets the current default exception handler, might be null. -290 * -291 * @return the default exception handler -292 */ -293 public ExceptionHandler getDefaultExceptionHandler() { -294 return defaultExceptionHandler; -295 } -296 -297 protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, CommandIssuer sender, List<String> args, Throwable t) { -298 if (t instanceof InvocationTargetException && t.getCause() != null) { -299 t = t.getCause(); -300 } -301 boolean result = false; -302 if (scope.getExceptionHandler() != null) { -303 result = scope.getExceptionHandler().execute(scope, registeredCommand, sender, args, t); -304 } else if (defaultExceptionHandler != null) { -305 result = defaultExceptionHandler.execute(scope, registeredCommand, sender, args, t); -306 } -307 return result; -308 } -309 -310 public void sendMessage(IT issuerArg, MessageType type, MessageKeyProvider key, String... replacements) { -311 sendMessage(getCommandIssuer(issuerArg), type, key, replacements); +279 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { +280 return new RegisteredCommand(command, cmdName, method, prefSubCommand); +281 } +282 +283 /** +284 * Sets the default {@link ExceptionHandler} that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered. +285 * +286 * @param exceptionHandler the handler that should handle uncaught exceptions +287 */ +288 public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler) { +289 defaultExceptionHandler = exceptionHandler; +290 } +291 +292 /** +293 * Gets the current default exception handler, might be null. +294 * +295 * @return the default exception handler +296 */ +297 public ExceptionHandler getDefaultExceptionHandler() { +298 return defaultExceptionHandler; +299 } +300 +301 protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, CommandIssuer sender, List<String> args, Throwable t) { +302 if (t instanceof InvocationTargetException && t.getCause() != null) { +303 t = t.getCause(); +304 } +305 boolean result = false; +306 if (scope.getExceptionHandler() != null) { +307 result = scope.getExceptionHandler().execute(scope, registeredCommand, sender, args, t); +308 } else if (defaultExceptionHandler != null) { +309 result = defaultExceptionHandler.execute(scope, registeredCommand, sender, args, t); +310 } +311 return result; 312 } 313 -314 public void sendMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { -315 String message = formatMessage(issuer, type, key, replacements); -316 -317 for (String msg : ACFPatterns.NEWLINE.split(message)) { -318 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); -319 } -320 } -321 -322 public String formatMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { -323 String message = getLocales().getMessage(issuer, key.getMessageKey()); -324 if (replacements.length > 0) { -325 message = ACFUtil.replaceStrings(message, replacements); -326 } -327 -328 message = getCommandReplacements().replace(message); -329 -330 MessageFormatter formatter = formatters.getOrDefault(type, defaultFormatter); -331 if (formatter != null) { -332 message = formatter.format(message); -333 } -334 return message; -335 } -336 -337 public void onLocaleChange(IssuerLocaleChangedCallback<I> onChange) { -338 localeChangedCallbacks.add(onChange); +314 public void sendMessage(IT issuerArg, MessageType type, MessageKeyProvider key, String... replacements) { +315 sendMessage(getCommandIssuer(issuerArg), type, key, replacements); +316 } +317 +318 public void sendMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { +319 String message = formatMessage(issuer, type, key, replacements); +320 +321 for (String msg : ACFPatterns.NEWLINE.split(message)) { +322 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); +323 } +324 } +325 +326 public String formatMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { +327 String message = getLocales().getMessage(issuer, key.getMessageKey()); +328 if (replacements.length > 0) { +329 message = ACFUtil.replaceStrings(message, replacements); +330 } +331 +332 message = getCommandReplacements().replace(message); +333 +334 MessageFormatter formatter = formatters.getOrDefault(type, defaultFormatter); +335 if (formatter != null) { +336 message = formatter.format(message); +337 } +338 return message; 339 } 340 -341 public void notifyLocaleChange(I issuer, Locale oldLocale, Locale newLocale) { -342 localeChangedCallbacks.forEach(cb -> { -343 try { -344 cb.onIssuerLocaleChange(issuer, oldLocale, newLocale); -345 } catch (Exception e) { -346 this.log(LogLevel.ERROR, "Error in notifyLocaleChange", e); -347 } -348 }); -349 } -350 -351 public Locale setIssuerLocale(IT issuer, Locale locale) { -352 I commandIssuer = getCommandIssuer(issuer); -353 -354 Locale old = issuersLocale.put(commandIssuer.getUniqueId(), locale); -355 if (!Objects.equals(old, locale)) { -356 this.notifyLocaleChange(commandIssuer, old, locale); -357 } -358 -359 return old; -360 } -361 -362 public Locale getIssuerLocale(CommandIssuer issuer) { -363 if (usingPerIssuerLocale()) { -364 Locale locale = issuersLocale.get(issuer.getUniqueId()); -365 if (locale != null) { -366 return locale; -367 } -368 } -369 -370 return getLocales().getDefaultLocale(); -371 } -372 -373 CommandOperationContext<I> createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) { -374 //noinspection unchecked -375 return new CommandOperationContext<>( -376 this, -377 (I) issuer, -378 command, -379 commandLabel, -380 args, -381 isAsync -382 ); -383 } -384 -385 /** -386 * Gets a list of all currently supported languages for this manager. -387 * These locales will be automatically loaded from -388 * @return -389 */ -390 public Set<Locale> getSupportedLanguages() { -391 return supportedLanguages; -392 } -393 -394 /** -395 * Adds a new locale to the list of automatic Locales to load Message Bundles for. -396 * All bundles loaded under the previous supported languages will now automatically load for this new locale too. -397 * -398 * @param locale -399 */ -400 public void addSupportedLanguage(Locale locale) { -401 supportedLanguages.add(locale); -402 getLocales().loadMissingBundles(); -403 } -404 -405 /** -406 * Registers an instance of a class to be registered as an injectable dependency.<br> -407 * The command manager will attempt to inject all fields in a command class that are annotated with -408 * {@link co.aikar.commands.annotation.Dependency} with the provided instance. -409 * -410 * @param clazz the class the injector should look for when injecting -411 * @param instance the instance of the class that should be injected -412 * @throws IllegalStateException when there is already an instance for the provided class registered -413 */ -414 public <T> void registerDependency(Class<? extends T> clazz, T instance){ -415 registerDependency(clazz, clazz.getName(), instance); -416 } -417 -418 /** -419 * Registers an instance of a class to be registered as an injectable dependency.<br> -420 * The command manager will attempt to inject all fields in a command class that are annotated with -421 * {@link co.aikar.commands.annotation.Dependency} with the provided instance. -422 * -423 * @param clazz the class the injector should look for when injecting -424 * @param key the key which needs to be present if that -425 * @param instance the instance of the class that should be injected -426 * @throws IllegalStateException when there is already an instance for the provided class registered -427 */ -428 public <T> void registerDependency(Class<? extends T> clazz, String key, T instance){ -429 if(dependencies.containsRow(clazz) && dependencies.containsColumn(key)){ -430 throw new IllegalStateException("There is already an instance of " + clazz.getName() + " with the key " + key + " registered!"); -431 } -432 -433 dependencies.put(clazz, key, instance); -434 } -435 -436 /** -437 * Attempts to inject instances of classes registered with {@link CommandManager#registerDependency(Class, Object)} -438 * into all fields of the class and its superclasses that are marked with {@link Dependency}. -439 * -440 * @param baseCommand the instance which fields should be filled -441 */ -442 void injectDependencies(BaseCommand baseCommand) { -443 Class clazz = baseCommand.getClass(); -444 do { -445 for (Field field : clazz.getDeclaredFields()) { -446 if (field.isAnnotationPresent(Dependency.class)) { -447 Dependency dependency = field.getAnnotation(Dependency.class); -448 String key = (key = dependency.value()).equals("") ? field.getType().getName() : key; -449 Object object = dependencies.row(field.getType()).get(key); -450 if (object == null) { -451 throw new UnresolvedDependencyException("Could not find a registered instance of " + -452 field.getType().getName() + " with key " + key + " for field " + field.getName() + -453 " in class " + baseCommand.getClass().getName()); -454 } -455 -456 try { -457 boolean accessible = field.isAccessible(); -458 if (!accessible) { -459 field.setAccessible(true); -460 } -461 field.set(baseCommand, object); -462 field.setAccessible(accessible); -463 } catch (IllegalAccessException e) { -464 e.printStackTrace(); //TODO should we print our own exception here to make a more descriptive error? -465 } -466 } -467 } -468 clazz = clazz.getSuperclass(); -469 } while (!clazz.equals(BaseCommand.class)); -470 } -471 -472 /** -473 * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF -474 * may require you to update your implementation to those unstable API's -475 */ -476 @Deprecated -477 public void enableUnstableAPI(String api) { -478 unstableAPIs.add(api); -479 } -480 void verifyUnstableAPI(String api) { -481 if (!unstableAPIs.contains(api)) { -482 throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs"); -483 } -484 } -485 -486 boolean hasUnstableAPI(String api) { -487 return unstableAPIs.contains(api); +341 public void onLocaleChange(IssuerLocaleChangedCallback<I> onChange) { +342 localeChangedCallbacks.add(onChange); +343 } +344 +345 public void notifyLocaleChange(I issuer, Locale oldLocale, Locale newLocale) { +346 localeChangedCallbacks.forEach(cb -> { +347 try { +348 cb.onIssuerLocaleChange(issuer, oldLocale, newLocale); +349 } catch (Exception e) { +350 this.log(LogLevel.ERROR, "Error in notifyLocaleChange", e); +351 } +352 }); +353 } +354 +355 public Locale setIssuerLocale(IT issuer, Locale locale) { +356 I commandIssuer = getCommandIssuer(issuer); +357 +358 Locale old = issuersLocale.put(commandIssuer.getUniqueId(), locale); +359 if (!Objects.equals(old, locale)) { +360 this.notifyLocaleChange(commandIssuer, old, locale); +361 } +362 +363 return old; +364 } +365 +366 public Locale getIssuerLocale(CommandIssuer issuer) { +367 if (usingPerIssuerLocale()) { +368 Locale locale = issuersLocale.get(issuer.getUniqueId()); +369 if (locale != null) { +370 return locale; +371 } +372 } +373 +374 return getLocales().getDefaultLocale(); +375 } +376 +377 CommandOperationContext<I> createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) { +378 //noinspection unchecked +379 return new CommandOperationContext<>( +380 this, +381 (I) issuer, +382 command, +383 commandLabel, +384 args, +385 isAsync +386 ); +387 } +388 +389 /** +390 * Gets a list of all currently supported languages for this manager. +391 * These locales will be automatically loaded from +392 * @return +393 */ +394 public Set<Locale> getSupportedLanguages() { +395 return supportedLanguages; +396 } +397 +398 /** +399 * Adds a new locale to the list of automatic Locales to load Message Bundles for. +400 * All bundles loaded under the previous supported languages will now automatically load for this new locale too. +401 * +402 * @param locale +403 */ +404 public void addSupportedLanguage(Locale locale) { +405 supportedLanguages.add(locale); +406 getLocales().loadMissingBundles(); +407 } +408 +409 /** +410 * Registers an instance of a class to be registered as an injectable dependency.<br> +411 * The command manager will attempt to inject all fields in a command class that are annotated with +412 * {@link co.aikar.commands.annotation.Dependency} with the provided instance. +413 * +414 * @param clazz the class the injector should look for when injecting +415 * @param instance the instance of the class that should be injected +416 * @throws IllegalStateException when there is already an instance for the provided class registered +417 */ +418 public <T> void registerDependency(Class<? extends T> clazz, T instance){ +419 registerDependency(clazz, clazz.getName(), instance); +420 } +421 +422 /** +423 * Registers an instance of a class to be registered as an injectable dependency.<br> +424 * The command manager will attempt to inject all fields in a command class that are annotated with +425 * {@link co.aikar.commands.annotation.Dependency} with the provided instance. +426 * +427 * @param clazz the class the injector should look for when injecting +428 * @param key the key which needs to be present if that +429 * @param instance the instance of the class that should be injected +430 * @throws IllegalStateException when there is already an instance for the provided class registered +431 */ +432 public <T> void registerDependency(Class<? extends T> clazz, String key, T instance){ +433 if(dependencies.containsRow(clazz) && dependencies.containsColumn(key)){ +434 throw new IllegalStateException("There is already an instance of " + clazz.getName() + " with the key " + key + " registered!"); +435 } +436 +437 dependencies.put(clazz, key, instance); +438 } +439 +440 /** +441 * Attempts to inject instances of classes registered with {@link CommandManager#registerDependency(Class, Object)} +442 * into all fields of the class and its superclasses that are marked with {@link Dependency}. +443 * +444 * @param baseCommand the instance which fields should be filled +445 */ +446 void injectDependencies(BaseCommand baseCommand) { +447 Class clazz = baseCommand.getClass(); +448 do { +449 for (Field field : clazz.getDeclaredFields()) { +450 if (annotations.hasAnnotation(field, Dependency.class)) { +451 String dependency = annotations.getAnnotationValue(field, Dependency.class); +452 String key = (key = dependency).isEmpty() ? field.getType().getName() : key; +453 Object object = dependencies.row(field.getType()).get(key); +454 if (object == null) { +455 throw new UnresolvedDependencyException("Could not find a registered instance of " + +456 field.getType().getName() + " with key " + key + " for field " + field.getName() + +457 " in class " + baseCommand.getClass().getName()); +458 } +459 +460 try { +461 boolean accessible = field.isAccessible(); +462 if (!accessible) { +463 field.setAccessible(true); +464 } +465 field.set(baseCommand, object); +466 field.setAccessible(accessible); +467 } catch (IllegalAccessException e) { +468 e.printStackTrace(); //TODO should we print our own exception here to make a more descriptive error? +469 } +470 } +471 } +472 clazz = clazz.getSuperclass(); +473 } while (!clazz.equals(BaseCommand.class)); +474 } +475 +476 /** +477 * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF +478 * may require you to update your implementation to those unstable API's +479 */ +480 @Deprecated +481 public void enableUnstableAPI(String api) { +482 unstableAPIs.add(api); +483 } +484 void verifyUnstableAPI(String api) { +485 if (!unstableAPIs.contains(api)) { +486 throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs"); +487 } 488 } -489} +489 +490 boolean hasUnstableAPI(String api) { +491 return unstableAPIs.contains(api); +492 } +493 +494 Annotations getAnnotations() { +495 return annotations; +496 } +497} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandOperationContext.html b/docs/acf-core/src-html/co/aikar/commands/CommandOperationContext.html index e9678f7f..5852da15 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandOperationContext.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandOperationContext.html @@ -87,15 +87,28 @@ 079 return registeredCommand; 080 } 081 -082 public <T extends Annotation> T getAnnotation(Class<T> anno) { -083 return registeredCommand.method.getAnnotation(anno); -084 } -085 -086 public boolean hasAnnotation(Class<? extends Annotation> anno) { -087 return getAnnotation(anno) != null; -088 } -089 -090} +082 /** +083 * This method will not support annotation processors!! use getAnnotationValue or hasAnnotation +084 * @deprecated Use {@link #getAnnotationValue(Class)} +085 */ +086 @Deprecated +087 public <T extends Annotation> T getAnnotation(Class<T> anno) { +088 return registeredCommand.method.getAnnotation(anno); +089 } +090 +091 public <T extends Annotation> String getAnnotationValue(Class<T> cls) { +092 return manager.getAnnotations().getAnnotationValue(registeredCommand.method, cls); +093 } +094 +095 public <T extends Annotation> String getAnnotationValue(Class<T> cls, int options) { +096 return manager.getAnnotations().getAnnotationValue(registeredCommand.method, cls, options); +097 } +098 +099 public boolean hasAnnotation(Class<? extends Annotation> anno) { +100 return getAnnotation(anno) != null; +101 } +102 +103} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandParameter.html b/docs/acf-core/src-html/co/aikar/commands/CommandParameter.html index e9433039..9a5d4608 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandParameter.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandParameter.html @@ -31,237 +31,238 @@ 023 024package co.aikar.commands; 025 -026import co.aikar.commands.annotation.Default; -027import co.aikar.commands.annotation.Description; -028import co.aikar.commands.annotation.Flags; -029import co.aikar.commands.annotation.Optional; -030import co.aikar.commands.annotation.Syntax; -031import co.aikar.commands.annotation.Values; -032import co.aikar.commands.contexts.ContextResolver; -033import co.aikar.commands.contexts.IssuerAwareContextResolver; -034import co.aikar.commands.contexts.IssuerOnlyContextResolver; -035import co.aikar.commands.contexts.OptionalContextResolver; -036import com.google.common.collect.Maps; -037 -038import java.lang.reflect.Parameter; -039import java.util.Map; -040 -041public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> { -042 private final Parameter parameter; -043 private final Class<?> type; -044 private final String name; -045 private final CommandManager manager; -046 private final int paramIndex; -047 -048 private ContextResolver<?, CEC> resolver; -049 private boolean optional; -050 private String description; -051 private String defaultValue; -052 private String syntax; -053 private boolean requiresInput; -054 private boolean commandIssuer; -055 private String[] values; -056 private Map<String, String> flags; -057 private boolean canConsumeInput; -058 private boolean optionalResolver; -059 -060 public CommandParameter(RegisteredCommand<CEC> command, Parameter param, int paramIndex) { -061 this.parameter = param; -062 this.type = param.getType(); -063 this.name = param.getName(); // do we care for an annotation to supply name? -064 //noinspection unchecked -065 this.manager = command.manager; -066 this.paramIndex = paramIndex; -067 CommandReplacements replacements = manager.getCommandReplacements(); -068 -069 Default defaultAnno = param.getAnnotation(Default.class); -070 Description descAnno = param.getAnnotation(Description.class); -071 -072 //noinspection unchecked -073 this.resolver = manager.getCommandContexts().getResolver(type); -074 if (this.resolver == null) { -075 ACFUtil.sneaky(new InvalidCommandContextException( -076 "Parameter " + type.getSimpleName() + " of " + command + " has no applicable context resolver" -077 )); -078 } -079 -080 this.description = descAnno != null ? descAnno.value() : null; -081 String defaultValue = defaultAnno != null ? replacements.replace(defaultAnno.value()) : null; -082 this.defaultValue = defaultValue != null && (type == String.class || !defaultValue.isEmpty()) ? defaultValue : null; -083 -084 -085 this.optional = param.isAnnotationPresent(Optional.class) || this.defaultValue != null; -086 this.optionalResolver = isOptionalResolver(resolver); -087 this.requiresInput = !this.optional && !this.optionalResolver; -088 //noinspection unchecked -089 this.commandIssuer = manager.isCommandIssuer(type); -090 this.canConsumeInput = !(resolver instanceof IssuerOnlyContextResolver); +026import co.aikar.commands.annotation.Conditions; +027import co.aikar.commands.annotation.Default; +028import co.aikar.commands.annotation.Description; +029import co.aikar.commands.annotation.Flags; +030import co.aikar.commands.annotation.Optional; +031import co.aikar.commands.annotation.Syntax; +032import co.aikar.commands.annotation.Values; +033import co.aikar.commands.contexts.ContextResolver; +034import co.aikar.commands.contexts.IssuerAwareContextResolver; +035import co.aikar.commands.contexts.IssuerOnlyContextResolver; +036import co.aikar.commands.contexts.OptionalContextResolver; +037import com.google.common.collect.Maps; +038 +039import java.lang.reflect.Parameter; +040import java.util.Map; +041 +042public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> { +043 private final Parameter parameter; +044 private final Class<?> type; +045 private final String name; +046 private final CommandManager manager; +047 private final int paramIndex; +048 +049 private ContextResolver<?, CEC> resolver; +050 private boolean optional; +051 private String description; +052 private String defaultValue; +053 private String syntax; +054 private String conditions; +055 private boolean requiresInput; +056 private boolean commandIssuer; +057 private String[] values; +058 private Map<String, String> flags; +059 private boolean canConsumeInput; +060 private boolean optionalResolver; +061 +062 public CommandParameter(RegisteredCommand<CEC> command, Parameter param, int paramIndex) { +063 this.parameter = param; +064 this.type = param.getType(); +065 this.name = param.getName(); // do we care for an annotation to supply name? +066 //noinspection unchecked +067 this.manager = command.manager; +068 this.paramIndex = paramIndex; +069 Annotations annotations = manager.getAnnotations(); +070 +071 this.defaultValue = annotations.getAnnotationValue(param, Default.class, Annotations.REPLACEMENTS | (type != String.class ? Annotations.NO_EMPTY : 0)); +072 this.description = annotations.getAnnotationValue(param, Description.class, Annotations.REPLACEMENTS | Annotations.DEFAULT_EMPTY); +073 this.conditions = annotations.getAnnotationValue(param, Conditions.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY); +074 +075 //noinspection unchecked +076 this.resolver = manager.getCommandContexts().getResolver(type); +077 if (this.resolver == null) { +078 ACFUtil.sneaky(new InvalidCommandContextException( +079 "Parameter " + type.getSimpleName() + " of " + command + " has no applicable context resolver" +080 )); +081 } +082 +083 this.optional = annotations.hasAnnotation(param, Optional.class) || this.defaultValue != null; +084 this.optionalResolver = isOptionalResolver(resolver); +085 this.requiresInput = !this.optional && !this.optionalResolver; +086 //noinspection unchecked +087 this.commandIssuer = manager.isCommandIssuer(type); +088 this.canConsumeInput = !(resolver instanceof IssuerOnlyContextResolver); +089 +090 this.values = annotations.getAnnotationValues(param, Values.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY); 091 -092 final Values values = param.getAnnotation(Values.class); -093 if (values != null) { -094 this.values = ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(values.value())); -095 } else { -096 this.values = null; -097 } -098 -099 this.syntax = null; -100 if (!commandIssuer) { -101 Syntax syntaxAnno = param.getAnnotation(Syntax.class); -102 if (syntaxAnno != null) { -103 this.syntax = replacements.replace(syntaxAnno.value()); -104 } else if (!requiresInput && canConsumeInput) { -105 this.syntax = "[" + name + "]"; -106 } else if (requiresInput) { -107 this.syntax = "<" + name + ">"; -108 } -109 } -110 -111 this.flags = Maps.newHashMap(); -112 Flags flags = param.getAnnotation(Flags.class); -113 if (flags != null) { -114 parseFlags(flags.value()); -115 } -116 inheritContextFlags(command.scope); -117 } -118 -119 private void inheritContextFlags(BaseCommand scope) { -120 if (!scope.contextFlags.isEmpty()) { -121 Class<?> pCls = this.type; -122 do { -123 parseFlags(scope.contextFlags.get(pCls)); -124 } while ((pCls = pCls.getSuperclass()) != null); -125 } -126 if (scope.parentCommand != null) { -127 inheritContextFlags(scope.parentCommand); -128 } -129 } -130 -131 private void parseFlags(String flags) { -132 if (flags != null) { -133 for (String s : ACFPatterns.COMMA.split(manager.getCommandReplacements().replace(flags))) { -134 String[] v = ACFPatterns.EQUALS.split(s, 2); -135 if (!this.flags.containsKey(v[0])) { -136 this.flags.put(v[0], v.length > 1 ? v[1] : null); -137 } -138 } -139 } -140 } +092 this.syntax = null; +093 if (!commandIssuer) { +094 this.syntax = annotations.getAnnotationValue(param, Syntax.class); +095 if (syntax == null) { +096 if (!requiresInput && canConsumeInput) { +097 this.syntax = "[" + name + "]"; +098 } else if (requiresInput) { +099 this.syntax = "<" + name + ">"; +100 } +101 } +102 } +103 +104 this.flags = Maps.newHashMap(); +105 String flags = annotations.getAnnotationValue(param, Flags.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY); +106 if (flags != null) { +107 parseFlags(flags); +108 } +109 inheritContextFlags(command.scope); +110 } +111 +112 private void inheritContextFlags(BaseCommand scope) { +113 if (!scope.contextFlags.isEmpty()) { +114 Class<?> pCls = this.type; +115 do { +116 parseFlags(scope.contextFlags.get(pCls)); +117 } while ((pCls = pCls.getSuperclass()) != null); +118 } +119 if (scope.parentCommand != null) { +120 inheritContextFlags(scope.parentCommand); +121 } +122 } +123 +124 private void parseFlags(String flags) { +125 if (flags != null) { +126 for (String s : ACFPatterns.COMMA.split(manager.getCommandReplacements().replace(flags))) { +127 String[] v = ACFPatterns.EQUALS.split(s, 2); +128 if (!this.flags.containsKey(v[0])) { +129 this.flags.put(v[0], v.length > 1 ? v[1] : null); +130 } +131 } +132 } +133 } +134 +135 private boolean isOptionalResolver(ContextResolver<?, CEC> resolver) { +136 return resolver instanceof IssuerAwareContextResolver +137 || resolver instanceof IssuerOnlyContextResolver +138 || resolver instanceof OptionalContextResolver; +139 } +140 141 -142 private boolean isOptionalResolver(ContextResolver<?, CEC> resolver) { -143 return resolver instanceof IssuerAwareContextResolver -144 || resolver instanceof IssuerOnlyContextResolver -145 || resolver instanceof OptionalContextResolver; -146 } -147 -148 -149 public Parameter getParameter() { -150 return parameter; -151 } -152 -153 public Class<?> getType() { -154 return type; -155 } -156 -157 public String getName() { -158 return name; -159 } -160 -161 public CommandManager getManager() { -162 return manager; -163 } -164 -165 public int getParamIndex() { -166 return paramIndex; -167 } -168 -169 public ContextResolver<?, CEC> getResolver() { -170 return resolver; -171 } -172 -173 public void setResolver(ContextResolver<?, CEC> resolver) { -174 this.resolver = resolver; -175 } -176 -177 public boolean isOptional() { -178 return optional; -179 } -180 -181 public void setOptional(boolean optional) { -182 this.optional = optional; -183 } -184 -185 public String getDescription() { -186 return description; -187 } -188 -189 public void setDescription(String description) { -190 this.description = description; -191 } -192 -193 public String getDefaultValue() { -194 return defaultValue; -195 } -196 -197 public void setDefaultValue(String defaultValue) { -198 this.defaultValue = defaultValue; -199 } -200 -201 public boolean isCommandIssuer() { -202 return commandIssuer; -203 } -204 -205 public void setCommandIssuer(boolean commandIssuer) { -206 this.commandIssuer = commandIssuer; -207 } -208 -209 public String[] getValues() { -210 return values; -211 } -212 -213 public void setValues(String[] values) { -214 this.values = values; -215 } -216 -217 public Map<String, String> getFlags() { -218 return flags; -219 } -220 -221 public void setFlags(Map<String, String> flags) { -222 this.flags = flags; -223 } -224 -225 public boolean canConsumeInput() { -226 return canConsumeInput; -227 } -228 -229 public void setCanConsumeInput(boolean canConsumeInput) { -230 this.canConsumeInput = canConsumeInput; -231 } -232 -233 public void setOptionalResolver(boolean optionalResolver) { -234 this.optionalResolver = optionalResolver; -235 } -236 -237 public boolean isOptionalResolver() { -238 return optionalResolver; -239 } -240 -241 public boolean requiresInput() { -242 return requiresInput; -243 } -244 -245 public void setRequiresInput(boolean requiresInput) { -246 this.requiresInput = requiresInput; -247 } -248 -249 public String getSyntax() { -250 return syntax; -251 } -252 -253 public void setSyntax(String syntax) { -254 this.syntax = syntax; -255 } -256} +142 public Parameter getParameter() { +143 return parameter; +144 } +145 +146 public Class<?> getType() { +147 return type; +148 } +149 +150 public String getName() { +151 return name; +152 } +153 +154 public CommandManager getManager() { +155 return manager; +156 } +157 +158 public int getParamIndex() { +159 return paramIndex; +160 } +161 +162 public ContextResolver<?, CEC> getResolver() { +163 return resolver; +164 } +165 +166 public void setResolver(ContextResolver<?, CEC> resolver) { +167 this.resolver = resolver; +168 } +169 +170 public boolean isOptional() { +171 return optional; +172 } +173 +174 public void setOptional(boolean optional) { +175 this.optional = optional; +176 } +177 +178 public String getDescription() { +179 return description; +180 } +181 +182 public void setDescription(String description) { +183 this.description = description; +184 } +185 +186 public String getDefaultValue() { +187 return defaultValue; +188 } +189 +190 public void setDefaultValue(String defaultValue) { +191 this.defaultValue = defaultValue; +192 } +193 +194 public boolean isCommandIssuer() { +195 return commandIssuer; +196 } +197 +198 public void setCommandIssuer(boolean commandIssuer) { +199 this.commandIssuer = commandIssuer; +200 } +201 +202 public String[] getValues() { +203 return values; +204 } +205 +206 public void setValues(String[] values) { +207 this.values = values; +208 } +209 +210 public Map<String, String> getFlags() { +211 return flags; +212 } +213 +214 public void setFlags(Map<String, String> flags) { +215 this.flags = flags; +216 } +217 +218 public boolean canConsumeInput() { +219 return canConsumeInput; +220 } +221 +222 public void setCanConsumeInput(boolean canConsumeInput) { +223 this.canConsumeInput = canConsumeInput; +224 } +225 +226 public void setOptionalResolver(boolean optionalResolver) { +227 this.optionalResolver = optionalResolver; +228 } +229 +230 public boolean isOptionalResolver() { +231 return optionalResolver; +232 } +233 +234 public boolean requiresInput() { +235 return requiresInput; +236 } +237 +238 public void setRequiresInput(boolean requiresInput) { +239 this.requiresInput = requiresInput; +240 } +241 +242 public String getSyntax() { +243 return syntax; +244 } +245 +246 public void setSyntax(String syntax) { +247 this.syntax = syntax; +248 } +249 +250 public String getConditions() { +251 return conditions; +252 } +253 +254 public void setConditions(String conditions) { +255 this.conditions = conditions; +256 } +257} diff --git a/docs/acf-core/src-html/co/aikar/commands/HelpEntry.html b/docs/acf-core/src-html/co/aikar/commands/HelpEntry.html index ca803606..e3aa7651 100644 --- a/docs/acf-core/src-html/co/aikar/commands/HelpEntry.html +++ b/docs/acf-core/src-html/co/aikar/commands/HelpEntry.html @@ -36,48 +36,45 @@ 028public class HelpEntry { 029 030 private final RegisteredCommand command; -031 private final String searchTags; -032 private int searchScore = 1; -033 -034 HelpEntry(RegisteredCommand command) { -035 this.command = command; -036 HelpSearchTags tagsAnno = command.method.getAnnotation(HelpSearchTags.class); -037 this.searchTags = tagsAnno != null ? tagsAnno.value() : null; -038 } -039 -040 RegisteredCommand getRegisteredCommand() { -041 return this.command; -042 } -043 -044 -045 public String getCommand(){ -046 return "/" + this.command.command; -047 } -048 -049 public String getParameterSyntax(){ -050 return this.command.syntaxText; -051 } -052 -053 public String getDescription(){ -054 return this.command.helpText; -055 } -056 -057 public void setSearchScore(int searchScore) { -058 this.searchScore = searchScore; -059 } -060 -061 public boolean shouldShow() { -062 return this.searchScore > 0; -063 } -064 -065 public int getSearchScore() { -066 return searchScore; -067 } -068 -069 public String getSearchTags() { -070 return searchTags; -071 } -072} +031 private int searchScore = 1; +032 +033 HelpEntry(RegisteredCommand command) { +034 this.command = command; +035 } +036 +037 RegisteredCommand getRegisteredCommand() { +038 return this.command; +039 } +040 +041 +042 public String getCommand(){ +043 return "/" + this.command.command; +044 } +045 +046 public String getParameterSyntax(){ +047 return this.command.syntaxText; +048 } +049 +050 public String getDescription(){ +051 return this.command.helpText; +052 } +053 +054 public void setSearchScore(int searchScore) { +055 this.searchScore = searchScore; +056 } +057 +058 public boolean shouldShow() { +059 return this.searchScore > 0; +060 } +061 +062 public int getSearchScore() { +063 return searchScore; +064 } +065 +066 public String getSearchTags() { +067 return command.helpSearchTags; +068 } +069} 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 3aeec899..00af2ab1 100644 --- a/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html +++ b/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html @@ -34,266 +34,269 @@ 026import co.aikar.commands.annotation.CommandAlias; 027import co.aikar.commands.annotation.CommandCompletion; 028import co.aikar.commands.annotation.CommandPermission; -029import co.aikar.commands.annotation.Description; -030import co.aikar.commands.annotation.Syntax; -031import co.aikar.commands.contexts.ContextResolver; -032import com.google.common.collect.ImmutableSet; -033import com.google.common.collect.Lists; -034import com.google.common.collect.Maps; -035import com.google.common.collect.Sets; -036import org.jetbrains.annotations.Nullable; -037 -038import java.lang.reflect.InvocationTargetException; -039import java.lang.reflect.Method; -040import java.lang.reflect.Parameter; -041import java.util.ArrayList; -042import java.util.Collection; -043import java.util.List; -044import java.util.Map; -045import java.util.Set; -046import java.util.stream.Collectors; -047 -048@SuppressWarnings("WeakerAccess") -049public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> { -050 final BaseCommand scope; -051 final String command; -052 final Method method; -053 final String prefSubCommand; +029import co.aikar.commands.annotation.Conditions; +030import co.aikar.commands.annotation.Description; +031import co.aikar.commands.annotation.HelpSearchTags; +032import co.aikar.commands.annotation.Syntax; +033import co.aikar.commands.contexts.ContextResolver; +034import com.google.common.collect.ImmutableSet; +035import com.google.common.collect.Lists; +036import com.google.common.collect.Maps; +037import com.google.common.collect.Sets; +038import org.jetbrains.annotations.Nullable; +039 +040import java.lang.reflect.InvocationTargetException; +041import java.lang.reflect.Method; +042import java.lang.reflect.Parameter; +043import java.util.ArrayList; +044import java.util.Collection; +045import java.util.List; +046import java.util.Map; +047import java.util.Set; +048import java.util.stream.Collectors; +049 +050@SuppressWarnings("WeakerAccess") +051public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> { +052 final BaseCommand scope; +053 final Method method; 054 final CommandParameter<CEC>[] parameters; -055 final String syntaxText; -056 final String helpText; +055 final CommandManager manager; +056 final List<String> registeredSubcommands = new ArrayList<>(); 057 -058 private final String permission; -059 final String complete; -060 final int requiredResolvers; -061 final int optionalResolvers; -062 final List<String> registeredSubcommands = new ArrayList<>(); -063 final CommandManager manager; -064 -065 RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) { -066 this.scope = scope; -067 this.manager = this.scope.manager; -068 CommandReplacements replacements = scope.manager.getCommandReplacements(); +058 String command; +059 String prefSubCommand; +060 String syntaxText; +061 String helpText; +062 String permission; +063 String complete; +064 String conditions; +065 +066 final int requiredResolvers; +067 final int optionalResolvers; +068 public String helpSearchTags; 069 -070 if (BaseCommand.CATCHUNKNOWN.equals(prefSubCommand) || BaseCommand.DEFAULT.equals(prefSubCommand)) { -071 prefSubCommand = ""; -072 } -073 this.command = command + (!method.isAnnotationPresent(CommandAlias.class) && !prefSubCommand.isEmpty() ? prefSubCommand : ""); -074 this.method = method; -075 this.prefSubCommand = prefSubCommand; -076 -077 final CommandPermission permissionAnno = method.getAnnotation(CommandPermission.class); -078 final CommandCompletion completionAnno = method.getAnnotation(CommandCompletion.class); -079 final Description descriptionAnno = method.getAnnotation(Description.class); -080 final Syntax syntaxStr = method.getAnnotation(Syntax.class); +070 RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) { +071 this.scope = scope; +072 this.manager = this.scope.manager; +073 final Annotations annotations = this.manager.getAnnotations(); +074 +075 if (BaseCommand.CATCHUNKNOWN.equals(prefSubCommand) || BaseCommand.DEFAULT.equals(prefSubCommand)) { +076 prefSubCommand = ""; +077 } +078 this.command = command + (!annotations.hasAnnotation(method, CommandAlias.class, false) && !prefSubCommand.isEmpty() ? prefSubCommand : ""); +079 this.method = method; +080 this.prefSubCommand = prefSubCommand; 081 -082 this.permission = permissionAnno != null ? replacements.replace(permissionAnno.value()) : null; -083 this.complete = completionAnno != null ? replacements.replace(completionAnno.value()) : null; -084 Parameter[] parameters = method.getParameters(); -085 //noinspection unchecked -086 this.parameters = new CommandParameter[parameters.length]; -087 this.helpText = descriptionAnno != null ? descriptionAnno.value() : ""; -088 -089 -090 int requiredResolvers = 0; -091 int optionalResolvers = 0; -092 StringBuilder syntaxBuilder = new StringBuilder(64); -093 -094 for (int i = 0; i < parameters.length; i++) { -095 CommandParameter<CEC> parameter = this.parameters[i] = new CommandParameter<>(this, parameters[i], i); -096 if (!parameter.isCommandIssuer()) { -097 if (!parameter.requiresInput()) { -098 optionalResolvers++; -099 } else { -100 requiredResolvers++; -101 } -102 } -103 if (parameter.getSyntax() != null) { -104 if (syntaxBuilder.length() > 0) { -105 syntaxBuilder.append(' '); -106 } -107 syntaxBuilder.append(parameter.getSyntax()); -108 } -109 } -110 String syntaxText = syntaxBuilder.toString().trim(); -111 this.syntaxText = replacements.replace(syntaxStr != null ? -112 ACFUtil.replace(syntaxStr.value(), "@syntax", syntaxText) : syntaxText); -113 this.requiredResolvers = requiredResolvers; -114 this.optionalResolvers = optionalResolvers; -115 } -116 -117 -118 void invoke(CommandIssuer sender, List<String> args, CommandOperationContext context) { -119 if (!scope.canExecute(sender, this)) { -120 return; -121 } -122 preCommand(); -123 try { -124 this.manager.conditions.validateConditions(context); -125 Map<String, Object> passedArgs = resolveContexts(sender, args); -126 if (passedArgs == null) return; -127 -128 method.invoke(scope, passedArgs.values().toArray()); -129 } catch (Exception e) { -130 handleException(sender, args, e); -131 } -132 postCommand(); -133 } -134 public void preCommand() {} -135 public void postCommand() {} -136 -137 void handleException(CommandIssuer sender, List<String> args, Exception e) { -138 if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) { -139 e = (Exception) e.getCause(); -140 } -141 if (e instanceof ShowCommandHelp) { -142 ShowCommandHelp showHelp = (ShowCommandHelp) e; -143 CommandHelp commandHelp = manager.generateCommandHelp(); -144 if (showHelp.search) { -145 commandHelp.setSearch(showHelp.searchArgs == null ? args : showHelp.searchArgs); -146 } -147 commandHelp.showHelp(sender); -148 } else if (e instanceof InvalidCommandArgument) { -149 InvalidCommandArgument invalidCommandArg = (InvalidCommandArgument) e; -150 if (invalidCommandArg.key != null) { -151 sender.sendMessage(MessageType.ERROR, invalidCommandArg.key, invalidCommandArg.replacements); -152 } else if (e.getMessage() != null && !e.getMessage().isEmpty()) { -153 sender.sendMessage(MessageType.ERROR, MessageKeys.ERROR_PREFIX, "{message}", e.getMessage()); -154 } -155 if (invalidCommandArg.showSyntax) { -156 scope.showSyntax(sender, this); +082 this.permission = annotations.getAnnotationValue(method, CommandPermission.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY); +083 this.complete = annotations.getAnnotationValue(method, CommandCompletion.class); +084 this.helpText = annotations.getAnnotationValue(method, Description.class, Annotations.REPLACEMENTS | Annotations.DEFAULT_EMPTY); +085 this.conditions = annotations.getAnnotationValue(method, Conditions.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY); +086 this.helpSearchTags = annotations.getAnnotationValue(method, HelpSearchTags.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY); +087 +088 Parameter[] parameters = method.getParameters(); +089 //noinspection unchecked +090 this.parameters = new CommandParameter[parameters.length]; +091 +092 +093 int requiredResolvers = 0; +094 int optionalResolvers = 0; +095 StringBuilder syntaxBuilder = new StringBuilder(64); +096 +097 for (int i = 0; i < parameters.length; i++) { +098 CommandParameter<CEC> parameter = this.parameters[i] = new CommandParameter<>(this, parameters[i], i); +099 if (!parameter.isCommandIssuer()) { +100 if (!parameter.requiresInput()) { +101 optionalResolvers++; +102 } else { +103 requiredResolvers++; +104 } +105 } +106 if (parameter.getSyntax() != null) { +107 if (syntaxBuilder.length() > 0) { +108 syntaxBuilder.append(' '); +109 } +110 syntaxBuilder.append(parameter.getSyntax()); +111 } +112 } +113 String syntaxText = syntaxBuilder.toString().trim(); +114 final String syntaxStr = annotations.getAnnotationValue(method, Syntax.class); +115 this.syntaxText = syntaxStr != null ? ACFUtil.replace(syntaxStr, "@syntax", syntaxText) : syntaxText; +116 this.requiredResolvers = requiredResolvers; +117 this.optionalResolvers = optionalResolvers; +118 } +119 +120 +121 void invoke(CommandIssuer sender, List<String> args, CommandOperationContext context) { +122 if (!scope.canExecute(sender, this)) { +123 return; +124 } +125 preCommand(); +126 try { +127 this.manager.conditions.validateConditions(context); +128 Map<String, Object> passedArgs = resolveContexts(sender, args); +129 if (passedArgs == null) return; +130 +131 method.invoke(scope, passedArgs.values().toArray()); +132 } catch (Exception e) { +133 handleException(sender, args, e); +134 } +135 postCommand(); +136 } +137 public void preCommand() {} +138 public void postCommand() {} +139 +140 void handleException(CommandIssuer sender, List<String> args, Exception e) { +141 if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) { +142 e = (Exception) e.getCause(); +143 } +144 if (e instanceof ShowCommandHelp) { +145 ShowCommandHelp showHelp = (ShowCommandHelp) e; +146 CommandHelp commandHelp = manager.generateCommandHelp(); +147 if (showHelp.search) { +148 commandHelp.setSearch(showHelp.searchArgs == null ? args : showHelp.searchArgs); +149 } +150 commandHelp.showHelp(sender); +151 } else if (e instanceof InvalidCommandArgument) { +152 InvalidCommandArgument invalidCommandArg = (InvalidCommandArgument) e; +153 if (invalidCommandArg.key != null) { +154 sender.sendMessage(MessageType.ERROR, invalidCommandArg.key, invalidCommandArg.replacements); +155 } else if (e.getMessage() != null && !e.getMessage().isEmpty()) { +156 sender.sendMessage(MessageType.ERROR, MessageKeys.ERROR_PREFIX, "{message}", e.getMessage()); 157 } -158 } else { -159 try { -160 if (!this.manager.handleUncaughtException(scope, this, sender, args, e)) { -161 sender.sendMessage(MessageType.ERROR, MessageKeys.ERROR_PERFORMING_COMMAND); -162 } -163 this.manager.log(LogLevel.ERROR, "Exception in command: " + command + " " + ACFUtil.join(args), e); -164 } catch (Exception e2) { -165 this.manager.log(LogLevel.ERROR, "Exception in handleException for command: " + command + " " + ACFUtil.join(args), e); -166 this.manager.log(LogLevel.ERROR, "Exception triggered by exception handler:", e2); -167 } -168 } -169 } -170 -171 @Nullable -172 Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args) throws InvalidCommandArgument { -173 return resolveContexts(sender, args, parameters.length); -174 } -175 @Nullable -176 Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args, int argLimit) throws InvalidCommandArgument { -177 args = Lists.newArrayList(args); -178 String[] origArgs = args.toArray(new String[args.size()]); -179 Map<String, Object> passedArgs = Maps.newLinkedHashMap(); -180 int remainingRequired = requiredResolvers; -181 CommandOperationContext opContext = CommandManager.getCurrentCommandOperationContext(); -182 for (int i = 0; i < parameters.length && i < argLimit; i++) { -183 boolean isLast = i == parameters.length - 1; -184 boolean allowOptional = remainingRequired == 0; -185 final CommandParameter<CEC> parameter = parameters[i]; -186 final String parameterName = parameter.getName(); -187 final Class<?> type = parameter.getType(); -188 //noinspection unchecked -189 final ContextResolver<?, CEC> resolver = parameter.getResolver(); -190 //noinspection unchecked -191 CEC context = (CEC) this.manager.createCommandContext(this, parameter, sender, args, i, passedArgs); -192 boolean requiresInput = parameter.requiresInput(); -193 if (requiresInput && remainingRequired > 0) { -194 remainingRequired--; -195 } -196 if (args.isEmpty() && !(isLast && type == String[].class)) { -197 if (allowOptional && parameter.getDefaultValue() != null) { -198 args.add(parameter.getDefaultValue()); -199 } else if (allowOptional && parameter.isOptional()) { -200 Object value = parameter.isOptionalResolver() ? resolver.getContext(context) : null; -201 if (value == null && parameter.getClass().isPrimitive()) { -202 throw new IllegalStateException("Parameter " + parameter.getName() + " is primitive and does not support Optional."); -203 } -204 //noinspection unchecked -205 this.manager.conditions.validateConditions(context, value); -206 passedArgs.put(parameterName, value); -207 //noinspection UnnecessaryContinue -208 continue; -209 } else if (requiresInput) { -210 scope.showSyntax(sender, this); -211 return null; -212 } -213 } -214 if (parameter.getValues() != null) { -215 String arg = !args.isEmpty() ? args.get(0) : ""; -216 -217 Set<String> possible = Sets.newHashSet(); -218 CommandCompletions commandCompletions = this.manager.getCommandCompletions(); -219 for (String s : parameter.getValues()) { -220 //noinspection unchecked -221 List<String> check = commandCompletions.getCompletionValues(this, sender, s, origArgs, opContext.isAsync()); -222 if (!check.isEmpty()) { -223 possible.addAll(check.stream().map(String::toLowerCase).collect(Collectors.toList())); -224 } else { -225 possible.add(s.toLowerCase()); -226 } -227 } -228 -229 if (!possible.contains(arg.toLowerCase())) { -230 throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_ONE_OF, -231 "{valid}", ACFUtil.join(possible, ", ")); -232 } -233 } -234 Object paramValue = resolver.getContext(context); -235 //noinspection unchecked -236 this.manager.conditions.validateConditions(context, paramValue); -237 passedArgs.put(parameterName, paramValue); -238 } -239 return passedArgs; -240 } -241 -242 boolean hasPermission(CommandIssuer issuer) { -243 return (permission == null || permission.isEmpty() || scope.manager.hasPermission(issuer, permission)) && scope.hasPermission(issuer); -244 } -245 -246 -247 /** -248 * @see #getRequiredPermissions() -249 * @deprecated -250 */ -251 @Deprecated -252 public String getPermission() { -253 if (this.permission == null || this.permission.isEmpty()) { -254 return null; -255 } -256 return ACFPatterns.COMMA.split(this.permission)[0]; -257 } -258 -259 public Set<String> getRequiredPermissions() { -260 if (this.permission == null || this.permission.isEmpty()) { -261 return ImmutableSet.of(); -262 } -263 return Sets.newHashSet(ACFPatterns.COMMA.split(this.permission)); -264 } -265 -266 public boolean requiresPermission(String permission) { -267 return getRequiredPermissions().contains(permission) || scope.requiresPermission(permission); -268 } -269 -270 public String getPrefSubCommand() { -271 return prefSubCommand; -272 } -273 -274 public String getSyntaxText() { -275 return syntaxText; -276 } -277 -278 public String getCommand() { -279 return command; -280 } -281 -282 public void addSubcommand(String cmd) { -283 this.registeredSubcommands.add(cmd); -284 } -285 public void addSubcommands(Collection<String> cmd) { -286 this.registeredSubcommands.addAll(cmd); +158 if (invalidCommandArg.showSyntax) { +159 scope.showSyntax(sender, this); +160 } +161 } else { +162 try { +163 if (!this.manager.handleUncaughtException(scope, this, sender, args, e)) { +164 sender.sendMessage(MessageType.ERROR, MessageKeys.ERROR_PERFORMING_COMMAND); +165 } +166 this.manager.log(LogLevel.ERROR, "Exception in command: " + command + " " + ACFUtil.join(args), e); +167 } catch (Exception e2) { +168 this.manager.log(LogLevel.ERROR, "Exception in handleException for command: " + command + " " + ACFUtil.join(args), e); +169 this.manager.log(LogLevel.ERROR, "Exception triggered by exception handler:", e2); +170 } +171 } +172 } +173 +174 @Nullable +175 Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args) throws InvalidCommandArgument { +176 return resolveContexts(sender, args, parameters.length); +177 } +178 @Nullable +179 Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args, int argLimit) throws InvalidCommandArgument { +180 args = Lists.newArrayList(args); +181 String[] origArgs = args.toArray(new String[args.size()]); +182 Map<String, Object> passedArgs = Maps.newLinkedHashMap(); +183 int remainingRequired = requiredResolvers; +184 CommandOperationContext opContext = CommandManager.getCurrentCommandOperationContext(); +185 for (int i = 0; i < parameters.length && i < argLimit; i++) { +186 boolean isLast = i == parameters.length - 1; +187 boolean allowOptional = remainingRequired == 0; +188 final CommandParameter<CEC> parameter = parameters[i]; +189 final String parameterName = parameter.getName(); +190 final Class<?> type = parameter.getType(); +191 //noinspection unchecked +192 final ContextResolver<?, CEC> resolver = parameter.getResolver(); +193 //noinspection unchecked +194 CEC context = (CEC) this.manager.createCommandContext(this, parameter, sender, args, i, passedArgs); +195 boolean requiresInput = parameter.requiresInput(); +196 if (requiresInput && remainingRequired > 0) { +197 remainingRequired--; +198 } +199 if (args.isEmpty() && !(isLast && type == String[].class)) { +200 if (allowOptional && parameter.getDefaultValue() != null) { +201 args.add(parameter.getDefaultValue()); +202 } else if (allowOptional && parameter.isOptional()) { +203 Object value = parameter.isOptionalResolver() ? resolver.getContext(context) : null; +204 if (value == null && parameter.getClass().isPrimitive()) { +205 throw new IllegalStateException("Parameter " + parameter.getName() + " is primitive and does not support Optional."); +206 } +207 //noinspection unchecked +208 this.manager.conditions.validateConditions(context, value); +209 passedArgs.put(parameterName, value); +210 //noinspection UnnecessaryContinue +211 continue; +212 } else if (requiresInput) { +213 scope.showSyntax(sender, this); +214 return null; +215 } +216 } +217 if (parameter.getValues() != null) { +218 String arg = !args.isEmpty() ? args.get(0) : ""; +219 +220 Set<String> possible = Sets.newHashSet(); +221 CommandCompletions commandCompletions = this.manager.getCommandCompletions(); +222 for (String s : parameter.getValues()) { +223 //noinspection unchecked +224 List<String> check = commandCompletions.getCompletionValues(this, sender, s, origArgs, opContext.isAsync()); +225 if (!check.isEmpty()) { +226 possible.addAll(check.stream().map(String::toLowerCase).collect(Collectors.toList())); +227 } else { +228 possible.add(s.toLowerCase()); +229 } +230 } +231 +232 if (!possible.contains(arg.toLowerCase())) { +233 throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_ONE_OF, +234 "{valid}", ACFUtil.join(possible, ", ")); +235 } +236 } +237 Object paramValue = resolver.getContext(context); +238 //noinspection unchecked +239 this.manager.conditions.validateConditions(context, paramValue); +240 passedArgs.put(parameterName, paramValue); +241 } +242 return passedArgs; +243 } +244 +245 boolean hasPermission(CommandIssuer issuer) { +246 return (permission == null || permission.isEmpty() || scope.manager.hasPermission(issuer, permission)) && scope.hasPermission(issuer); +247 } +248 +249 +250 /** +251 * @see #getRequiredPermissions() +252 * @deprecated +253 */ +254 @Deprecated +255 public String getPermission() { +256 if (this.permission == null || this.permission.isEmpty()) { +257 return null; +258 } +259 return ACFPatterns.COMMA.split(this.permission)[0]; +260 } +261 +262 public Set<String> getRequiredPermissions() { +263 if (this.permission == null || this.permission.isEmpty()) { +264 return ImmutableSet.of(); +265 } +266 return Sets.newHashSet(ACFPatterns.COMMA.split(this.permission)); +267 } +268 +269 public boolean requiresPermission(String permission) { +270 return getRequiredPermissions().contains(permission) || scope.requiresPermission(permission); +271 } +272 +273 public String getPrefSubCommand() { +274 return prefSubCommand; +275 } +276 +277 public String getSyntaxText() { +278 return syntaxText; +279 } +280 +281 public String getCommand() { +282 return command; +283 } +284 +285 public void addSubcommand(String cmd) { +286 this.registeredSubcommands.add(cmd); 287 } -288} +288 public void addSubcommands(Collection<String> cmd) { +289 this.registeredSubcommands.addAll(cmd); +290 } +291} diff --git a/docs/acf-jda/co/aikar/commands/JDACommandExecutionContext.html b/docs/acf-jda/co/aikar/commands/JDACommandExecutionContext.html index 6081687f..dcad747b 100644 --- a/docs/acf-jda/co/aikar/commands/JDACommandExecutionContext.html +++ b/docs/acf-jda/co/aikar/commands/JDACommandExecutionContext.html @@ -140,7 +140,7 @@ extends co.aikar.commands.CommandExecutionContext<
  • diff --git a/docs/acf-jda/co/aikar/commands/JDARootCommand.html b/docs/acf-jda/co/aikar/commands/JDARootCommand.html index 673aa68f..8f4f258c 100644 --- a/docs/acf-jda/co/aikar/commands/JDARootCommand.html +++ b/docs/acf-jda/co/aikar/commands/JDARootCommand.html @@ -18,7 +18,7 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":18,"i2":18,"i3":18,"i4":10,"i5":10,"i6":18,"i7":10,"i8":10,"i9":10,"i10":18,"i11":18}; +var methods = {"i0":10,"i1":18,"i2":18,"i3":18,"i4":10,"i5":10,"i6":18,"i7":10,"i8":18,"i9":10,"i10":10,"i11":18,"i12":18,"i13":18}; var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"],16:["t5","Default Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; @@ -164,26 +164,34 @@ extends getDefCommand()  +default String +getDescription()  + + co.aikar.commands.CommandManager getManager()  - + com.google.common.collect.SetMultimap<String,co.aikar.commands.RegisteredCommand> getSubCommands()  - + default List<String> getTabCompletions(co.aikar.commands.CommandIssuer arg0, String arg1, String[] arg2)  - + default List<String> getTabCompletions(co.aikar.commands.CommandIssuer arg0, String arg1, String[] arg2, boolean arg3)  + +default String +getUsage()  +
  • Methods inherited from class co.aikar.commands.CommandOperationContext

    -getAnnotation, getArgs, getCommand, getCommandIssuer, getCommandLabel, getCommandManager, getRegisteredCommand, hasAnnotation, isAsync, setRegisteredCommand
  • +getAnnotation, getAnnotationValue, getAnnotationValue, getArgs, getCommand, getCommandIssuer, getCommandLabel, getCommandManager, getRegisteredCommand, hasAnnotation, isAsync, setRegisteredCommand
  • getDefCommand()  +default String +getDescription()  + + Optional<org.spongepowered.api.text.Text> getHelp(@NotNull org.spongepowered.api.command.CommandSource source)  - + co.aikar.commands.CommandManager getManager()  - + Optional<org.spongepowered.api.text.Text> getShortDescription(@NotNull org.spongepowered.api.command.CommandSource source)  - + com.google.common.collect.SetMultimap<String,co.aikar.commands.RegisteredCommand> getSubCommands()  - + List<String> getSuggestions(@NotNull org.spongepowered.api.command.CommandSource source, @NotNull String arguments, org.spongepowered.api.world.Location<org.spongepowered.api.world.World> location)  - + default List<String> getTabCompletions(co.aikar.commands.CommandIssuer arg0, String arg1, String[] arg2)  - + default List<String> getTabCompletions(co.aikar.commands.CommandIssuer arg0, String arg1, String[] arg2, boolean arg3)  - + +default String +getUsage()  + + org.spongepowered.api.text.Text getUsage(@NotNull org.spongepowered.api.command.CommandSource source)  - + org.spongepowered.api.command.CommandResult process(@NotNull org.spongepowered.api.command.CommandSource source, @NotNull String arguments)  - + boolean testPermission(@NotNull org.spongepowered.api.command.CommandSource source)  @@ -322,7 +330,7 @@ implements org.spongepowered.api.command.CommandCallable
    • getHelp

      -
      public Optional<org.spongepowered.api.text.Text> getHelp(@NotNull
      +
      public Optional<org.spongepowered.api.text.Text> getHelp(@NotNull
                                                                @NotNull org.spongepowered.api.command.CommandSource source)
      Specified by:
      @@ -336,7 +344,7 @@ implements org.spongepowered.api.command.CommandCallable
      • getUsage

        -
        public org.spongepowered.api.text.Text getUsage(@NotNull
        +
        public org.spongepowered.api.text.Text getUsage(@NotNull
                                                         @NotNull org.spongepowered.api.command.CommandSource source)
        Specified by:
        @@ -350,7 +358,7 @@ implements org.spongepowered.api.command.CommandCallable
        • addChild

          -
          public void addChild(co.aikar.commands.BaseCommand command)
          +
          public void addChild(co.aikar.commands.BaseCommand command)
        @@ -359,7 +367,7 @@ implements org.spongepowered.api.command.CommandCallable @@ -368,7 +376,7 @@ implements org.spongepowered.api.command.CommandCallable @@ -377,7 +385,7 @@ implements org.spongepowered.api.command.CommandCallable @@ -386,7 +394,7 @@ implements org.spongepowered.api.command.CommandCallable @@ -446,12 +454,30 @@ implements org.spongepowered.api.command.CommandCallable -
      • diff --git a/docs/acf-sponge/src-html/co/aikar/commands/SpongeRootCommand.html b/docs/acf-sponge/src-html/co/aikar/commands/SpongeRootCommand.html index 6cc09542..f169c71d 100644 --- a/docs/acf-sponge/src-html/co/aikar/commands/SpongeRootCommand.html +++ b/docs/acf-sponge/src-html/co/aikar/commands/SpongeRootCommand.html @@ -85,51 +85,53 @@ 077 078 @Override 079 public Optional<Text> getShortDescription(@NotNull CommandSource source) { -080 return Optional.empty(); -081 } -082 -083 @Override -084 public Optional<Text> getHelp(@NotNull CommandSource source) { -085 return Optional.empty(); -086 } -087 -088 @Override -089 public Text getUsage(@NotNull CommandSource source) { -090 return Text.of(); -091 } -092 -093 private CommandResult executeSponge(CommandIssuer sender, String commandLabel, String[] args) { -094 BaseCommand cmd = execute(sender, commandLabel, args); -095 return ((SpongeCommandOperationContext) cmd.lastCommandOperationContext).getResult(); -096 } -097 -098 public void addChild(BaseCommand command) { -099 if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { -100 this.defCommand = command; -101 } -102 addChildShared(this.children, this.subCommands, command); -103 } -104 -105 @Override -106 public BaseCommand getDefCommand(){ -107 return defCommand; -108 } -109 -110 @Override -111 public CommandManager getManager() { -112 return manager; -113 } -114 -115 @Override -116 public SetMultimap<String, RegisteredCommand> getSubCommands() { -117 return subCommands; -118 } -119 -120 @Override -121 public List<BaseCommand> getChildren() { -122 return children; -123 } -124} +080 String description = getDescription(); +081 return description != null ? Optional.of(Text.of(description)) : Optional.empty(); +082 } +083 +084 @Override +085 public Optional<Text> getHelp(@NotNull CommandSource source) { +086 return Optional.empty(); +087 } +088 +089 @Override +090 public Text getUsage(@NotNull CommandSource source) { +091 String usage = getUsage(); +092 return usage != null ? Text.of(usage) : Text.of(); +093 } +094 +095 private CommandResult executeSponge(CommandIssuer sender, String commandLabel, String[] args) { +096 BaseCommand cmd = execute(sender, commandLabel, args); +097 return ((SpongeCommandOperationContext) cmd.lastCommandOperationContext).getResult(); +098 } +099 +100 public void addChild(BaseCommand command) { +101 if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { +102 this.defCommand = command; +103 } +104 addChildShared(this.children, this.subCommands, command); +105 } +106 +107 @Override +108 public BaseCommand getDefCommand(){ +109 return defCommand; +110 } +111 +112 @Override +113 public CommandManager getManager() { +114 return manager; +115 } +116 +117 @Override +118 public SetMultimap<String, RegisteredCommand> getSubCommands() { +119 return subCommands; +120 } +121 +122 @Override +123 public List<BaseCommand> getChildren() { +124 return children; +125 } +126}