Interface ParameterParser
-
public interface ParameterParser
A parser that can semantically parse and validate a command parameter string according to a defined usage string syntax and return the parsed parameters, optionally converted to given types.The usage string has to follow this pre-defined format for non-typed parameters:
- Placeholders for free text without whitespaces (in the value) look like
<my placeholder>
-
One placeholder for free text with whitespaces (in the value) is allowed as effectively last parameter
and looks like
<my placeholder...>
- Literal parameters look like
'literal'
- Optional parts are enclosed in square brackets like
[<optional placeholder>]
-
Alternatives are enclosed in parentheses and are separated by pipe characters
like
('all' | 'some' | 'none')
- Whitespace characters between the defined tokens are optional and ignored
@Usage("<coin type> <amount>")
@Usage("['all'] ['exact']")
@Usage("[<text...>]")
@Usage("(<targetLanguage> '|' | <sourceLanguage> <targetLanguage>) <text...>")
String
s unless multiple parameters with the same name have a value given by the user like with the pattern<foo> <foo>
, in which case the value will be aList<String>
.For typed parameters the format is almost the same. The only difference is, that a colon (
:
) followed by a parameter type can optionally be added after a parameter name like for example<amount:integer>
. Parameters that do not have a type specified, are implicitly of typestring
. If a colon is needed within the actual parameter name, a type has to be specified explicitly, as invalid parameter types are not allowed and will trigger an error at runtime.To inject the parameter parser for non-typed parameters, just inject this interface. For the typed parser, add the qualifier
@Typed
to the injected field or parameter.Warning: If you for example have
- an optional placeholder followed by an optional literal like in
[<placeholder>] ['literal']
or - alternatively a placeholder or literal like in
(<placeholder> | 'literal')
literal
, it could fit in both parameter slots. You have to decide yourself in which slot it belongs. For cases where the literal parameter can never be meant for the placeholder, you can useParameters.fixup(String, String)
to correct the parameters instance for the two given parameters. - Placeholders for free text without whitespaces (in the value) look like
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static interface
ParameterParser.Typed
A CDI qualifier that is used for selecting the typed parameter parser instead of the non-typed one which is injected by default.
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description <V> Parameters<V>
parse(CommandContext<?> commandContext)
Returns the parsed parameters for the usage of the command that was triggered by the given command context with an optional implicit downcast for the values.
-
-
-
Method Detail
-
parse
<V> Parameters<V> parse(CommandContext<?> commandContext)
Returns the parsed parameters for the usage of the command that was triggered by the given command context with an optional implicit downcast for the values. The resulting parameters instance will have the placeholder names and literal parameters as keys and the actual supplied arguments as values. In case of the typed parser the values are the converted ones. If multiple placeholders with the same name have a value like with the pattern<foo> <foo>
, the values are returned asList<?>
for that parameter.If only a certain class is queried from the parameters instance, or there is anyway only a certain class present, the returned reference can implicitly downcast the values by using
ParameterParser
to define the class. One example for this is the non-typed parser with a usage definition where a parameter name cannot be assigned twice by the user where all values areString
s.V
can be defined using an explicit type parameter like with
or using implicit type inference like withparameterParser.<String>parse(...).get("placeholder").map(String::intern);
Parameters<String> parameters = parameterParser.parse(commandContext);
If multiple unrelated classes are needed, this method should not be called multiple times to produce parameters instances with different value types, as each time the parameter string has to be parsed and each time the arguments need to be converted if necessary. Instead use
Parameters<Object>
orParameters<? super Object>
and then use the downcasting methods ofParameters
, includingParameters.getParameters()
to downcast the whole instance, to further narrow down the value type.Warning: Be aware that choosing
V
must be done wisely as it is an unsafe operation. If you for example selectString
forV
and then try to get aUser
object from the returned parameters instance, you will get aClassCastException
at runtime.Warning: If you for example have
- an optional placeholder followed by an optional literal like in
[<placeholder>] ['literal']
or - alternatively a placeholder or literal like in
(<placeholder> | 'literal')
literal
, it could fit in both parameter slots. You have to decide yourself in which slot it belongs. For cases where the literal parameter can never be meant for the placeholder, you can useParameters.fixup(String, String)
to correct the parameters instance for the two given parameters.- Type Parameters:
V
- the class to which the values are implicitly downcasted- Parameters:
commandContext
- the command context, usually fully populated but not necessarily- Returns:
- the parsed and converted parameters
- Throws:
ParameterParseException
- if the parameter string does not adhere to the usage pattern of the given command, which includes that there are arguments given when none were expected; the message is suitable to be directly forwarded to end usersInvalidParameterFormatException
- for the typed parameter parser if the format of a parameter is invalid and could not be parsed; the message should be suitable to be directly forwarded to end usersInvalidParameterValueException
- for the typed parameter parser if the value of a parameter is invalid, for example the id of an unknown user was given; the message should be suitable to be directly forwarded to end users- See Also:
Parameters.fixup(String, String)
- an optional placeholder followed by an optional literal like in
-
-