Skip to content

Instantly share code, notes, and snippets.

@pianovwork
Last active April 23, 2019 02:45
Show Gist options
  • Save pianovwork/964f7844f96f7df2f649a697e23f1935 to your computer and use it in GitHub Desktop.
Save pianovwork/964f7844f96f7df2f649a697e23f1935 to your computer and use it in GitHub Desktop.
JSR-303 OneOf
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = OneOfValidator.class)
public @interface OneOf {
String MESSAGE = "{" + "validation.constraints.OneOf.message" + "}";
String message() default MESSAGE;
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
String[] value();
/** if TRUE null and empty string will be skipped, otherwise it will try to find it in a defined 'value' list */
boolean canBeEmpty() default true;
}
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Validates a given object's String representation to match one of the provided values.
*/
public class OneOfValidator implements ConstraintValidator<OneOf, Object> {
/**
* String array of possible enum values
*/
private String[] values;
private boolean canBeEmpty;
@Override
public void initialize(final OneOf constraintAnnotation) {
this.values = constraintAnnotation.value();
this.canBeEmpty = constraintAnnotation.canBeEmpty();
}
@Override
public boolean isValid(final Object value, final ConstraintValidatorContext context) {
String str = value == null ? null : String.valueOf(value);
return canBeEmpty && StringUtils.isBlank(str)
|| ArrayUtils.contains(this.values, str);
}
}
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class OneOfValidatorTest {
@Test
public void isValid() throws Exception {
Object bean = new Object() {
@OneOf(value = "valid_value", canBeEmpty = false)
String field = "valid_value";
};
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Object>> errors = validator.validate(bean);
assertTrue(errors.isEmpty());
}
@Test
public void isInvalid() throws Exception {
Object bean = new Object() {
@OneOf(value = "valid_value", canBeEmpty = false)
String field = "invalid_value";
};
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Object>> errors = validator.validate(bean);
assertEquals(1, errors.size());
assertEquals("must be one of [valid_value]", errors.iterator().next().getMessage());
}
@Test
public void isInvalid_missing_value() throws Exception {
Object bean = new Object() {
@OneOf(value = "valid_value", canBeEmpty = false)
String field = null;
};
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Object>> errors = validator.validate(bean);
assertEquals(1, errors.size());
assertEquals("must be one of [valid_value]", errors.iterator().next().getMessage());
}
@Test
public void isInvalid_missing_value_ok() throws Exception {
Object bean = new Object() {
@OneOf(value = "valid_value")
String field = " ";
};
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Object>> errors = validator.validate(bean);
assertTrue(errors.isEmpty());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment