I have the following annotation class
public @interface Size {
int min() default 1;
int max() default 100;
String message() default "Age between min - max";
}
Here at the default message()
I want the default value of min()
and max()
. Simply writing String message() default "Age between" + min() + "-" + max();
doesn't work here. Is there any direct way to do it?
EDIT 1: I have a person class too
public class Person {
@Size(max = 10)
private String name;
@Size(min = 18, message = "Age can not be less than {min}")
private int age;
public Person(String s, int i) {
this.name = s;
this.age = i;
}
}
Now, Here the min()
and max()
value can be set. Therefore if the user gives wrong input then the message()
will be printer accordingly.
EDIT 2:
As @nicolas wanted. Here the AnnonatedValidator
class that validated the inputs and print error message.
public class AnnotatedValidator {
public static void validate(Person p, List<ValidationError> errors) {
try {
Field[] fields = p.getClass().getDeclaredFields();
for(Field field : fields) {
if(field.getType().equals(String.class)){
field.setAccessible(true);
String string = (String)field.get(p);
Annotation[] annotationsName = field.getDeclaredAnnotations();
for (Annotation annotation : annotationsName){
if (annotation instanceof Size){
Size size = (Size) annotation;
if (string.length() < size.min() || string.length() > size.max()) {
error(size, errors);
}
}
}
} else if (field.getType().equals(int.class)) {
field.setAccessible(true);
int integer = (Integer)field.get(p);
Annotation[] annotationsAge = field.getDeclaredAnnotations();
for (Annotation annotation : annotationsAge){
if (annotation instanceof Size){
Size size = (Size) annotation;
if (integer < size.min() || integer > size.max()) {
error(size,errors);
}
}
}
}
}
}catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void print(List<ValidationError> errors) {
for (int i = 0; i < errors.size(); i++){
System.out.println("Errors: " + errors.get(i).getError());
}
}
public static void error (Size size, List<ValidationError> errors) {
String error = size.message();
if (!error.equals(null)) {
if (error.contains("min")) {
error = error.replace("min", ""+size.min());
}
if (error.contains("max")){
error = error.replace("max", ""+size.max());
}
}
ValidationError v = new ValidationError();
v.setError(error);
errors.add(v);
}
}
ValidationError
is an another class that just saves the errors.
No,
default
values forString
types must be constant expressions, as the Java Language Specification dictates.An invocation of another annotation element is not a constant expression.
You would need to handle this in the component that manages the use of the annotation. Declare the
default
message as some special value.then check for it while constructing the message. For example