/** * Validate an object. * * @param object the object to be validated. * @throws RaveException if validation fails. */ public void validate(Object object) throws RaveException { Class<?> clazz = object.getClass(); Validated validated = clazz.getAnnotation(Validated.class); BaseValidator validator; synchronized (this) { if (validated == null && !unannotatedModelValidator.hasSeen(clazz)) { unannotatedModelValidator.processNonAnnotatedClasses(clazz); } validator = classValidatorMap.get(clazz); if (validator == null) { validator = getValidatorInstance(clazz); } if (validator == null) { throw new UnsupportedObjectException(Collections.singletonList( new RaveError(clazz, "", RaveErrorStrings.CLASS_NOT_SUPPORTED_ERROR))); } } validator.validate(object); }
/** * Process any {@link Class} that is not annotated with the {@link Validated} annotation. * * @param clazz the {@link Class} to process. */ void processNonAnnotatedClasses(Class<?> clazz) { Validated validated = clazz.getAnnotation(Validated.class); if (validated != null) { throw new IllegalArgumentException( clazz.getCanonicalName() + " is annotated with " + Validated.class.getCanonicalName()); } if (!traverseClassHierarchy(clazz, clazz)) { unsupportedClassesCache.put(clazz, null); } addSupportedClass(clazz); getInstance().registerValidatorWithClass(this, clazz); }
/** * Recursively traverse the inheritance tree until a {@link Validated} annotation is reached. * * @param original the original {@link Class} we are processing. * @param classToCheck the {@link Class} that we are checking which is in the inheritance tree of * {@code original} * @return true if any node in the inheritance tree is annotated with the {@link Validated} annotation. False * otherwise. */ private boolean traverseClassHierarchy(Class<?> original, Class<?> classToCheck) { boolean returnValue = false; Class<?> parentClass = classToCheck.getSuperclass(); if (parentClass != null) { returnValue = evaluateInheritance(original, parentClass); } for (Class<?> interfaces : classToCheck.getInterfaces()) { returnValue = evaluateInheritance(original, interfaces) || returnValue; } return returnValue; }
@Override protected void validateAs( Object object, Class<?> clazz) throws RaveException { if (unsupportedClassesCache.containsKey(clazz)) { throw new UnsupportedObjectException(Collections.singletonList( new RaveError(clazz, "", RaveErrorStrings.CLASS_NOT_SUPPORTED_ERROR))); } Set<Class<?>> inheritanceSet = supportedClassesCache.get(clazz); if (inheritanceSet == null || inheritanceSet.isEmpty()) { throw new IllegalArgumentException(clazz.getCanonicalName() + ":" + RaveErrorStrings.CLASS_NOT_SUPPORTED_ERROR + this.getClass().getCanonicalName()); } List<RaveError> raveErrors = null; for (Class<?> parentClass : inheritanceSet) { raveErrors = mergeErrors(raveErrors, reEvaluateAsSuperType(parentClass, object)); } if (raveErrors != null && !raveErrors.isEmpty()) { throw new InvalidModelException(raveErrors); } }
/** * Evaluate an individual node in the inheritance tree. * * @param original the original {@link Class} we are processing. * @param classToCheck the {@link Class} that we are checking which is in the inheritance tree of * {@code original} * @return true if any node in the inheritance tree is annotated with the {@link Validated} annotation. False * otherwise. */ private boolean evaluateInheritance(Class<?> original, Class<?> classToCheck) { Validated validated = classToCheck.getAnnotation(Validated.class); if (validated != null) { Set<Class<?>> set = supportedClassesCache.get(original); if (set == null) { set = new HashSet<>(); supportedClassesCache.put(original, set); } set.add(classToCheck); return true; } return traverseClassHierarchy(original, classToCheck); }
@Test(expected = IllegalArgumentException.class) public void unAnnotateValidatorHandlerValidateAs_whenModelIsAnnotated_shouldThrowException() throws RaveException { Rave.UnAnnotatedModelValidator handler = new Rave.UnAnnotatedModelValidator(1); handler.validateAs(new SingleMethodSampleModel("", ""), SingleMethodSampleModel.class); }
@Test(expected = IllegalArgumentException.class) public void unAnnotateValidatorHandlerValidateAs_whenNonSupportedClass_shouldThrowException() throws RaveException { Rave.UnAnnotatedModelValidator handler = new Rave.UnAnnotatedModelValidator(1); handler.validateAs(new NonAnnotated(""), NonAnnotated.class); }
@Test(expected = UnsupportedObjectException.class) public void unAnnotateValidatorHandlerProcessAnnotation_whenUnSupportedClass_shouldThrowUnsupportedObjectException() throws RaveException { Rave.UnAnnotatedModelValidator handler = new Rave.UnAnnotatedModelValidator(1); handler.processNonAnnotatedClasses(Object.class); handler.processNonAnnotatedClasses(String.class); handler.validateAs("", String.class); }
@Test(expected = IllegalArgumentException.class) public void processNonAnnotatedClass_whenModelIsAnnotated_shouldThrowException() throws RaveException { Rave.UnAnnotatedModelValidator handler = new Rave.UnAnnotatedModelValidator(1); handler.processNonAnnotatedClasses(SingleMethodSampleModel.class); }
@Test(expected = IllegalArgumentException.class) public void unAnnotateValidatorHandlerProcessAnnotation_whenUnSupportedClass_shouldThrowException() throws RaveException { Rave.UnAnnotatedModelValidator handler = new Rave.UnAnnotatedModelValidator(1); handler.processNonAnnotatedClasses(Object.class); handler.processNonAnnotatedClasses(String.class); handler.validateAs(new Object(), Object.class); }