diff --git a/docs/acf-bukkit/co/aikar/commands/BukkitCommandExecutionContext.html b/docs/acf-bukkit/co/aikar/commands/BukkitCommandExecutionContext.html index 8acc3c9e..834ba0f3 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-bungee/co/aikar/commands/BungeeCommandExecutionContext.html b/docs/acf-bungee/co/aikar/commands/BungeeCommandExecutionContext.html index ebdfa056..d2d8b943 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-core/co/aikar/commands/CommandContexts.html b/docs/acf-core/co/aikar/commands/CommandContexts.html index 70355c28..e6066735 100644 --- a/docs/acf-core/co/aikar/commands/CommandContexts.html +++ b/docs/acf-core/co/aikar/commands/CommandContexts.html @@ -249,7 +249,7 @@ extends

    registerSenderAwareContext

    @Deprecated
    -public <T> void registerSenderAwareContext(Class<T> context,
    +public <T> void registerSenderAwareContext(Class<T> context,
                                                            IssuerAwareContextResolver<T,R> supplier)
    Deprecated. Please switch to registerIssuerAwareContext(Class, IssuerAwareContextResolver) as the core wants to use the platform agnostic term of "Issuer" instead of Sender
    @@ -265,7 +265,7 @@ public <T> void 
  • registerIssuerAwareContext

    -
    public <T> void registerIssuerAwareContext(Class<T> context,
    +
    public <T> void registerIssuerAwareContext(Class<T> context,
                                                IssuerAwareContextResolver<T,R> supplier)
    Registers a context resolver that may conditionally consume input, falling back to using the context of the issuer to potentially fulfill this context. @@ -279,7 +279,7 @@ public <T> void 
  • registerIssuerOnlyContext

    -
    public <T> void registerIssuerOnlyContext(Class<T> context,
    +
    public <T> void registerIssuerOnlyContext(Class<T> context,
                                               IssuerOnlyContextResolver<T,R> supplier)
    Registers a context resolver that will never consume input. It will always satisfy its context based on the issuer of the command, so it will not appear in syntax strings.
    @@ -291,7 +291,7 @@ public <T> void 
  • registerOptionalContext

    -
    public <T> void registerOptionalContext(Class<T> context,
    +
    public <T> void registerOptionalContext(Class<T> context,
                                             OptionalContextResolver<T,R> supplier)
    Registers a context that can safely accept a null input from the command issuer to resolve. This resolver should always call CommandExecutionContext.popFirstArg()
    @@ -303,7 +303,7 @@ public <T> void 
  • registerContext

    -
    public <T> void registerContext(Class<T> context,
    +
    public <T> void registerContext(Class<T> context,
                                     ContextResolver<T,R> supplier)
    Registers a context that requires input from the command issuer to resolve. This resolver should always call CommandExecutionContext.popFirstArg()
    @@ -315,7 +315,7 @@ public <T> void 
  • getResolver

    -
    public ContextResolver<?,RgetResolver(Class<?> type)
    +
    public ContextResolver<?,RgetResolver(Class<?> type)
  • diff --git a/docs/acf-core/co/aikar/commands/CommandExecutionContext.html b/docs/acf-core/co/aikar/commands/CommandExecutionContext.html index 54bd39f3..b96c75f2 100644 --- a/docs/acf-core/co/aikar/commands/CommandExecutionContext.html +++ b/docs/acf-core/co/aikar/commands/CommandExecutionContext.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}; +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,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":10}; var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; @@ -160,93 +160,142 @@ extends getArgs()  +Boolean +getBooleanFlagValue(String flag)  + + +Boolean +getBooleanFlagValue(String flag, + Boolean def)  + + RegisteredCommand getCmd()  - + +Double +getDoubleFlagValue(String flag, + Number def)  + + String getFirstArg()  - + Map<String,String> getFlags()  - + +Double +getFlagValue(String flag, + Double def)  + + +Float +getFlagValue(String flag, + Float def)  + + Integer getFlagValue(String flag, Integer def)  - + +Long +getFlagValue(String flag, + Long def)  + + +Double +getFlagValue(String flag, + Number def)  + + String getFlagValue(String flag, String def)  - + +Float +getFloatFlagValue(String flag, + Number def)  + + int getIndex()  - + +Integer +getIntFlagValue(String flag, + Number def)  + + I getIssuer()  - + String getLastArg()  - + +Long +getLongFlagValue(String flag, + Number def)  + + int getNumParams()  - + Parameter getParam()  - + Map<String,Object> getPassedArgs()  - + Object getResolvedArg(Class<?>... classes)  - + Object getResolvedArg(String arg)  - + <T> T getResolvedArg(String key, Class<?>... classes)  - + <T extends Annotation>
    boolean
    hasAnnotation(Class<T> cls)  - + boolean hasFlag(String flag)  - + boolean isLastArg()  - + boolean isOptional()  - + String joinArgs()  - + String joinArgs(String sep)  - + String popFirstArg()  - + String popLastArg()  @@ -395,7 +444,7 @@ extends
  • hasFlag

    -
    public boolean hasFlag(String flag)
    +
    public boolean hasFlag(String flag)
  • @@ -404,7 +453,7 @@ extends
  • getFlagValue

    -
    public String getFlagValue(String flag,
    +
    public String getFlagValue(String flag,
                                String def)
  • @@ -414,17 +463,116 @@ extends
  • getFlagValue

    -
    public Integer getFlagValue(String flag,
    +
    public Integer getFlagValue(String flag,
                                 Integer def)
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -433,7 +581,7 @@ extends
  • hasAnnotation

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

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

    -
    public Parameter getParam()
    +
    public Parameter getParam()
  • @@ -460,7 +608,7 @@ extends
  • getIssuer

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

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

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

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

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

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

    -
    public String joinArgs(String sep)
    +
    public String joinArgs(String sep)
  • diff --git a/docs/acf-core/co/aikar/commands/CommandParameter.html b/docs/acf-core/co/aikar/commands/CommandParameter.html index cff00753..75ccc01b 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}; +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 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
  • @@ -184,66 +184,74 @@ extends 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)  - + void setFlags(Map<String,String> flags)  - + void setOptional(boolean optional)  - + void setOptionalResolver(boolean optionalResolver)  - + void setRequiresInput(boolean requiresInput)  - + void setResolver(ContextResolver<?,CEC> resolver)  - + +void +setSyntax(String syntax)  + + void setValues(String[] values)  @@ -275,7 +283,7 @@ extends
  • CommandParameter

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    -
    public boolean isOptionalResolver()
    +
    public boolean isOptionalResolver()
  • @@ -501,16 +509,34 @@ extends
  • requiresInput

    -
    public boolean requiresInput()
    +
    public boolean requiresInput()
  • -
      + + + + + + + + + diff --git a/docs/acf-core/co/aikar/commands/RegisteredCommand.html b/docs/acf-core/co/aikar/commands/RegisteredCommand.html index 33aff09d..75bc52f4 100644 --- a/docs/acf-core/co/aikar/commands/RegisteredCommand.html +++ b/docs/acf-core/co/aikar/commands/RegisteredCommand.html @@ -198,7 +198,7 @@ extends
    • preCommand

      -
      public void preCommand()
      +
      public void preCommand()
    @@ -207,7 +207,7 @@ extends
  • postCommand

    -
    public void postCommand()
    +
    public void postCommand()
  • @@ -217,7 +217,7 @@ extends

    getPermission

    @Deprecated
    -public String getPermission()
    +public String getPermission()
    Deprecated. 
    See Also:
    @@ -231,7 +231,7 @@ public 
  • getRequiredPermissions

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

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

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

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

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

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

    -
    public void addSubcommands(Collection<String> cmd)
    +
    public void addSubcommands(Collection<String> cmd)
  • diff --git a/docs/acf-core/index-all.html b/docs/acf-core/index-all.html index 64c723d8..462dace6 100644 --- a/docs/acf-core/index-all.html +++ b/docs/acf-core/index-all.html @@ -458,6 +458,10 @@
     
    getArgs() - Method in class co.aikar.commands.CommandOperationContext
     
    +
    getBooleanFlagValue(String) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    +
    getBooleanFlagValue(String, Boolean) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    getCause(Throwable) - Static method in class co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil
    Introspects the Throwable to obtain the cause.
    @@ -568,6 +572,8 @@
     
    getDescription() - Method in class co.aikar.commands.HelpEntry
     
    +
    getDoubleFlagValue(String, Number) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    getEnumFromName(T[], String) - Static method in class co.aikar.commands.ACFUtil
     
    getEnumFromName(T[], String, T) - Static method in class co.aikar.commands.ACFUtil
    @@ -594,6 +600,16 @@
     
    getFlagValue(String, Integer) - Method in class co.aikar.commands.CommandExecutionContext
     
    +
    getFlagValue(String, Long) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    +
    getFlagValue(String, Float) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    +
    getFlagValue(String, Double) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    +
    getFlagValue(String, Number) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    +
    getFloatFlagValue(String, Number) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    getFormat(MessageType) - Method in class co.aikar.commands.CommandManager
     
    getFormatReplacements(HelpEntry) - Method in class co.aikar.commands.CommandHelp
    @@ -610,6 +626,8 @@
     
    getInput() - Method in class co.aikar.commands.CommandCompletionContext
     
    +
    getIntFlagValue(String, Number) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    getIssuer() - Method in class co.aikar.commands.CommandCompletionContext
     
    getIssuer() - Method in class co.aikar.commands.CommandExecutionContext
    @@ -628,6 +646,8 @@
    Returns a Locales Manager to add and modify language tables for your commands.
    +
    getLongFlagValue(String, Number) - Method in class co.aikar.commands.CommandExecutionContext
    +
     
    getManager() - Method in class co.aikar.commands.CommandHelp
     
    getManager() - Method in interface co.aikar.commands.CommandIssuer
    @@ -713,6 +733,8 @@
    Gets a list of all currently supported languages for this manager.
    +
    getSyntax() - Method in class co.aikar.commands.CommandParameter
    +
     
    getSyntaxText() - Method in class co.aikar.commands.RegisteredCommand
     
    getThrowable(int) - Method in interface co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil.Nestable
    @@ -1519,6 +1541,8 @@
     
    setSearchScore(int) - Method in class co.aikar.commands.HelpEntry
     
    +
    setSyntax(String) - Method in class co.aikar.commands.CommandParameter
    +
     
    setValues(String[]) - Method in class co.aikar.commands.CommandParameter
     
    shouldShow() - Method in class co.aikar.commands.HelpEntry
    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 f4ce8905..428bfac0 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html @@ -55,77 +55,77 @@ 047 this.manager = manager; 048 registerContext(Short.class, (c) -> { 049 try { -050 return parseAndValidateNumber(c, Short.MAX_VALUE).shortValue(); +050 return parseAndValidateNumber(c, Short.MIN_VALUE, Short.MAX_VALUE).shortValue(); 051 } catch (NumberFormatException e) { 052 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 053 } 054 }); 055 registerContext(short.class, (c) -> { 056 try { -057 return parseAndValidateNumber(c, Short.MAX_VALUE).shortValue(); +057 return parseAndValidateNumber(c, Short.MIN_VALUE, Short.MAX_VALUE).shortValue(); 058 } catch (NumberFormatException e) { 059 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 060 } 061 }); 062 registerContext(Integer.class, (c) -> { 063 try { -064 return parseAndValidateNumber(c, Integer.MAX_VALUE).intValue(); +064 return parseAndValidateNumber(c, Integer.MIN_VALUE, Integer.MAX_VALUE).intValue(); 065 } catch (NumberFormatException e) { 066 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 067 } 068 }); 069 registerContext(int.class, (c) -> { 070 try { -071 return parseAndValidateNumber(c, Integer.MAX_VALUE).intValue(); +071 return parseAndValidateNumber(c, Integer.MIN_VALUE, Integer.MAX_VALUE).intValue(); 072 } catch (NumberFormatException e) { 073 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 074 } 075 }); 076 registerContext(Long.class, (c) -> { 077 try { -078 return parseAndValidateNumber(c, Long.MAX_VALUE).longValue(); +078 return parseAndValidateNumber(c, Long.MIN_VALUE, Long.MAX_VALUE).longValue(); 079 } catch (NumberFormatException e) { 080 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 081 } 082 }); 083 registerContext(long.class, (c) -> { 084 try { -085 return parseAndValidateNumber(c, Long.MAX_VALUE).longValue(); +085 return parseAndValidateNumber(c, Long.MIN_VALUE, Long.MAX_VALUE).longValue(); 086 } catch (NumberFormatException e) { 087 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 088 } 089 }); 090 registerContext(Float.class, (c) -> { 091 try { -092 return parseAndValidateNumber(c, Float.MAX_VALUE).floatValue(); +092 return parseAndValidateNumber(c, Float.MIN_VALUE, Float.MAX_VALUE).floatValue(); 093 } catch (NumberFormatException e) { 094 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 095 } 096 }); 097 registerContext(float.class, (c) -> { 098 try { -099 return parseAndValidateNumber(c, Float.MAX_VALUE).floatValue(); +099 return parseAndValidateNumber(c, Float.MIN_VALUE, Float.MAX_VALUE).floatValue(); 100 } catch (NumberFormatException e) { 101 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 102 } 103 }); 104 registerContext(Double.class, (c) -> { 105 try { -106 return parseAndValidateNumber(c, Double.MAX_VALUE).doubleValue(); +106 return parseAndValidateNumber(c, Double.MIN_VALUE, Double.MAX_VALUE).doubleValue(); 107 } catch (NumberFormatException e) { 108 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 109 } 110 }); 111 registerContext(double.class, (c) -> { 112 try { -113 return parseAndValidateNumber(c, Double.MAX_VALUE).doubleValue(); +113 return parseAndValidateNumber(c, Double.MIN_VALUE, Double.MAX_VALUE).doubleValue(); 114 } catch (NumberFormatException e) { 115 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 116 } 117 }); 118 registerContext(Number.class, (c) -> { 119 try { -120 return parseAndValidateNumber(c, Double.MAX_VALUE); +120 return parseAndValidateNumber(c, Double.MIN_VALUE, Double.MAX_VALUE); 121 } catch (NumberFormatException e) { 122 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); 123 } @@ -133,7 +133,7 @@ 125 registerContext(BigDecimal.class, (c) -> { 126 try { 127 BigDecimal number = ACFUtil.parseBigNumber(c.popFirstArg(), c.hasFlag("suffixes")); -128 validateMinMax(c, number, null); +128 validateMinMax(c, number); 129 return number; 130 } catch (NumberFormatException e) { 131 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); @@ -142,7 +142,7 @@ 134 registerContext(BigInteger.class, (c) -> { 135 try { 136 BigDecimal number = ACFUtil.parseBigNumber(c.popFirstArg(), c.hasFlag("suffixes")); -137 validateMinMax(c, number, null); +137 validateMinMax(c, number); 138 return number.toBigIntegerExact(); 139 } catch (NumberFormatException e) { 140 throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", c.getFirstArg()); @@ -250,86 +250,88 @@ 242 } 243 244 @NotNull -245 private Number parseAndValidateNumber(R c, Number maxValue) throws InvalidCommandArgument { -246 Number val = ACFUtil.parseNumber(c.getFirstArg(), c.hasFlag("suffixes")); -247 validateMinMax(c, val, maxValue); -248 c.popFirstArg(); // pop later so we can have a chance to display a nicer error message -249 return val; -250 } -251 -252 private void validateMinMax(R c, Number val, Number maxValue) throws InvalidCommandArgument { -253 Number minValue = c.getFlagValue("min", (Integer) null); -254 maxValue = c.getFlagValue("max", maxValue != null ? maxValue.intValue() : null); -255 if (maxValue != null && val.doubleValue() > maxValue.doubleValue()) { -256 throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_AT_MOST, "{max}", String.valueOf(maxValue)); -257 } -258 if (minValue != null && val.doubleValue() < minValue.doubleValue()) { -259 throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_AT_LEAST, "{min}", String.valueOf(minValue)); -260 } -261 } -262 -263 -264 /** -265 * @deprecated Please switch to {@link #registerIssuerAwareContext(Class, IssuerAwareContextResolver)} -266 * as the core wants to use the platform agnostic term of "Issuer" instead of Sender -267 * @see #registerIssuerAwareContext(Class, IssuerAwareContextResolver) -268 */ -269 @Deprecated -270 public <T> void registerSenderAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { -271 contextMap.put(context, supplier); -272 } -273 -274 /** -275 * Registers a context resolver that may conditionally consume input, falling back to using the context of the -276 * issuer to potentially fulfill this context. -277 * You may call {@link CommandExecutionContext#getFirstArg()} and then conditionally call {@link CommandExecutionContext#popFirstArg()} -278 * if you want to consume that input. -279 */ -280 public <T> void registerIssuerAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { -281 contextMap.put(context, supplier); -282 } -283 -284 /** -285 * Registers a context resolver that will never consume input. It will always satisfy its context based on the -286 * issuer of the command, so it will not appear in syntax strings. -287 */ -288 public <T> void registerIssuerOnlyContext(Class<T> context, IssuerOnlyContextResolver<T, R> supplier) { -289 contextMap.put(context, supplier); -290 } -291 -292 /** -293 * Registers a context that can safely accept a null input from the command issuer to resolve. This resolver should always -294 * call {@link CommandExecutionContext#popFirstArg()} -295 */ -296 public <T> void registerOptionalContext(Class<T> context, OptionalContextResolver<T, R> supplier) { -297 contextMap.put(context, supplier); -298 } -299 -300 /** -301 * Registers a context that requires input from the command issuer to resolve. This resolver should always -302 * call {@link CommandExecutionContext#popFirstArg()} -303 */ -304 public <T> void registerContext(Class<T> context, ContextResolver<T, R> supplier) { -305 contextMap.put(context, supplier); -306 } -307 -308 public ContextResolver<?, R> getResolver(Class<?> type) { -309 Class<?> rootType = type; -310 do { -311 if (type == Object.class) { -312 break; -313 } -314 -315 final ContextResolver<?, R> resolver = contextMap.get(type); -316 if (resolver != null) { -317 return resolver; -318 } -319 } while ((type = type.getSuperclass()) != null); -320 -321 this.manager.log(LogLevel.ERROR, "Could not find context resolver", new IllegalStateException("No context resolver defined for " + rootType.getName())); -322 return null; -323 } -324} +245 private Number parseAndValidateNumber(R c, Number minValue, Number maxValue) throws InvalidCommandArgument { +246 final Number val = ACFUtil.parseNumber(c.popFirstArg(), c.hasFlag("suffixes")); +247 validateMinMax(c, val, minValue, maxValue); +248 return val; +249 } +250 +251 private void validateMinMax(R c, Number val) throws InvalidCommandArgument { +252 validateMinMax(c, val, null, null); +253 } +254 private void validateMinMax(R c, Number val, Number minValue, Number maxValue) throws InvalidCommandArgument { +255 minValue = c.getFlagValue("min", minValue); +256 maxValue = c.getFlagValue("max", maxValue); +257 if (maxValue != null && val.doubleValue() > maxValue.doubleValue()) { +258 throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_AT_MOST, "{max}", String.valueOf(maxValue)); +259 } +260 if (minValue != null && val.doubleValue() < minValue.doubleValue()) { +261 throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_AT_LEAST, "{min}", String.valueOf(minValue)); +262 } +263 } +264 +265 +266 /** +267 * @deprecated Please switch to {@link #registerIssuerAwareContext(Class, IssuerAwareContextResolver)} +268 * as the core wants to use the platform agnostic term of "Issuer" instead of Sender +269 * @see #registerIssuerAwareContext(Class, IssuerAwareContextResolver) +270 */ +271 @Deprecated +272 public <T> void registerSenderAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { +273 contextMap.put(context, supplier); +274 } +275 +276 /** +277 * Registers a context resolver that may conditionally consume input, falling back to using the context of the +278 * issuer to potentially fulfill this context. +279 * You may call {@link CommandExecutionContext#getFirstArg()} and then conditionally call {@link CommandExecutionContext#popFirstArg()} +280 * if you want to consume that input. +281 */ +282 public <T> void registerIssuerAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { +283 contextMap.put(context, supplier); +284 } +285 +286 /** +287 * Registers a context resolver that will never consume input. It will always satisfy its context based on the +288 * issuer of the command, so it will not appear in syntax strings. +289 */ +290 public <T> void registerIssuerOnlyContext(Class<T> context, IssuerOnlyContextResolver<T, R> supplier) { +291 contextMap.put(context, supplier); +292 } +293 +294 /** +295 * Registers a context that can safely accept a null input from the command issuer to resolve. This resolver should always +296 * call {@link CommandExecutionContext#popFirstArg()} +297 */ +298 public <T> void registerOptionalContext(Class<T> context, OptionalContextResolver<T, R> supplier) { +299 contextMap.put(context, supplier); +300 } +301 +302 /** +303 * Registers a context that requires input from the command issuer to resolve. This resolver should always +304 * call {@link CommandExecutionContext#popFirstArg()} +305 */ +306 public <T> void registerContext(Class<T> context, ContextResolver<T, R> supplier) { +307 contextMap.put(context, supplier); +308 } +309 +310 public ContextResolver<?, R> getResolver(Class<?> type) { +311 Class<?> rootType = type; +312 do { +313 if (type == Object.class) { +314 break; +315 } +316 +317 final ContextResolver<?, R> resolver = contextMap.get(type); +318 if (resolver != null) { +319 return resolver; +320 } +321 } while ((type = type.getSuperclass()) != null); +322 +323 this.manager.log(LogLevel.ERROR, "Could not find context resolver", new IllegalStateException("No context resolver defined for " + rootType.getName())); +324 return null; +325 } +326} 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 a644c228..1eb64bda 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandExecutionContext.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandExecutionContext.html @@ -121,61 +121,106 @@ 113 public boolean isOptional() { 114 return param.isOptional(); 115 } -116 public boolean hasFlag(String flag) { -117 return flags.containsKey(flag); -118 } -119 -120 public String getFlagValue(String flag, String def) { -121 return flags.getOrDefault(flag, def); -122 } -123 -124 public Integer getFlagValue(String flag, Integer def) { -125 return ACFUtil.parseInt(this.flags.get(flag), def); -126 } -127 -128 public <T extends Annotation> T getAnnotation(Class<T> cls) { -129 return param.getParameter().getAnnotation(cls); -130 } -131 -132 public <T extends Annotation> boolean hasAnnotation(Class<T> cls) { -133 return param.getParameter().isAnnotationPresent(cls); -134 } -135 -136 public RegisteredCommand getCmd() { -137 return this.cmd; -138 } -139 -140 public Parameter getParam() { -141 return this.param.getParameter(); -142 } -143 -144 public I getIssuer() { -145 return this.issuer; -146 } -147 -148 public List<String> getArgs() { -149 return this.args; -150 } -151 -152 public int getIndex() { -153 return this.index; -154 } -155 -156 public Map<String, Object> getPassedArgs() { -157 return this.passedArgs; -158 } -159 -160 public Map<String, String> getFlags() { -161 return this.flags; -162 } -163 -164 public String joinArgs() { -165 return ACFUtil.join(args, " "); -166 } -167 public String joinArgs(String sep) { -168 return ACFUtil.join(args, sep); -169 } -170} +116 +117 public boolean hasFlag(String flag) { +118 return flags.containsKey(flag); +119 } +120 +121 public String getFlagValue(String flag, String def) { +122 return flags.getOrDefault(flag, def); +123 } +124 +125 public Integer getFlagValue(String flag, Integer def) { +126 return ACFUtil.parseInt(this.flags.get(flag), def); +127 } +128 +129 public Long getFlagValue(String flag, Long def) { +130 return ACFUtil.parseLong(this.flags.get(flag), def); +131 } +132 +133 public Float getFlagValue(String flag, Float def) { +134 return ACFUtil.parseFloat(this.flags.get(flag), def); +135 } +136 +137 public Double getFlagValue(String flag, Double def) { +138 return ACFUtil.parseDouble(this.flags.get(flag), def); +139 } +140 +141 public Integer getIntFlagValue(String flag, Number def) { +142 return ACFUtil.parseInt(this.flags.get(flag), def != null ? def.intValue() : null); +143 } +144 +145 public Long getLongFlagValue(String flag, Number def) { +146 return ACFUtil.parseLong(this.flags.get(flag), def != null ? def.longValue() : null); +147 } +148 +149 public Float getFloatFlagValue(String flag, Number def) { +150 return ACFUtil.parseFloat(this.flags.get(flag), def != null ? def.floatValue() : null); +151 } +152 +153 public Double getDoubleFlagValue(String flag, Number def) { +154 return ACFUtil.parseDouble(this.flags.get(flag), def != null ? def.doubleValue() : null); +155 } +156 +157 public Boolean getBooleanFlagValue(String flag) { +158 return getBooleanFlagValue(flag, false); +159 } +160 +161 public Boolean getBooleanFlagValue(String flag, Boolean def) { +162 String val = this.flags.get(flag); +163 if (val == null) { +164 return def; +165 } +166 return ACFUtil.isTruthy(val); +167 } +168 +169 public Double getFlagValue(String flag, Number def) { +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); +214 } +215} 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 3bba04ae..e9433039 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandParameter.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandParameter.html @@ -35,210 +35,233 @@ 027import co.aikar.commands.annotation.Description; 028import co.aikar.commands.annotation.Flags; 029import co.aikar.commands.annotation.Optional; -030import co.aikar.commands.annotation.Values; -031import co.aikar.commands.contexts.ContextResolver; -032import co.aikar.commands.contexts.IssuerAwareContextResolver; -033import co.aikar.commands.contexts.IssuerOnlyContextResolver; -034import co.aikar.commands.contexts.OptionalContextResolver; -035import com.google.common.collect.Maps; -036 -037import java.lang.reflect.Parameter; -038import java.util.Map; -039 -040public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> { -041 private final Parameter parameter; -042 private final Class<?> type; -043 private final String name; -044 private final CommandManager manager; -045 private final int paramIndex; -046 private ContextResolver<?, CEC> resolver; -047 private boolean optional; -048 private String description; -049 private String defaultValue; -050 private boolean requiresInput; -051 private boolean commandIssuer; -052 private String[] values; -053 private Map<String, String> flags; -054 private boolean canConsumeInput; -055 private boolean optionalResolver; -056 -057 public CommandParameter(RegisteredCommand<CEC> command, Parameter param, int paramIndex) { -058 this.parameter = param; -059 this.type = param.getType(); -060 this.name = param.getName(); // do we care for an annotation to supply name? -061 //noinspection unchecked -062 this.manager = command.manager; -063 this.paramIndex = paramIndex; -064 CommandReplacements replacements = manager.getCommandReplacements(); -065 -066 Default defaultAnno = param.getAnnotation(Default.class); -067 Description descAnno = param.getAnnotation(Description.class); +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 //noinspection unchecked -070 this.resolver = manager.getCommandContexts().getResolver(type); -071 if (this.resolver == null) { -072 ACFUtil.sneaky(new InvalidCommandContextException( -073 "Parameter " + type.getSimpleName() + " of " + command + " has no applicable context resolver" -074 )); -075 } -076 -077 this.description = descAnno != null ? descAnno.value() : null; -078 String defaultValue = defaultAnno != null ? replacements.replace(defaultAnno.value()) : null; -079 this.defaultValue = defaultValue != null && (type == String.class || !defaultValue.isEmpty()) ? defaultValue : null; -080 -081 -082 this.optional = param.isAnnotationPresent(Optional.class) || this.defaultValue != null; -083 this.optionalResolver = isOptionalResolver(resolver); -084 this.requiresInput = !this.optional && !this.optionalResolver; -085 //noinspection unchecked -086 this.commandIssuer = manager.isCommandIssuer(type); -087 this.canConsumeInput = !(resolver instanceof IssuerOnlyContextResolver); -088 -089 final Values values = param.getAnnotation(Values.class); -090 if (values != null) { -091 this.values = ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(values.value())); -092 } else { -093 this.values = null; -094 } -095 this.flags = Maps.newHashMap(); -096 Flags flags = param.getAnnotation(Flags.class); -097 if (flags != null) { -098 parseFlags(flags.value()); -099 } -100 inheritContextFlags(command.scope); -101 } -102 -103 private void inheritContextFlags(BaseCommand scope) { -104 if (!scope.contextFlags.isEmpty()) { -105 Class<?> pCls = this.type; -106 do { -107 parseFlags(scope.contextFlags.get(pCls)); -108 } while ((pCls = pCls.getSuperclass()) != null); +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); +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 if (scope.parentCommand != null) { -111 inheritContextFlags(scope.parentCommand); -112 } -113 } -114 -115 private void parseFlags(String flags) { -116 if (flags != null) { -117 for (String s : ACFPatterns.COMMA.split(manager.getCommandReplacements().replace(flags))) { -118 String[] v = ACFPatterns.EQUALS.split(s, 2); -119 if (!this.flags.containsKey(v[0])) { -120 this.flags.put(v[0], v.length > 1 ? v[1] : null); -121 } -122 } -123 } -124 } -125 -126 private boolean isOptionalResolver(ContextResolver<?, CEC> resolver) { -127 return resolver instanceof IssuerAwareContextResolver -128 || resolver instanceof IssuerOnlyContextResolver -129 || resolver instanceof OptionalContextResolver; -130 } -131 -132 -133 public Parameter getParameter() { -134 return parameter; -135 } -136 -137 public Class<?> getType() { -138 return type; -139 } -140 -141 public String getName() { -142 return name; -143 } -144 -145 public CommandManager getManager() { -146 return manager; -147 } +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 } +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 int getParamIndex() { -150 return paramIndex; +149 public Parameter getParameter() { +150 return parameter; 151 } 152 -153 public ContextResolver<?, CEC> getResolver() { -154 return resolver; +153 public Class<?> getType() { +154 return type; 155 } 156 -157 public void setResolver(ContextResolver<?, CEC> resolver) { -158 this.resolver = resolver; +157 public String getName() { +158 return name; 159 } 160 -161 public boolean isOptional() { -162 return optional; +161 public CommandManager getManager() { +162 return manager; 163 } 164 -165 public void setOptional(boolean optional) { -166 this.optional = optional; +165 public int getParamIndex() { +166 return paramIndex; 167 } 168 -169 public String getDescription() { -170 return description; +169 public ContextResolver<?, CEC> getResolver() { +170 return resolver; 171 } 172 -173 public void setDescription(String description) { -174 this.description = description; +173 public void setResolver(ContextResolver<?, CEC> resolver) { +174 this.resolver = resolver; 175 } 176 -177 public String getDefaultValue() { -178 return defaultValue; +177 public boolean isOptional() { +178 return optional; 179 } 180 -181 public void setDefaultValue(String defaultValue) { -182 this.defaultValue = defaultValue; +181 public void setOptional(boolean optional) { +182 this.optional = optional; 183 } 184 -185 public boolean isCommandIssuer() { -186 return commandIssuer; +185 public String getDescription() { +186 return description; 187 } 188 -189 public void setCommandIssuer(boolean commandIssuer) { -190 this.commandIssuer = commandIssuer; +189 public void setDescription(String description) { +190 this.description = description; 191 } 192 -193 public String[] getValues() { -194 return values; +193 public String getDefaultValue() { +194 return defaultValue; 195 } 196 -197 public void setValues(String[] values) { -198 this.values = values; +197 public void setDefaultValue(String defaultValue) { +198 this.defaultValue = defaultValue; 199 } 200 -201 public Map<String, String> getFlags() { -202 return flags; +201 public boolean isCommandIssuer() { +202 return commandIssuer; 203 } 204 -205 public void setFlags(Map<String, String> flags) { -206 this.flags = flags; +205 public void setCommandIssuer(boolean commandIssuer) { +206 this.commandIssuer = commandIssuer; 207 } 208 -209 public boolean canConsumeInput() { -210 return canConsumeInput; +209 public String[] getValues() { +210 return values; 211 } 212 -213 public void setCanConsumeInput(boolean canConsumeInput) { -214 this.canConsumeInput = canConsumeInput; +213 public void setValues(String[] values) { +214 this.values = values; 215 } 216 -217 public void setOptionalResolver(boolean optionalResolver) { -218 this.optionalResolver = optionalResolver; +217 public Map<String, String> getFlags() { +218 return flags; 219 } 220 -221 public boolean isOptionalResolver() { -222 return optionalResolver; +221 public void setFlags(Map<String, String> flags) { +222 this.flags = flags; 223 } 224 -225 public boolean requiresInput() { -226 return requiresInput; +225 public boolean canConsumeInput() { +226 return canConsumeInput; 227 } 228 -229 public void setRequiresInput(boolean requiresInput) { -230 this.requiresInput = requiresInput; +229 public void setCanConsumeInput(boolean canConsumeInput) { +230 this.canConsumeInput = canConsumeInput; 231 } 232 -233} +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} 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 f9d3a027..3aeec899 100644 --- a/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html +++ b/docs/acf-core/src-html/co/aikar/commands/RegisteredCommand.html @@ -73,225 +73,227 @@ 065 RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) { 066 this.scope = scope; 067 this.manager = this.scope.manager; -068 if (BaseCommand.CATCHUNKNOWN.equals(prefSubCommand) || BaseCommand.DEFAULT.equals(prefSubCommand)) { -069 prefSubCommand = ""; -070 } -071 this.command = command + (method.getAnnotation(CommandAlias.class) == null && !prefSubCommand.isEmpty() ? prefSubCommand : ""); -072 this.method = method; -073 this.prefSubCommand = prefSubCommand; -074 CommandPermission permissionAnno = method.getAnnotation(CommandPermission.class); -075 this.permission = permissionAnno != null ? scope.manager.getCommandReplacements().replace(permissionAnno.value()) : null; -076 CommandCompletion completionAnno = method.getAnnotation(CommandCompletion.class); -077 this.complete = completionAnno != null ? scope.manager.getCommandReplacements().replace(completionAnno.value()) : null; -078 Parameter[] parameters = method.getParameters(); -079 //noinspection unchecked -080 this.parameters = new CommandParameter[parameters.length]; +068 CommandReplacements replacements = scope.manager.getCommandReplacements(); +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); 081 -082 Description descriptionAnno = method.getAnnotation(Description.class); -083 this.helpText = descriptionAnno != null ? descriptionAnno.value() : ""; -084 final Syntax syntaxStr = method.getAnnotation(Syntax.class); -085 -086 -087 int requiredResolvers = 0; -088 int optionalResolvers = 0; -089 StringBuilder syntaxB = new StringBuilder(64); -090 -091 for (int i = 0; i < parameters.length; i++) { -092 CommandParameter<CEC> parameter = this.parameters[i] = new CommandParameter<>(this, parameters[i], i); +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 if (!parameter.isCommandIssuer()) { -095 String name = parameter.getName(); -096 if (!parameter.requiresInput()) { -097 optionalResolvers++; -098 if (parameter.canConsumeInput()) { -099 syntaxB.append('[').append(name).append("] "); -100 } -101 } else { -102 requiredResolvers++; -103 syntaxB.append('<').append(name).append("> "); -104 } -105 } -106 -107 } -108 String syntaxText = syntaxB.toString(); -109 this.syntaxText = this.manager.getCommandReplacements().replace(syntaxStr != null ? -110 ACFUtil.replace(syntaxStr.value(), "@syntax", syntaxText) : syntaxText); -111 this.requiredResolvers = requiredResolvers; -112 this.optionalResolvers = optionalResolvers; -113 } -114 -115 -116 void invoke(CommandIssuer sender, List<String> args, CommandOperationContext context) { -117 if (!scope.canExecute(sender, this)) { -118 return; -119 } -120 preCommand(); -121 try { -122 this.manager.conditions.validateConditions(context); -123 Map<String, Object> passedArgs = resolveContexts(sender, args); -124 if (passedArgs == null) return; -125 -126 method.invoke(scope, passedArgs.values().toArray()); -127 } catch (Exception e) { -128 handleException(sender, args, e); -129 } -130 postCommand(); -131 } -132 public void preCommand() {} -133 public void postCommand() {} -134 -135 void handleException(CommandIssuer sender, List<String> args, Exception e) { -136 if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) { -137 e = (Exception) e.getCause(); -138 } -139 if (e instanceof ShowCommandHelp) { -140 ShowCommandHelp showHelp = (ShowCommandHelp) e; -141 CommandHelp commandHelp = manager.generateCommandHelp(); -142 if (showHelp.search) { -143 commandHelp.setSearch(showHelp.searchArgs == null ? args : showHelp.searchArgs); -144 } -145 commandHelp.showHelp(sender); -146 } else if (e instanceof InvalidCommandArgument) { -147 InvalidCommandArgument invalidCommandArg = (InvalidCommandArgument) e; -148 if (invalidCommandArg.key != null) { -149 sender.sendMessage(MessageType.ERROR, invalidCommandArg.key, invalidCommandArg.replacements); -150 } else if (e.getMessage() != null && !e.getMessage().isEmpty()) { -151 sender.sendMessage(MessageType.ERROR, MessageKeys.ERROR_PREFIX, "{message}", e.getMessage()); -152 } -153 if (invalidCommandArg.showSyntax) { -154 scope.showSyntax(sender, this); -155 } -156 } else { -157 try { -158 if (!this.manager.handleUncaughtException(scope, this, sender, args, e)) { -159 sender.sendMessage(MessageType.ERROR, MessageKeys.ERROR_PERFORMING_COMMAND); -160 } -161 this.manager.log(LogLevel.ERROR, "Exception in command: " + command + " " + ACFUtil.join(args), e); -162 } catch (Exception e2) { -163 this.manager.log(LogLevel.ERROR, "Exception in handleException for command: " + command + " " + ACFUtil.join(args), e); -164 this.manager.log(LogLevel.ERROR, "Exception triggered by exception handler:", e2); -165 } -166 } -167 } -168 -169 @Nullable -170 Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args) throws InvalidCommandArgument { -171 return resolveContexts(sender, args, parameters.length); -172 } -173 @Nullable -174 Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args, int argLimit) throws InvalidCommandArgument { -175 args = Lists.newArrayList(args); -176 String[] origArgs = args.toArray(new String[args.size()]); -177 Map<String, Object> passedArgs = Maps.newLinkedHashMap(); -178 int remainingRequired = requiredResolvers; -179 CommandOperationContext opContext = CommandManager.getCurrentCommandOperationContext(); -180 for (int i = 0; i < parameters.length && i < argLimit; i++) { -181 boolean isLast = i == parameters.length - 1; -182 boolean allowOptional = remainingRequired == 0; -183 final CommandParameter<CEC> parameter = parameters[i]; -184 final String parameterName = parameter.getName(); -185 final Class<?> type = parameter.getType(); -186 //noinspection unchecked -187 final ContextResolver<?, CEC> resolver = parameter.getResolver(); +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); +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 CEC context = (CEC) this.manager.createCommandContext(this, parameter, sender, args, i, passedArgs); -190 boolean requiresInput = parameter.requiresInput(); -191 if (requiresInput && remainingRequired > 0) { -192 remainingRequired--; -193 } -194 if (args.isEmpty() && !(isLast && type == String[].class)) { -195 if (allowOptional && parameter.getDefaultValue() != null) { -196 args.add(parameter.getDefaultValue()); -197 } else if (allowOptional && parameter.isOptional()) { -198 Object value = parameter.isOptionalResolver() ? resolver.getContext(context) : null; -199 if (value == null && parameter.getClass().isPrimitive()) { -200 throw new IllegalStateException("Parameter " + parameter.getName() + " is primitive and does not support Optional."); -201 } -202 //noinspection unchecked -203 this.manager.conditions.validateConditions(context, value); -204 passedArgs.put(parameterName, value); -205 //noinspection UnnecessaryContinue -206 continue; -207 } else if (requiresInput) { -208 scope.showSyntax(sender, this); -209 return null; -210 } -211 } -212 if (parameter.getValues() != null) { -213 String arg = !args.isEmpty() ? args.get(0) : ""; -214 -215 Set<String> possible = Sets.newHashSet(); -216 CommandCompletions commandCompletions = this.manager.getCommandCompletions(); -217 for (String s : parameter.getValues()) { -218 //noinspection unchecked -219 List<String> check = commandCompletions.getCompletionValues(this, sender, s, origArgs, opContext.isAsync()); -220 if (!check.isEmpty()) { -221 possible.addAll(check.stream().map(String::toLowerCase).collect(Collectors.toList())); -222 } else { -223 possible.add(s.toLowerCase()); -224 } -225 } -226 -227 if (!possible.contains(arg.toLowerCase())) { -228 throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_ONE_OF, -229 "{valid}", ACFUtil.join(possible, ", ")); -230 } -231 } -232 Object paramValue = resolver.getContext(context); -233 //noinspection unchecked -234 this.manager.conditions.validateConditions(context, paramValue); -235 passedArgs.put(parameterName, paramValue); -236 } -237 return passedArgs; -238 } -239 -240 boolean hasPermission(CommandIssuer issuer) { -241 return (permission == null || permission.isEmpty() || scope.manager.hasPermission(issuer, permission)) && scope.hasPermission(issuer); -242 } -243 -244 -245 /** -246 * @see #getRequiredPermissions() -247 * @deprecated -248 */ -249 @Deprecated -250 public String getPermission() { -251 if (this.permission == null || this.permission.isEmpty()) { -252 return null; -253 } -254 return ACFPatterns.COMMA.split(this.permission)[0]; -255 } -256 -257 public Set<String> getRequiredPermissions() { -258 if (this.permission == null || this.permission.isEmpty()) { -259 return ImmutableSet.of(); -260 } -261 return Sets.newHashSet(ACFPatterns.COMMA.split(this.permission)); -262 } -263 -264 public boolean requiresPermission(String permission) { -265 return getRequiredPermissions().contains(permission) || scope.requiresPermission(permission); -266 } -267 -268 public String getPrefSubCommand() { -269 return prefSubCommand; -270 } -271 -272 public String getSyntaxText() { -273 return syntaxText; -274 } -275 -276 public String getCommand() { -277 return command; -278 } -279 -280 public void addSubcommand(String cmd) { -281 this.registeredSubcommands.add(cmd); -282 } -283 public void addSubcommands(Collection<String> cmd) { -284 this.registeredSubcommands.addAll(cmd); -285 } -286} +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); +287 } +288} diff --git a/docs/acf-jda/co/aikar/commands/JDACommandExecutionContext.html b/docs/acf-jda/co/aikar/commands/JDACommandExecutionContext.html index 2804a57f..6081687f 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-sponge/co/aikar/commands/SpongeCommandExecutionContext.html b/docs/acf-sponge/co/aikar/commands/SpongeCommandExecutionContext.html index 6c9c9675..1d0eec63 100644 --- a/docs/acf-sponge/co/aikar/commands/SpongeCommandExecutionContext.html +++ b/docs/acf-sponge/co/aikar/commands/SpongeCommandExecutionContext.html @@ -162,7 +162,7 @@ extends co.aikar.commands.CommandExecutionContext<