description | icon |
---|---|
This page explains how to create ParameterValidators that perform checks against parameters after they are supplied by the user. |
binary-circle-check |
The ParameterValidator
interface is a part of the commands framework that allows you to perform custom validation on command parameters. This can be particularly useful when you want to enforce specific rules or constraints on command inputs, such as validating ranges, formats, or other criteria.
Let's create an example of a custom ParameterValidator
that checks if a number is within a specified range. This validator will make use of a custom annotation called @Range
to specify the minimum and maximum allowed values.
First, we'll create a custom annotation @Range
to specify the minimum and maximum values for our parameter:
{% tabs %} {% tab title="Java" %}
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Range {
double min();
double max();
}
{% endtab %}
{% tab title="Kotlin" %}
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Range(val min: Double, val max: Double)
{% endtab %} {% endtabs %}
Next, we implement the RangeValidator
using the ParameterValidator
interface. This validator checks the parameter value against the @Range
annotation's constraints:
{% tabs %} {% tab title="Java" %}
public enum RangeValidator implements ParameterValidator<CommandActor, Number> {
INSTANCE;
@Override
public void validate(@NotNull CommandActor actor, Number value, @NotNull ParameterNode<CommandActor, Number> parameter, @NotNull Lamp<CommandActor> lamp) {
Range range = parameter.getAnnotation(Range.class);
if (range == null) return;
double d = value.doubleValue();
if (d < range.min())
throw new CommandErrorException("Specified value (" + d + ") is less than minimum " + range.min());
if (d > range.max())
throw new CommandErrorException("Specified value (" + d + ") is greater than maximum " + range.max());
}
}
{% endtab %}
{% tab title="Kotlin" %}
object RangeValidator : ParameterValidator<CommandActor, Number> {
override fun validate(
actor: CommandActor,
value: Number,
parameter: ParameterNode<CommandActor, Number>,
lamp: Lamp<CommandActor>
) {
val range = parameter.getAnnotation(Range::class.java) ?: return
val d = value.toDouble()
if (d < range.min)
throw CommandErrorException("Specified value ($d) is less than minimum ${range.min}")
if (d > range.max)
throw CommandErrorException("Specified value ($d) is greater than maximum ${range.max}")
}
}
{% endtab %} {% endtabs %}
To use the RangeValidator
, you need to register it with your Lamp
instance. This is done through the Lamp.Builder
:
{% tabs %} {% tab title="Java" %}
var lamp = Lamp.builder()
.parameterValidator(Number.class, RangeValidator.INSTANCE)
.build();
{% endtab %}
{% tab title="Kotlin" %}
val lamp = Lamp.builder<CommandActor>()
.parameterValidator(Number::class.java, RangeValidator)
.build()
{% endtab %} {% endtabs %}
Now, you can use the @Range
annotation in your command methods to specify the valid range for numeric parameters:
{% tabs %} {% tab title="Java" %}
@Command("age")
public void setAge(CommandActor actor, @Range(min = 13, max = 99) int age) {
/* ... */
}
{% endtab %}
{% tab title="Kotlin" %}
@Command("age")
fun setAge(actor: CommandActor, @Range(min = 13.0, max = 99.0) age: Int) {
/* ... */
}
{% endtab %} {% endtabs %}
In this example, the setAge
command requires the age
parameter to be between 18 and 99. If the user provides a value outside this range, the RangeValidator
will throw an exception, and Lamp will handle it appropriately.