Validators
Validators check option/argument values before the command executes. Validation errors abort execution and display a message to the user.
There are two kinds: OptionValidator checks a single option’s value, and CommandValidator checks the command as a whole (useful for cross-option constraints).
OptionValidator
Validates individual options or arguments after conversion:
public interface OptionValidator<T extends ValidatorInvocation> {
void validate(T validatorInvocation) throws OptionValidatorException;
}The ValidatorInvocation provides:
getValue()– the converted value (already the target type, not a String)getCommand()– the command instance being populatedgetAeshContext()– the current Æsh context
Example: Port Range Validator
import org.aesh.command.validator.OptionValidator;
import org.aesh.command.validator.OptionValidatorException;
import org.aesh.command.validator.ValidatorInvocation;
public class PortValidator implements OptionValidator<ValidatorInvocation> {
@Override
public void validate(ValidatorInvocation invocation) throws OptionValidatorException {
int port = (int) invocation.getValue();
if (port < 1 || port > 65535) {
throw new OptionValidatorException(
"Port must be between 1 and 65535, got: " + port);
}
if (port < 1024) {
throw new OptionValidatorException(
"Ports below 1024 require root privileges. Use a port >= 1024.");
}
}
}Use it with @Option:
@CommandDefinition(name = "server", description = "Start the server")
public class ServerCommand implements Command<CommandInvocation> {
@Option(
name = "port",
validator = PortValidator.class,
description = "Server port (1024-65535)"
)
private int port = 8080;
@Override
public CommandResult execute(CommandInvocation invocation) {
invocation.println("Starting server on port " + port);
return CommandResult.SUCCESS;
}
}$ server --port 80
Ports below 1024 require root privileges. Use a port >= 1024.
$ server --port 9090
Starting server on port 9090CommandValidator
Validates the entire command after all options are parsed. This is where you check constraints between options:
public interface CommandValidator<C extends Command<CI>, CI extends CommandInvocation> {
void validate(C command) throws CommandValidatorException;
}Example: Cross-Option Validation
import org.aesh.command.validator.CommandValidator;
import org.aesh.command.validator.CommandValidatorException;
import org.aesh.command.invocation.CommandInvocation;
public class ServerCommandValidator
implements CommandValidator<ServerCommand, CommandInvocation> {
@Override
public void validate(ServerCommand command) throws CommandValidatorException {
if (command.useSSL && command.sslCertPath == null) {
throw new CommandValidatorException(
"SSL requires a certificate path. Use --cert <path>.");
}
if (command.port == 443 && !command.useSSL) {
throw new CommandValidatorException(
"Port 443 is reserved for HTTPS. Add --ssl or use a different port.");
}
}
}Reference the validator in @CommandDefinition:
@CommandDefinition(
name = "server",
description = "Start the server",
validator = ServerCommandValidator.class
)
public class ServerCommand implements Command<CommandInvocation> {
@Option(name = "port", description = "Server port")
int port = 80;
@Option(name = "ssl", hasValue = false, description = "Enable SSL")
boolean useSSL = false;
@Option(name = "cert", description = "SSL certificate path")
String sslCertPath;
@Override
public CommandResult execute(CommandInvocation invocation) {
String protocol = useSSL ? "https" : "http";
invocation.println("Starting " + protocol + " server on port " + port);
return CommandResult.SUCCESS;
}
}$ server --ssl
SSL requires a certificate path. Use --cert <path>.
$ server --ssl --cert /etc/ssl/server.pem
Starting https server on port 80Validation Order
- Each option’s value is converted (String to target type)
- Each option’s OptionValidator runs (if specified)
- All options are set on the command object
- The CommandValidator runs (if specified)
execute()is called
If any step fails, execution stops and the error message is displayed.
Validator vs Converter
- Validators check whether a value is acceptable. They answer: “Is this value allowed?”
- Converters transform the input string into a typed value. They answer: “What does this string mean?”
Use a validator when the type is standard (int, String, File) but only certain values are valid. Use a Converter when you need a custom type.