Merge branch '3.2.x'

* 3.2.x: (28 commits)
  Hide 'doc' changes from jdiff reports
  Document @Bean 'lite' mode vs @Configuration
  Final preparations for 3.2.2
  Remove Tiles 3 configuration method
  Polishing
  Extracted buildRequestAttributes template method from FrameworkServlet
  Added "beforeExistingAdvisors" flag to AbstractAdvisingBeanPostProcessor
  Minor refinements along the way of researching static CGLIB callbacks
  Compare Kind references before checking log levels
  Polish Javadoc in RequestAttributes
  Fix copy-n-paste errors in NativeWebRequest
  Fix issue with restoring included attributes
  Add additional test for daylight savings glitch
  Document context hierarchy support in the TCF
  Fix test for daylight savings glitch
  Make the methodParameter field of HandlerMethod final
  Disable AsyncTests in spring-test-mvc
  Reformat the testing chapter
  Document context hierarchy support in the TCF
  Document context hierarchy support in the TCF
  ...
This commit is contained in:
Phillip Webb
2013-03-13 14:01:46 -07:00
267 changed files with 8384 additions and 6246 deletions

View File

@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
@@ -240,14 +241,58 @@ public abstract class AnnotationUtils {
* if not found
* @see Class#isAnnotationPresent(Class)
* @see Class#getDeclaredAnnotations()
* @see #findAnnotationDeclaringClassForTypes(List, Class)
* @see #isAnnotationDeclaredLocally(Class, Class)
*/
public static Class<?> findAnnotationDeclaringClass(Class<? extends Annotation> annotationType, Class<?> clazz) {
Assert.notNull(annotationType, "Annotation type must not be null");
if (clazz == null || clazz.equals(Object.class)) {
return null;
}
return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz :
findAnnotationDeclaringClass(annotationType, clazz.getSuperclass());
return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz : findAnnotationDeclaringClass(
annotationType, clazz.getSuperclass());
}
/**
* Find the first {@link Class} in the inheritance hierarchy of the specified
* {@code clazz} (including the specified {@code clazz} itself) which declares
* at least one of the specified {@code annotationTypes}, or {@code null} if
* none of the specified annotation types could be found.
* <p>If the supplied {@code clazz} is {@code null}, {@code null} will be
* returned.
* <p>If the supplied {@code clazz} is an interface, only the interface itself
* will be checked; the inheritance hierarchy for interfaces will not be traversed.
* <p>The standard {@link Class} API does not provide a mechanism for determining
* which class in an inheritance hierarchy actually declares one of several
* candidate {@linkplain Annotation annotations}, so we need to handle this
* explicitly.
* @param annotationTypes the list of Class objects corresponding to the
* annotation types
* @param clazz the Class object corresponding to the class on which to check
* for the annotations, or {@code null}
* @return the first {@link Class} in the inheritance hierarchy of the specified
* {@code clazz} which declares an annotation of at least one of the specified
* {@code annotationTypes}, or {@code null} if not found
* @see Class#isAnnotationPresent(Class)
* @see Class#getDeclaredAnnotations()
* @see #findAnnotationDeclaringClass(Class, Class)
* @see #isAnnotationDeclaredLocally(Class, Class)
* @since 3.2.2
*/
public static Class<?> findAnnotationDeclaringClassForTypes(List<Class<? extends Annotation>> annotationTypes,
Class<?> clazz) {
Assert.notEmpty(annotationTypes, "The list of annotation types must not be empty");
if (clazz == null || clazz.equals(Object.class)) {
return null;
}
for (Class<? extends Annotation> annotationType : annotationTypes) {
if (isAnnotationDeclaredLocally(annotationType, clazz)) {
return clazz;
}
}
return findAnnotationDeclaringClassForTypes(annotationTypes, clazz.getSuperclass());
}
/**
@@ -348,8 +393,8 @@ public abstract class AnnotationUtils {
* and corresponding attribute values as values
* @since 3.1.1
*/
public static AnnotationAttributes getAnnotationAttributes(
Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) {
public static AnnotationAttributes getAnnotationAttributes(Annotation annotation, boolean classValuesAsString,
boolean nestedAnnotationsAsMap) {
AnnotationAttributes attrs = new AnnotationAttributes();
Method[] methods = annotation.annotationType().getDeclaredMethods();
@@ -371,15 +416,15 @@ public abstract class AnnotationUtils {
}
}
if (nestedAnnotationsAsMap && value instanceof Annotation) {
attrs.put(method.getName(), getAnnotationAttributes(
(Annotation)value, classValuesAsString, nestedAnnotationsAsMap));
attrs.put(method.getName(),
getAnnotationAttributes((Annotation) value, classValuesAsString, nestedAnnotationsAsMap));
}
else if (nestedAnnotationsAsMap && value instanceof Annotation[]) {
Annotation[] realAnnotations = (Annotation[])value;
Annotation[] realAnnotations = (Annotation[]) value;
AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length];
for (int i = 0; i < realAnnotations.length; i++) {
mappedAnnotations[i] = getAnnotationAttributes(
realAnnotations[i], classValuesAsString, nestedAnnotationsAsMap);
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString,
nestedAnnotationsAsMap);
}
attrs.put(method.getName(), mappedAnnotations);
}