Kiss My App

Tuesday, November 30, 2004

Annotation Inheritance Part 1

With the new metadata JSR, the group decided no to allow any extensibility or inhertance with Annotations themselves (the spec only describes inheritance of annotated properties on objects themselves). I started to think about how a system could check for user defined annotations (since things like instanceof will not work). e.g. Being able to label a property with a Validator annotation, but then allow user defined Validators that have properties like smallest and largest value, or even a money Validator. Here's kind of what I'm thinking (whiteboard quality)--



@Retention(RetentionPolicy.RUNTIME);
public @interface Validator {
Class value();
}

@Validator(IntegerRangeValidatorInstance.class);
public @interface IntegerRangeValidator {
int start() default 0;
int end() default Integer.MAX_VALUE;
}

public class IntegerRangeValidatorInstance
implements ValidatorInstance {

protected int start;
protected int end;

public void setStart(int start) {
this.start = start;
}
public void setEnd(int end) {
this.end = end;
}

public ValidationError validate(Object value) {
try {
int ivalue = Integer.parseInt(
value.toString());
if (ivalue > end || ivalue < start) {
return new ValidationError(
"Value must be between "
+start+" and "+end+".");
}
} catch (Exception e) {
return new ValidationError("not an integer");
}
return null;
}
}

Now, how this ends up getting validated is by doing depth first searches on the properties and classes you are modifying for type Validator.class. It's not hard to concieve a recursive method that walks through an annotation from a method or class, get it's type, and then ask it for it's annotations until there are no more to get, or we've found a Validator annotation type.


In theory, once we've found a Validator type, instantiate class value, and if the Validator was a parent of the another annotation, use it's annoationType to reflect out the properties defined, and assign them to the instantiated class via setter injection. Now that we have a complete instance of the actual Validator object, then we can call some method on it to validate the input. Since Annotations are static, we can do lots for caching created validator for even higher performance.

I will probably try to hack something up tonight and post it on this blog as soon as I can.

2 Comments:

Post a Comment

<< Home