Browse Source

Polish MergedAnnotation support

pull/22982/head
Sam Brannen 6 years ago
parent
commit
785e8d8116
  1. 2
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java
  2. 6
      spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java
  3. 2
      spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java
  4. 8
      spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java
  5. 9
      spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java
  6. 2
      spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java
  7. 69
      spring-core/src/test/java/org/springframework/core/annotation/AttributeMethodsTests.java

2
spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java

@ -647,7 +647,7 @@ final class AnnotationTypeMapping { @@ -647,7 +647,7 @@ final class AnnotationTypeMapping {
!ObjectUtils.nullSafeEquals(lastValue, value)) {
String on = (source != null) ? " declared on " + source : "";
throw new AnnotationConfigurationException(String.format(
"Different @AliasFor mirror values for annotation [%s]%s, attribute '%s' " +
"Different @AliasFor mirror values for annotation [%s]%s; attribute '%s' " +
"and its alias '%s' are declared with values of [%s] and [%s].",
getAnnotationType().getName(), on,
attributes.get(result).getName(),

6
spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java

@ -89,11 +89,11 @@ final class AttributeMethods { @@ -89,11 +89,11 @@ final class AttributeMethods {
/**
* Determine if this instance only contains only a single attribute named
* Determine if this instance only contains a single attribute named
* {@code value}.
* @return {@code true} if this is only a value attribute
* @return {@code true} if there is only a value attribute
*/
boolean isOnlyValueAttribute() {
boolean hasOnlyValueAttribute() {
return (this.attributeMethods.length == 1 &&
MergedAnnotation.VALUE.equals(this.attributeMethods[0].getName()));
}

2
spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java

@ -77,7 +77,7 @@ public interface MergedAnnotation<A extends Annotation> { @@ -77,7 +77,7 @@ public interface MergedAnnotation<A extends Annotation> {
* Return a complete type hierarchy from this annotation to the
* {@link #getRoot() root}. Provides a useful way to uniquely identify a
* merged annotation instance.
* @return the type heirarchy for the annotation
* @return the type hierarchy for the annotation
* @see MergedAnnotationPredicates#unique(Function)
*/
List<Class<? extends Annotation>> getTypeHierarchy();

8
spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java

@ -35,10 +35,10 @@ import org.springframework.lang.Nullable; @@ -35,10 +35,10 @@ import org.springframework.lang.Nullable;
*
* <ul>
* <li>Explicit and Implicit {@link AliasFor @AliasFor} declarations on one or
* more attributes within the annotation.</li>
* <li>Explicit {@link AliasFor @AliasFor} declarations for a meta-annotation.</li>
* more attributes within the annotation</li>
* <li>Explicit {@link AliasFor @AliasFor} declarations for a meta-annotation</li>
* <li>Convention based attribute aliases for a meta-annotation</li>
* <li>From a meta-annotation declaration.</li>
* <li>From a meta-annotation declaration</li>
* </ul>
*
* <p>For example, a {@code @PostMapping} annotation might be defined as follows:
@ -116,7 +116,7 @@ import org.springframework.lang.Nullable; @@ -116,7 +116,7 @@ import org.springframework.lang.Nullable;
* // get all ExampleAnnotation declarations (including any meta-annotations) and
* // print the merged "value" attributes
* mergedAnnotations.stream(ExampleAnnotation.class).map(
* a -> a.getString("value")).forEach(System.out::println);
* a -&gt; a.getString("value")).forEach(System.out::println);
* </pre>
*
* @author Phillip Webb

9
spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java

@ -163,11 +163,8 @@ public abstract class RepeatableContainers { @@ -163,11 +163,8 @@ public abstract class RepeatableContainers {
private static Object computeRepeatedAnnotationsMethod(Class<? extends Annotation> annotationType) {
AttributeMethods methods = AttributeMethods.forAnnotationType(annotationType);
if (methods.isOnlyValueAttribute()) {
Method method = methods.get("value");
if (method == null) {
return NONE;
}
if (methods.hasOnlyValueAttribute()) {
Method method = methods.get(0);
Class<?> returnType = method.getReturnType();
if (returnType.isArray()) {
Class<?> componentType = returnType.getComponentType();
@ -201,7 +198,7 @@ public abstract class RepeatableContainers { @@ -201,7 +198,7 @@ public abstract class RepeatableContainers {
if (container == null) {
container = deduceContainer(repeatable);
}
Method valueMethod = AttributeMethods.forAnnotationType(container).get("value");
Method valueMethod = AttributeMethods.forAnnotationType(container).get(MergedAnnotation.VALUE);
try {
if (valueMethod == null) {
throw new NoSuchMethodException("No value method found");

2
spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java

@ -394,7 +394,7 @@ public class AnnotationTypeMappingsTests { @@ -394,7 +394,7 @@ public class AnnotationTypeMappingsTests {
.withMessage("Different @AliasFor mirror values for annotation ["
+ AliasPair.class.getName() + "] declared on "
+ WithDifferentValueAliasPair.class.getName()
+ ", attribute 'a' and its alias 'b' are declared with values of [test1] and [test2].");
+ "; attribute 'a' and its alias 'b' are declared with values of [test1] and [test2].");
}
@Test

69
spring-core/src/test/java/org/springframework/core/annotation/AttributeMethodsTests.java

@ -52,52 +52,46 @@ public class AttributeMethodsTests { @@ -52,52 +52,46 @@ public class AttributeMethodsTests {
@Test
public void forAnnotationTypeWhenHasMultipleAttributesReturnsAttributes() {
AttributeMethods methods = AttributeMethods.forAnnotationType(
MultipleAttributes.class);
AttributeMethods methods = AttributeMethods.forAnnotationType(MultipleAttributes.class);
assertThat(methods.get("value").getName()).isEqualTo("value");
assertThat(methods.get("intValue").getName()).isEqualTo("intValue");
assertThat(getAll(methods)).flatExtracting(Method::getName).containsExactly(
"intValue", "value");
assertThat(getAll(methods)).flatExtracting(Method::getName).containsExactly("intValue", "value");
}
@Test
public void isOnlyValueAttributeWhenHasOnlyValueAttributeReturnsTrue() {
public void hasOnlyValueAttributeWhenHasOnlyValueAttributeReturnsTrue() {
AttributeMethods methods = AttributeMethods.forAnnotationType(ValueOnly.class);
assertThat(methods.isOnlyValueAttribute()).isTrue();
assertThat(methods.hasOnlyValueAttribute()).isTrue();
}
@Test
public void isOnlyValueAttributeWhenHasOnlySingleNonValueAttributeReturnsFalse() {
public void hasOnlyValueAttributeWhenHasOnlySingleNonValueAttributeReturnsFalse() {
AttributeMethods methods = AttributeMethods.forAnnotationType(NonValueOnly.class);
assertThat(methods.isOnlyValueAttribute()).isFalse();
assertThat(methods.hasOnlyValueAttribute()).isFalse();
}
@Test
public void isOnlyValueAttributeWhenHasOnlyMultipleAttributesIncludingValueReturnsFalse() {
AttributeMethods methods = AttributeMethods.forAnnotationType(
MultipleAttributes.class);
assertThat(methods.isOnlyValueAttribute()).isFalse();
public void hasOnlyValueAttributeWhenHasOnlyMultipleAttributesIncludingValueReturnsFalse() {
AttributeMethods methods = AttributeMethods.forAnnotationType(MultipleAttributes.class);
assertThat(methods.hasOnlyValueAttribute()).isFalse();
}
@Test
public void indexOfNameReturnsIndex() {
AttributeMethods methods = AttributeMethods.forAnnotationType(
MultipleAttributes.class);
AttributeMethods methods = AttributeMethods.forAnnotationType(MultipleAttributes.class);
assertThat(methods.indexOf("value")).isEqualTo(1);
}
@Test
public void indexOfMethodReturnsIndex() throws Exception {
AttributeMethods methods = AttributeMethods.forAnnotationType(
MultipleAttributes.class);
AttributeMethods methods = AttributeMethods.forAnnotationType(MultipleAttributes.class);
Method method = MultipleAttributes.class.getDeclaredMethod("value");
assertThat(methods.indexOf(method)).isEqualTo(1);
}
@Test
public void sizeReturnsSize() {
AttributeMethods methods = AttributeMethods.forAnnotationType(
MultipleAttributes.class);
AttributeMethods methods = AttributeMethods.forAnnotationType(MultipleAttributes.class);
assertThat(methods.size()).isEqualTo(2);
}
@ -109,8 +103,7 @@ public class AttributeMethodsTests { @@ -109,8 +103,7 @@ public class AttributeMethodsTests {
@Test
public void canThrowTypeNotPresentExceptionWhenHasClassArrayAttributeReturnsTrue() {
AttributeMethods methods = AttributeMethods.forAnnotationType(
ClassArrayValue.class);
AttributeMethods methods = AttributeMethods.forAnnotationType(ClassArrayValue.class);
assertThat(methods.canThrowTypeNotPresentException(0)).isTrue();
}
@ -122,15 +115,13 @@ public class AttributeMethodsTests { @@ -122,15 +115,13 @@ public class AttributeMethodsTests {
@Test
public void hasDefaultValueMethodWhenHasDefaultValueMethodReturnsTrue() {
AttributeMethods methods = AttributeMethods.forAnnotationType(
DefaultValueAttribute.class);
AttributeMethods methods = AttributeMethods.forAnnotationType(DefaultValueAttribute.class);
assertThat(methods.hasDefaultValueMethod()).isTrue();
}
@Test
public void hasDefaultValueMethodWhenHasNoDefaultValueMethodsReturnsFalse() {
AttributeMethods methods = AttributeMethods.forAnnotationType(
MultipleAttributes.class);
AttributeMethods methods = AttributeMethods.forAnnotationType(MultipleAttributes.class);
assertThat(methods.hasDefaultValueMethod()).isFalse();
}
@ -138,8 +129,7 @@ public class AttributeMethodsTests { @@ -138,8 +129,7 @@ public class AttributeMethodsTests {
public void isValidWhenHasTypeNotPresentExceptionReturnsFalse() {
ClassValue annotation = mockAnnotation(ClassValue.class);
given(annotation.value()).willThrow(TypeNotPresentException.class);
AttributeMethods attributes = AttributeMethods.forAnnotationType(
annotation.annotationType());
AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType());
assertThat(attributes.isValid(annotation)).isFalse();
}
@ -148,8 +138,7 @@ public class AttributeMethodsTests { @@ -148,8 +138,7 @@ public class AttributeMethodsTests {
public void isValidWhenDoesNotHaveTypeNotPresentExceptionReturnsTrue() {
ClassValue annotation = mock(ClassValue.class);
given(annotation.value()).willReturn((Class) InputStream.class);
AttributeMethods attributes = AttributeMethods.forAnnotationType(
annotation.annotationType());
AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType());
assertThat(attributes.isValid(annotation)).isTrue();
}
@ -157,10 +146,8 @@ public class AttributeMethodsTests { @@ -157,10 +146,8 @@ public class AttributeMethodsTests {
public void validateWhenHasTypeNotPresentExceptionThrowsException() {
ClassValue annotation = mockAnnotation(ClassValue.class);
given(annotation.value()).willThrow(TypeNotPresentException.class);
AttributeMethods attributes = AttributeMethods.forAnnotationType(
annotation.annotationType());
assertThatIllegalStateException().isThrownBy(() ->
attributes.validate(annotation));
AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType());
assertThatIllegalStateException().isThrownBy(() -> attributes.validate(annotation));
}
@Test
@ -168,8 +155,7 @@ public class AttributeMethodsTests { @@ -168,8 +155,7 @@ public class AttributeMethodsTests {
public void validateWhenDoesNotHaveTypeNotPresentExceptionThrowsNothing() {
ClassValue annotation = mockAnnotation(ClassValue.class);
given(annotation.value()).willReturn((Class) InputStream.class);
AttributeMethods attributes = AttributeMethods.forAnnotationType(
annotation.annotationType());
AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType());
attributes.validate(annotation);
}
@ -189,12 +175,11 @@ public class AttributeMethodsTests { @@ -189,12 +175,11 @@ public class AttributeMethodsTests {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface NoAttributes {
@interface NoAttributes {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface MultipleAttributes {
@interface MultipleAttributes {
int intValue();
@ -203,35 +188,35 @@ public class AttributeMethodsTests { @@ -203,35 +188,35 @@ public class AttributeMethodsTests {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface ValueOnly {
@interface ValueOnly {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
static @interface NonValueOnly {
@interface NonValueOnly {
String test();
}
@Retention(RetentionPolicy.RUNTIME)
static @interface ClassValue {
@interface ClassValue {
Class<?> value();
}
@Retention(RetentionPolicy.RUNTIME)
static @interface ClassArrayValue {
@interface ClassArrayValue {
Class<?>[] value();
}
@Retention(RetentionPolicy.RUNTIME)
static @interface DefaultValueAttribute {
@interface DefaultValueAttribute {
String one();

Loading…
Cancel
Save