summaryrefslogtreecommitdiff
path: root/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
diff options
context:
space:
mode:
authorEmmanuel Bourg <ebourg@apache.org>2018-04-08 23:27:38 +0200
committerEmmanuel Bourg <ebourg@apache.org>2018-04-08 23:27:38 +0200
commite9dafb5ce16aa2faa4fee1019417cc0a7456af57 (patch)
treec38471d22f5c367a45673724d3a6571d5daf591b /spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
parent6dc3d6835b664af0d21e774a5342b90d4417f628 (diff)
New upstream version 4.3.15
Diffstat (limited to 'spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java')
-rw-r--r--spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java74
1 files changed, 55 insertions, 19 deletions
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
index 5e19db46..971568da 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -145,17 +145,17 @@ public abstract class AnnotationUtils {
* <p>Note that this method supports only a single level of meta-annotations.
* For support for arbitrary levels of meta-annotations, use one of the
* {@code find*()} methods instead.
- * @param ann the Annotation to check
+ * @param annotation the Annotation to check
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
* @return the first matching annotation, or {@code null} if not found
* @since 4.0
*/
@SuppressWarnings("unchecked")
- public static <A extends Annotation> A getAnnotation(Annotation ann, Class<A> annotationType) {
- if (annotationType.isInstance(ann)) {
- return synthesizeAnnotation((A) ann);
+ public static <A extends Annotation> A getAnnotation(Annotation annotation, Class<A> annotationType) {
+ if (annotationType.isInstance(annotation)) {
+ return synthesizeAnnotation((A) annotation);
}
- Class<? extends Annotation> annotatedElement = ann.annotationType();
+ Class<? extends Annotation> annotatedElement = annotation.annotationType();
try {
return synthesizeAnnotation(annotatedElement.getAnnotation(annotationType), annotatedElement);
}
@@ -568,7 +568,6 @@ public abstract class AnnotationUtils {
if (result == null) {
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
result = findAnnotation((AnnotatedElement) resolvedMethod, annotationType);
-
if (result == null) {
result = searchOnInterfaces(method, annotationType, method.getDeclaringClass().getInterfaces());
}
@@ -603,10 +602,10 @@ public abstract class AnnotationUtils {
private static <A extends Annotation> A searchOnInterfaces(Method method, Class<A> annotationType, Class<?>... ifcs) {
A annotation = null;
- for (Class<?> iface : ifcs) {
- if (isInterfaceWithAnnotatedMethods(iface)) {
+ for (Class<?> ifc : ifcs) {
+ if (isInterfaceWithAnnotatedMethods(ifc)) {
try {
- Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
+ Method equivalentMethod = ifc.getMethod(method.getName(), method.getParameterTypes());
annotation = getAnnotation(equivalentMethod, annotationType);
}
catch (NoSuchMethodException ex) {
@@ -620,13 +619,13 @@ public abstract class AnnotationUtils {
return annotation;
}
- static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
- Boolean found = annotatedInterfaceCache.get(iface);
+ static boolean isInterfaceWithAnnotatedMethods(Class<?> ifc) {
+ Boolean found = annotatedInterfaceCache.get(ifc);
if (found != null) {
return found;
}
found = Boolean.FALSE;
- for (Method ifcMethod : iface.getMethods()) {
+ for (Method ifcMethod : ifc.getMethods()) {
try {
if (ifcMethod.getAnnotations().length > 0) {
found = Boolean.TRUE;
@@ -637,7 +636,7 @@ public abstract class AnnotationUtils {
handleIntrospectionFailure(ifcMethod, ex);
}
}
- annotatedInterfaceCache.put(iface, found);
+ annotatedInterfaceCache.put(ifc, found);
return found;
}
@@ -933,6 +932,32 @@ public abstract class AnnotationUtils {
}
/**
+ * Check the declared attributes of the given annotation, in particular covering
+ * Google App Engine's late arrival of {@code TypeNotPresentExceptionProxy} for
+ * {@code Class} values (instead of early {@code Class.getAnnotations() failure}.
+ * <p>This method not failing indicates that {@link #getAnnotationAttributes(Annotation)}
+ * won't failure either (when attempted later on).
+ * @param annotation the annotation to validate
+ * @throws IllegalStateException if a declared {@code Class} attribute could not be read
+ * @since 4.3.15
+ * @see Class#getAnnotations()
+ * @see #getAnnotationAttributes(Annotation)
+ */
+ public static void validateAnnotation(Annotation annotation) {
+ for (Method method : getAttributeMethods(annotation.annotationType())) {
+ Class<?> returnType = method.getReturnType();
+ if (returnType == Class.class || returnType == Class[].class) {
+ try {
+ method.invoke(annotation);
+ }
+ catch (Throwable ex) {
+ throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex);
+ }
+ }
+ }
+ }
+
+ /**
* Retrieve the given annotation's attributes as a {@link Map}, preserving all
* attribute types.
* <p>Equivalent to calling {@link #getAnnotationAttributes(Annotation, boolean, boolean)}
@@ -1260,15 +1285,12 @@ public abstract class AnnotationUtils {
}
Object value = attributes.get(attributeName);
boolean valuePresent = (value != null && !(value instanceof DefaultValueHolder));
-
for (String aliasedAttributeName : aliasMap.get(attributeName)) {
if (valuesAlreadyReplaced.contains(aliasedAttributeName)) {
continue;
}
-
Object aliasedValue = attributes.get(aliasedAttributeName);
boolean aliasPresent = (aliasedValue != null && !(aliasedValue instanceof DefaultValueHolder));
-
// Something to validate or replace with an alias?
if (valuePresent || aliasPresent) {
if (valuePresent && aliasPresent) {
@@ -1882,17 +1904,31 @@ public abstract class AnnotationUtils {
if (element instanceof Class && Annotation.class.isAssignableFrom((Class<?>) element)) {
// Meta-annotation or (default) value lookup on an annotation type
if (loggerToUse.isDebugEnabled()) {
- loggerToUse.debug("Failed to meta-introspect annotation [" + element + "]: " + ex);
+ loggerToUse.debug("Failed to meta-introspect annotation " + element + ": " + ex);
}
}
else {
// Direct annotation lookup on regular Class, Method, Field
if (loggerToUse.isInfoEnabled()) {
- loggerToUse.info("Failed to introspect annotations on [" + element + "]: " + ex);
+ loggerToUse.info("Failed to introspect annotations on " + element + ": " + ex);
}
}
}
+ /**
+ * Clear the internal annotation metadata cache.
+ * @since 4.3.15
+ */
+ public static void clearCache() {
+ findAnnotationCache.clear();
+ metaPresentCache.clear();
+ annotatedInterfaceCache.clear();
+ synthesizableCache.clear();
+ attributeAliasesCache.clear();
+ attributeMethodsCache.clear();
+ aliasDescriptorCache.clear();
+ }
+
/**
* Cache key for the AnnotatedElement cache.