Revise method and parameter names in annotation support

In AnnotatedElementUtils, all methods pertaining to merging annotation
attributes have been renamed to "getMerged*()" and "findMerged*()"
accordingly. Existing methods such as getAnnotationAttributes(..) have
been deprecated in favor of the more descriptive "merged" variants.
This aligns the naming conventions in AnnotatedElementUtils with those
already present in AnnotationReadingVisitorUtils.

The use of "annotationType" as a variable name for the fully qualified
class name of an annotation type has been replaced with
"annotationName" in order to improve the readability and intent of the
code base.

In MetaAnnotationUtils.AnnotationDescriptor, getMergedAnnotation() has
been renamed to synthesizeAnnotation(), and the method is now
overridden in UntypedAnnotationDescriptor to always throw an
UnsupportedOperationException in order to avoid potential run-time
ClassCastExceptions.

Issue: SPR-11511
This commit is contained in:
Sam Brannen
2015-06-14 00:21:15 +02:00
parent 2b339db53b
commit 32c17bf540
26 changed files with 390 additions and 342 deletions

View File

@@ -37,7 +37,7 @@ public class TestAnnotationUtils {
* annotated with {@code @Timed}
*/
public static long getTimeout(Method method) {
Timed timed = AnnotatedElementUtils.findAnnotation(method, Timed.class);
Timed timed = AnnotatedElementUtils.findMergedAnnotation(method, Timed.class);
if (timed == null) {
return 0;
}

View File

@@ -86,7 +86,7 @@ class MergedSqlConfig {
Assert.notNull(testClass, "testClass must not be null");
// Get global attributes, if any.
AnnotationAttributes attributes = AnnotatedElementUtils.findAnnotationAttributes(testClass,
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(testClass,
SqlConfig.class.getName(), false, false);
// Override global attributes with local attributes.

View File

@@ -137,7 +137,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
// Traverse the class hierarchy...
while (descriptor != null) {
Class<?> declaringClass = descriptor.getDeclaringClass();
TestExecutionListeners testExecutionListeners = descriptor.getMergedAnnotation();
TestExecutionListeners testExecutionListeners = descriptor.synthesizeAnnotation();
if (logger.isTraceEnabled()) {
logger.trace(String.format("Retrieved @TestExecutionListeners [%s] for declaring class [%s].",
testExecutionListeners, declaringClass.getName()));

View File

@@ -86,7 +86,7 @@ abstract class ActiveProfilesUtils {
while (descriptor != null) {
Class<?> rootDeclaringClass = descriptor.getRootDeclaringClass();
Class<?> declaringClass = descriptor.getDeclaringClass();
ActiveProfiles annotation = descriptor.getMergedAnnotation();
ActiveProfiles annotation = descriptor.synthesizeAnnotation();
if (logger.isTraceEnabled()) {
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", annotation,

View File

@@ -26,6 +26,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextHierarchy;
@@ -132,8 +133,10 @@ abstract class ContextLoaderUtils {
final List<ContextConfigurationAttributes> configAttributesList = new ArrayList<ContextConfigurationAttributes>();
if (contextConfigDeclaredLocally) {
convertContextConfigToConfigAttributesAndAddToList(
(ContextConfiguration) descriptor.getMergedAnnotation(), rootDeclaringClass,
ContextConfiguration contextConfiguration = AnnotationUtils.synthesizeAnnotation(
descriptor.getAnnotationAttributes(), ContextConfiguration.class,
descriptor.getRootDeclaringClass());
convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, rootDeclaringClass,
configAttributesList);
}
else if (contextHierarchyDeclaredLocally) {
@@ -256,7 +259,7 @@ abstract class ContextLoaderUtils {
annotationType.getName(), testClass.getName()));
while (descriptor != null) {
convertContextConfigToConfigAttributesAndAddToList(descriptor.getMergedAnnotation(),
convertContextConfigToConfigAttributesAndAddToList(descriptor.synthesizeAnnotation(),
descriptor.getRootDeclaringClass(), attributesList);
descriptor = findAnnotationDescriptor(descriptor.getRootDeclaringClass().getSuperclass(), annotationType);
}

View File

@@ -73,7 +73,7 @@ public class DefaultActiveProfilesResolver implements ActiveProfilesResolver {
}
else {
Class<?> declaringClass = descriptor.getDeclaringClass();
ActiveProfiles annotation = descriptor.getMergedAnnotation();
ActiveProfiles annotation = descriptor.synthesizeAnnotation();
if (logger.isTraceEnabled()) {
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", annotation,

View File

@@ -155,8 +155,8 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi
Assert.notNull(testClass, "The test class of the supplied TestContext must not be null");
Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null");
DirtiesContext methodAnn = AnnotatedElementUtils.findAnnotation(testMethod, DirtiesContext.class);
DirtiesContext classAnn = AnnotatedElementUtils.findAnnotation(testClass, DirtiesContext.class);
DirtiesContext methodAnn = AnnotatedElementUtils.findMergedAnnotation(testMethod, DirtiesContext.class);
DirtiesContext classAnn = AnnotatedElementUtils.findMergedAnnotation(testClass, DirtiesContext.class);
boolean methodAnnotated = (methodAnn != null);
boolean classAnnotated = (classAnn != null);
MethodMode methodMode = (methodAnnotated ? methodAnn.methodMode() : null);
@@ -183,7 +183,7 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi
Class<?> testClass = testContext.getTestClass();
Assert.notNull(testClass, "The test class of the supplied TestContext must not be null");
DirtiesContext dirtiesContext = AnnotatedElementUtils.findAnnotation(testClass, DirtiesContext.class);
DirtiesContext dirtiesContext = AnnotatedElementUtils.findMergedAnnotation(testClass, DirtiesContext.class);
boolean classAnnotated = (dirtiesContext != null);
ClassMode classMode = (classAnnotated ? dirtiesContext.classMode() : null);

View File

@@ -96,7 +96,7 @@ public abstract class TestPropertySourceUtils {
annotationType.getName(), testClass.getName()));
while (descriptor != null) {
TestPropertySource testPropertySource = descriptor.getMergedAnnotation();
TestPropertySource testPropertySource = descriptor.synthesizeAnnotation();
Class<?> rootDeclaringClass = descriptor.getRootDeclaringClass();
if (logger.isTraceEnabled()) {

View File

@@ -499,7 +499,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
if (this.configurationAttributes == null) {
Class<?> clazz = testContext.getTestClass();
TransactionConfiguration txConfig = AnnotatedElementUtils.findAnnotation(clazz,
TransactionConfiguration txConfig = AnnotatedElementUtils.findMergedAnnotation(clazz,
TransactionConfiguration.class);
if (logger.isDebugEnabled()) {
logger.debug(String.format("Retrieved @TransactionConfiguration [%s] for test class [%s].",

View File

@@ -272,8 +272,6 @@ public abstract class MetaAnnotationUtils {
private final T annotation;
private final T mergedAnnotation;
private final AnnotationAttributes annotationAttributes;
@@ -281,7 +279,6 @@ public abstract class MetaAnnotationUtils {
this(rootDeclaringClass, rootDeclaringClass, null, annotation);
}
@SuppressWarnings("unchecked")
public AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
Annotation composedAnnotation, T annotation) {
Assert.notNull(rootDeclaringClass, "rootDeclaringClass must not be null");
@@ -290,10 +287,8 @@ public abstract class MetaAnnotationUtils {
this.declaringClass = declaringClass;
this.composedAnnotation = composedAnnotation;
this.annotation = annotation;
this.annotationAttributes = AnnotatedElementUtils.findAnnotationAttributes(rootDeclaringClass,
this.annotationAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes(rootDeclaringClass,
annotation.annotationType().getName(), false, false);
this.mergedAnnotation = AnnotationUtils.synthesizeAnnotation(annotationAttributes,
(Class<T>) annotation.annotationType(), rootDeclaringClass);
}
public Class<?> getRootDeclaringClass() {
@@ -309,13 +304,18 @@ public abstract class MetaAnnotationUtils {
}
/**
* Get the annotation that was synthesized from the merged
* {@link #getAnnotationAttributes AnnotationAttributes}.
* Synthesize the merged {@link #getAnnotationAttributes AnnotationAttributes}
* in this descriptor back into an annotation of the target
* {@linkplain #getAnnotationType annotation type}.
* @since 4.2
* @see #getAnnotationAttributes()
* @see #getAnnotationType()
* @see AnnotationUtils#synthesizeAnnotation(java.util.Map, Class, java.lang.reflect.AnnotatedElement)
*/
public T getMergedAnnotation() {
return this.mergedAnnotation;
@SuppressWarnings("unchecked")
public T synthesizeAnnotation() {
return AnnotationUtils.synthesizeAnnotation(getAnnotationAttributes(), (Class<T>) getAnnotationType(),
getRootDeclaringClass());
}
public Class<? extends Annotation> getAnnotationType() {
@@ -364,6 +364,18 @@ public abstract class MetaAnnotationUtils {
Annotation composedAnnotation, Annotation annotation) {
super(rootDeclaringClass, declaringClass, composedAnnotation, annotation);
}
/**
* Throws an {@link UnsupportedOperationException} since the type of annotation
* represented by the {@link #getAnnotationAttributes AnnotationAttributes} in
* an {@code UntypedAnnotationDescriptor} is unknown.
* @since 4.2
*/
@Override
public Annotation synthesizeAnnotation() {
throw new UnsupportedOperationException(
"getMergedAnnotation() is unsupported in UntypedAnnotationDescriptor");
}
}
}