-新Validationプラン
。。。ということで、出来たみたい。ValidatorもConvertorもPOJOでいけるなあ。
public interface NewValidationAPI { @Retention(RUNTIME) @Target({METHOD}) public @interface Variable { } @Retention(RUNTIME) @Target({METHOD}) public @interface Execute { } @Retention(RUNTIME) @Target({ANNOTATION_TYPE}) public @interface Validator { Class delegateTo(); } }
public interface MyValidation { @Retention(RUNTIME) @Target({METHOD}) @Validator(delegateTo=LengthValidatorImpl.class) public @interface LengthValidator { int min() default -1; int max() default -1; } public class LengthValidatorImpl { private int _min = -1; private int _max = -1; @Variable public void setMin(int min) { _min = min; } @Variable public void setMax(int max) { _max = max; } @Execute public void validate(String value) throws Throwable { if(value == null) { new Throwable("null"); } int len = value.length(); if(_min != -1 && len < _min) { throw new Throwable("min"); } if(_max != -1 && _max < len) { throw new Throwable("max"); } } } }
public class NewValidationRunTest extends TestCase { public void testRun() throws Throwable { //++ lazy initialization. final Class pageModel = ValidationTestRunModel.class; final Method method = pageModel.getMethod("setName", String.class); final String value = "1234"; //-- Annotation userValidatorInstance = null; for(Annotation annotation: method.getAnnotations()) { if(annotation.annotationType().isAnnotationPresent(Validator.class)) { userValidatorInstance = annotation; break; } } if(userValidatorInstance != null) { Class userValidator = userValidatorInstance.annotationType(); Validator validator = userValidator.getAnnotation(Validator.class); Class delegateTo = validator.delegateTo(); Method delegateMethod = null; for(Method execute: delegateTo.getMethods()) { if(execute.isAnnotationPresent(Execute.class)) { delegateMethod = execute; break; } } if(delegateMethod == null) { throw new IllegalStateException(); } try { Object validatorImpl = delegateTo.newInstance(); //++ lazy reflection Method setMax = delegateTo.getMethod("setMax", int.class); Method max = userValidator.getMethod("max"); setMax.invoke(validatorImpl, max.invoke(userValidatorInstance)); //-- delegateMethod.invoke(validatorImpl, value); } catch(InvocationTargetException t) { String msg = t.getTargetException().getMessage(); assertEquals("max", msg); return; } } fail(); } }