Polish MergedAnnotation support
This commit is contained in:
parent
cfc4a59135
commit
785e8d8116
|
@ -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(),
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
|||
* // 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 -> a.getString("value")).forEach(System.out::println);
|
||||
* </pre>
|
||||
*
|
||||
* @author Phillip Webb
|
||||
|
|
|
@ -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 {
|
|||
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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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 {
|
|||
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 {
|
|||
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 {
|
|||
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 {
|
|||
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 {
|
|||
}
|
||||
|
||||
@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 {
|
|||
}
|
||||
|
||||
@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…
Reference in New Issue