Validation

Bean Validation (JSR-380) integration with built-in file validators and custom constraint support.

Crest integrates with Bean Validation (JSR-380) to validate command parameters before the command method executes. If validation fails, the framework reports the error to the user automatically.

Built-in Validators

Crest provides built-in validation annotations for common file system checks:

  • @Exists – the file or directory must exist
  • @Readable – the file must be readable
  • @Writable – the file must be writable
  • @Executable – the file must be executable
  • @Directory – the path must be a directory

These annotations can be combined on a single parameter:

@Command
public void process(@Option("input") @Exists @Readable final File input,
                    @Option("output") @Directory final File outDir) { ... }

If the user provides a path that does not exist for --input, the framework reports a validation error before the command runs.

Custom Validators

Create custom validation annotations using the standard @Constraint mechanism from Bean Validation. Define the annotation and its validator class together:

@Exists
@Constraint(validatedBy = {IsFile.Constraint.class})
@Target({PARAMETER})
@Retention(RUNTIME)
public @interface IsFile {
    String message() default "{org.example.IsFile.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    class Constraint implements ConstraintValidator<IsFile, File> {
        @Override
        public boolean isValid(final File file,
                               final ConstraintValidatorContext ctx) {
            return file.isFile();
        }
    }
}

This @IsFile annotation composes @Exists (so the file must exist) and adds its own check that the path is a regular file (not a directory). Use it on command parameters just like the built-in annotations:

@Command
public void analyze(@Option("config") @IsFile final File config,
                    @Option("output") @Directory @Writable final File outDir) { ... }

Validation on Wrapper Types

Bean Validation annotations can also be placed on constructor parameters of domain wrapper types. This lets you centralize validation logic in the type itself:

public class Port {
    private final int value;

    public Port(@Min(1) @Max(65535) final String port) {
        this.value = Integer.parseInt(port);
    }

    public int get() { return value; }
}