I am trying to write a custom annotation that would validate a String
against a specific Enum
. I am using Hibernate Validator API
. The desired use-case would look like follows.
@MessageTypeOf(MessageType.NETWORK)
private String message;
The String
should be validated against the value given from the toString()
method of the enum given as the enum argument (in this case, MessageType.NETWORK
).
I have written a validator and looks like this.
public class MessageTypeValidator implements ConstraintValidator<MessageTypeOf, String> {
private Set<String> values;
@Override
public void initialize(MessageTypeOf constraintAnnotation) {
values = Arrays.asList(MessageType.values())
.stream()
.map(v -> v.toString())
.collect(Collectors.toSet());
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (s == null) return false;
return values.contains(s);
}
}
And the annotation.
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = MessageTypeValidator.class)
@Documented
public @interface MessageTypeOf {
String message() default "{org.hibernate.validator.referenceguide.chapter06.CheckCase." +
"message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
MessageType value();
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@interface List {
MessageType[] value();
}
}
However, this would validate if a string is part of the enum (any value), where as I need to validate against a specific one. Could someone suggest how to do that?
So, basically, the only valid value of the property would be MessageType.NETWORK.toString()
, is that right? That's quite strange (expecting the client to provide a string that can only have one valid value), but anyway, you just need to check that:
public class MessageTypeValidator implements ConstraintValidator<MessageTypeOf, String> {
private String validValue;
@Override
public void initialize(MessageTypeOf constraintAnnotation) {
this.validValue = constraintAnnotation.value().toString();
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
return this.validValue.equals(s);
}
}