Java validation framework
Simple and extensible validator pattern implementation with sensible defaults
Why?
How many times You had to implement Validator Pattern? Or maybe how many times You wish you did? This java library provides some easy and extensible interfaces to introduce consistent way of validation through your application.
Usage
Add library dependency:
compile "com.github.bgalek.utils:validation-framework:1.0.0"
Let's assume a very simple class to validate:
public class MovieCharacter {
public final String value;
}
Use provided implementations:
DefaultValidator
Validations are processed respecting declaration order. Will return a PositiveValidationResult
only when all validations are successful, otherwise, it stops at first fail encountered and returns: NegativeValidationResult
Validator<MovieCharacter> characterValidator = Validator.of(MovieCharacter.class)
.validation(movieStar -> movieStar.value.length() > 0, "name needs to has to be at least 1 character long")
.validation(movieStar -> Character.isUpperCase(movieStar.value.charAt(0)), "name needs to start with uppercase letter")
.validation(movieStar -> movieStar.value.length() < 50, "name needs to has to be shorter than 50 characters")
.ensure();
DefaultValidator with exception instead of validation result
Validations are processed respecting declaration order. Will return a PositiveValidationResult
only when all validations are successful, otherwise, it stops at first fail encountered and throws provided exception.
Validator<MovieCharacter> characterValidator = Validator.of(MovieCharacter.class)
.validation(movieStar -> movieStar.value.length() > 0, "name needs to has to be at least 1 character long")
.validation(movieStar -> Character.isUpperCase(movieStar.value.charAt(0)), "name needs to start with uppercase letter")
.validation(movieStar -> movieStar.value.length() < 50, "name needs to has to be shorter than 50 characters")
.ensure(IllegalArgumentException::new);
SummaryValidator
Validations are processed respecting declaration order. Will return a ValidationSummary
containing passed and failed validations.
SummaryValidator<MovieCharacter> characterValidator = Validator.of(MovieCharacter.class)
.validation(movieStar -> movieStar.value.startsWith("A"), "only names starting with A allowed")
.validation(movieStar -> movieStar.value.split(" ").length == 2, "has to contain name and surname")
.validation(movieStar -> movieStar.value.endsWith("Z"), "only names ending with Z allowed")
.summary();
Extending
You can implement your own validators
class SystemOutValidator<T> implements Validator<T> {
private final Map<Predicate<T>, String> validations;
public SystemOutValidator(Map<Predicate<T>, String> validations) {
this.validations = validations;
}
@Override
public ValidationResult<T> validate(T subject) {
validations.forEach((key, value) -> System.out.println("processing: " + value));
return new PositiveValidationResult<>(subject, new HashSet<>(validations.values()));
}
}
and use them like this:
Validator<MovieCharacter> customValidator = Validator.of(MovieCharacter.class, SystemOutValidator::new)
.validation(movieStar -> movieStar.value.length() > 0, "name needs to has to be at least 1 character long")
.validation(movieStar -> movieStar.value.length() < 50, "name needs to has to be shorter than 50 characters")
.ensure();
Check out unit tests for more examples!