Nullability refinements (no IntelliJ warnings, fewer null checks)

Includes consistent ignoring of all java.lang (meta-)annotations.

Closes gh-22586
This commit is contained in:
Juergen Hoeller
2019-03-23 12:13:38 +01:00
parent 75b52309a7
commit 5e15338a09
33 changed files with 439 additions and 801 deletions

View File

@@ -700,17 +700,12 @@ public class AnnotatedElementUtilsTests {
assertArrayEquals("path attribute: ", asArray("/test"), webMapping.path());
}
@Test
public void javaLangAnnotationTypeViaFindMergedAnnotation() throws Exception {
Constructor<?> deprecatedCtor = Date.class.getConstructor(String.class);
assertEquals(deprecatedCtor.getAnnotation(Deprecated.class), findMergedAnnotation(deprecatedCtor, Deprecated.class));
assertEquals(Date.class.getAnnotation(Deprecated.class), findMergedAnnotation(Date.class, Deprecated.class));
}
@Test
public void javaxAnnotationTypeViaFindMergedAnnotation() throws Exception {
assertEquals(ResourceHolder.class.getAnnotation(Resource.class), findMergedAnnotation(ResourceHolder.class, Resource.class));
assertEquals(SpringAppConfigClass.class.getAnnotation(Resource.class), findMergedAnnotation(SpringAppConfigClass.class, Resource.class));
assertEquals(ResourceHolder.class.getAnnotation(Resource.class),
findMergedAnnotation(ResourceHolder.class, Resource.class));
assertEquals(SpringAppConfigClass.class.getAnnotation(Resource.class),
findMergedAnnotation(SpringAppConfigClass.class, Resource.class));
}
@Test

View File

@@ -16,19 +16,16 @@
package org.springframework.core.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.*;
/**
* Tests for {@link AnnotationFilter}.
@@ -37,35 +34,22 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*/
public class AnnotationFilterTests {
private static final AnnotationFilter FILTER = annotationType -> ObjectUtils.nullSafeEquals(
annotationType, TestAnnotation.class.getName());
private static final AnnotationFilter FILTER = annotationType ->
ObjectUtils.nullSafeEquals(annotationType, TestAnnotation.class.getName());
@Test
public void matchesAnnotationWhenAnnotationIsNullReturnsFalse() {
TestAnnotation annotation = null;
assertThat(FILTER.matches(annotation)).isFalse();
}
@Test
public void matchesAnnotationWhenMatchReturnsTrue() {
TestAnnotation annotation = WithTestAnnotation.class.getDeclaredAnnotation(
TestAnnotation.class);
TestAnnotation annotation = WithTestAnnotation.class.getDeclaredAnnotation(TestAnnotation.class);
assertThat(FILTER.matches(annotation)).isTrue();
}
@Test
public void matchesAnnotationWhenNoMatchReturnsFalse() {
OtherAnnotation annotation = WithOtherAnnotation.class.getDeclaredAnnotation(
OtherAnnotation.class);
OtherAnnotation annotation = WithOtherAnnotation.class.getDeclaredAnnotation(OtherAnnotation.class);
assertThat(FILTER.matches(annotation)).isFalse();
}
@Test
public void matchesAnnotationClassWhenAnnotationClassIsNullReturnsFalse() {
Class<Annotation> annotationType = null;
assertThat(FILTER.matches(annotationType)).isFalse();
}
@Test
public void matchesAnnotationClassWhenMatchReturnsTrue() {
Class<TestAnnotation> annotationType = TestAnnotation.class;
@@ -109,27 +93,15 @@ public class AnnotationFilterTests {
}
@Test
public void noneWhenNonNullReturnsFalse() {
public void noneReturnsFalse() {
assertThat(AnnotationFilter.NONE.matches(Retention.class)).isFalse();
assertThat(AnnotationFilter.NONE.matches(Nullable.class)).isFalse();
assertThat(AnnotationFilter.NONE.matches(TestAnnotation.class)).isFalse();
assertThat(AnnotationFilter.NONE.matches((Annotation) null)).isFalse();
assertThat(AnnotationFilter.NONE.matches((Class<Annotation>) null)).isFalse();
assertThat(AnnotationFilter.NONE.matches((String) null)).isFalse();
}
@Test
public void pacakgesReturnsPackagesAnnotationFilter() {
assertThat(AnnotationFilter.packages("com.example")).isInstanceOf(
PackagesAnnotationFilter.class);
}
@Test
public void mostAppropriateForCollectionWhenAnnotationTypesIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> AnnotationFilter.mostAppropriateFor(
(Collection<Class<? extends Annotation>>) null)).withMessage(
"AnnotationTypes must not be null");
assertThat(AnnotationFilter.packages("com.example")).isInstanceOf(PackagesAnnotationFilter.class);
}
@Test
@@ -146,14 +118,6 @@ public class AnnotationFilterTests {
assertThat(filter).isSameAs(AnnotationFilter.NONE);
}
@Test
public void mostAppropriateForArrayWhenAnnotationTypesIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> AnnotationFilter.mostAppropriateFor(
(Class<? extends Annotation>[]) null)).withMessage(
"AnnotationTypes must not be null");
}
@Test
public void mostAppropriateForArrayReturnsPlainWhenPossible() {
AnnotationFilter filter = AnnotationFilter.mostAppropriateFor(
@@ -168,24 +132,21 @@ public class AnnotationFilterTests {
assertThat(filter).isSameAs(AnnotationFilter.NONE);
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotation {
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnnotation {
}
@TestAnnotation
static class WithTestAnnotation {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface OtherAnnotation {
@interface OtherAnnotation {
}
@OtherAnnotation
static class WithOtherAnnotation {
}
}

View File

@@ -28,7 +28,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.junit.Test;
@@ -47,35 +46,24 @@ import static org.assertj.core.api.Assertions.*;
*/
public class AnnotationTypeMappingsTests {
@Test
public void forAnnotationTypeWhenAnnotationIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> AnnotationTypeMappings.forAnnotationType(null)).withMessage(
"AnnotationType must not be null");
}
@Test
public void forAnnotationTypeWhenNoMetaAnnotationsReturnsMappings() {
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
SimpleAnnotation.class);
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SimpleAnnotation.class);
assertThat(mappings.size()).isEqualTo(1);
assertThat(mappings.get(0).getAnnotationType()).isEqualTo(SimpleAnnotation.class);
assertThat(getAll(mappings)).flatExtracting(
AnnotationTypeMapping::getAnnotationType).containsExactly(
SimpleAnnotation.class);
AnnotationTypeMapping::getAnnotationType).containsExactly(SimpleAnnotation.class);
}
@Test
public void forAnnotationWhenHasSpringAnnotationReturnsFilteredMappings() {
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
WithSpringLangAnnotation.class);
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithSpringLangAnnotation.class);
assertThat(mappings.size()).isEqualTo(1);
}
@Test
public void forAnnotationTypeWhenMetaAnnotationsReturnsMappings() {
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
MetaAnnotated.class);
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MetaAnnotated.class);
assertThat(mappings.size()).isEqualTo(6);
assertThat(getAll(mappings)).flatExtracting(
AnnotationTypeMapping::getAnnotationType).containsExactly(
@@ -85,33 +73,27 @@ public class AnnotationTypeMappingsTests {
@Test
public void forAnnotationTypeWhenHasRepeatingMetaAnnotationReturnsMapping() {
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
WithRepeatedMetaAnnotations.class);
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class);
assertThat(mappings.size()).isEqualTo(3);
assertThat(getAll(mappings)).flatExtracting(
AnnotationTypeMapping::getAnnotationType).containsExactly(
WithRepeatedMetaAnnotations.class, Repeating.class,
Repeating.class);
WithRepeatedMetaAnnotations.class, Repeating.class, Repeating.class);
}
@Test
public void forAnnotationTypeWhenSelfAnnotatedReturnsMapping() {
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
SelfAnnotated.class);
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SelfAnnotated.class);
assertThat(mappings.size()).isEqualTo(1);
assertThat(getAll(mappings)).flatExtracting(
AnnotationTypeMapping::getAnnotationType).containsExactly(
SelfAnnotated.class);
AnnotationTypeMapping::getAnnotationType).containsExactly(SelfAnnotated.class);
}
@Test
public void forAnnotationTypeWhenFormsLoopReturnsMapping() {
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
LoopA.class);
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(LoopA.class);
assertThat(mappings.size()).isEqualTo(2);
assertThat(getAll(mappings)).flatExtracting(
AnnotationTypeMapping::getAnnotationType).containsExactly(LoopA.class,
LoopB.class);
AnnotationTypeMapping::getAnnotationType).containsExactly(LoopA.class, LoopB.class);
}
@Test

View File

@@ -540,13 +540,6 @@ public class AnnotationUtilsTests {
assertEquals(Ordered.LOWEST_PRECEDENCE, getDefaultValue(Order.class));
}
@Test
public void findRepeatableAnnotationOnComposedAnnotation() {
Repeatable repeatable = findAnnotation(MyRepeatableMeta1.class, Repeatable.class);
assertNotNull(repeatable);
assertEquals(MyRepeatableContainer.class, repeatable.value());
}
@Test
public void getRepeatableAnnotationsDeclaredOnMethod() throws Exception {
Method method = InterfaceWithRepeated.class.getMethod("foo");

View File

@@ -511,6 +511,7 @@ public class AnnotationsScannerTests {
assertThat(result).isEqualTo("OK");
}
private Method methodFrom(Class<?> type) {
return ReflectionUtils.findMethod(type, "method");
}
@@ -532,81 +533,68 @@ public class AnnotationsScannerTests {
return result.stream();
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotation1 {
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnnotation1 {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotation2 {
@interface TestAnnotation2 {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotation3 {
@interface TestAnnotation3 {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotation4 {
@interface TestAnnotation4 {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotation5 {
@interface TestAnnotation5 {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotation6 {
@interface TestAnnotation6 {
}
@Retention(RetentionPolicy.RUNTIME)
@Inherited
static @interface TestInheritedAnnotation1 {
@interface TestInheritedAnnotation1 {
}
@Retention(RetentionPolicy.RUNTIME)
@Inherited
static @interface TestInheritedAnnotation2 {
@interface TestInheritedAnnotation2 {
}
@Retention(RetentionPolicy.RUNTIME)
@Inherited
static @interface TestInheritedAnnotation3 {
@interface TestInheritedAnnotation3 {
}
@Retention(RetentionPolicy.RUNTIME)
@Inherited
static @interface TestInheritedAnnotation4 {
@interface TestInheritedAnnotation4 {
}
@Retention(RetentionPolicy.RUNTIME)
@Inherited
static @interface TestInheritedAnnotation5 {
@interface TestInheritedAnnotation5 {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface OnSuperClass {
@interface OnSuperClass {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface OnInterface {
@interface OnInterface {
}
static class WithNoAnnotations {
public void method() {
}
}
@TestAnnotation1
@@ -615,7 +603,6 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method() {
}
}
@TestAnnotation1
@@ -626,7 +613,6 @@ public class AnnotationsScannerTests {
@TestAnnotation2
public void method() {
}
}
@TestAnnotation2
@@ -637,7 +623,6 @@ public class AnnotationsScannerTests {
@TestInheritedAnnotation2
public void method() {
}
}
@TestAnnotation1
@@ -646,7 +631,6 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method() {
}
}
@TestInheritedAnnotation2
@@ -655,7 +639,6 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method() {
}
}
@TestAnnotation1
@@ -664,17 +647,15 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method() {
}
}
@TestAnnotation2
@TestInheritedAnnotation2
static interface SingleInterface {
interface SingleInterface {
@TestAnnotation2
@TestInheritedAnnotation2
public void method();
void method();
}
@TestAnnotation1
@@ -683,7 +664,6 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method() {
}
}
@TestAnnotation2
@@ -694,7 +674,6 @@ public class AnnotationsScannerTests {
@TestInheritedAnnotation2
public void method() {
}
}
@TestAnnotation3
@@ -703,33 +682,29 @@ public class AnnotationsScannerTests {
@TestAnnotation3
public void method() {
}
}
@TestAnnotation4
static interface HierarchySuperSuperclassInterface {
interface HierarchySuperSuperclassInterface {
@TestAnnotation4
public void method();
void method();
}
@TestAnnotation5
@TestInheritedAnnotation5
static interface HierarchyInterface extends HierarchyInterfaceInterface {
interface HierarchyInterface extends HierarchyInterfaceInterface {
@TestAnnotation5
@TestInheritedAnnotation5
public void method();
void method();
}
@TestAnnotation6
static interface HierarchyInterfaceInterface {
interface HierarchyInterfaceInterface {
@TestAnnotation6
public void method();
void method();
}
static class BridgedMethod implements BridgeMethod<String> {
@@ -738,37 +713,32 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method(String arg) {
}
}
static interface BridgeMethod<T> {
interface BridgeMethod<T> {
@TestAnnotation2
void method(T arg);
}
static class Ignoreable implements IgnoreableOverrideInterface1,
IgnoreableOverrideInterface2, Serializable {
@SuppressWarnings("serial")
static class Ignoreable implements IgnoreableOverrideInterface1, IgnoreableOverrideInterface2, Serializable {
@TestAnnotation1
public void method() {
}
}
static interface IgnoreableOverrideInterface1 {
interface IgnoreableOverrideInterface1 {
@Nullable
public void method();
void method();
}
static interface IgnoreableOverrideInterface2 {
interface IgnoreableOverrideInterface2 {
@Nullable
public void method();
void method();
}
static abstract class MultipleMethods implements MultipleMethodsInterface {
@@ -776,7 +746,6 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method() {
}
}
interface MultipleMethodsInterface {
@@ -786,23 +755,19 @@ public class AnnotationsScannerTests {
@TestAnnotation2
void method1();
}
static class GenericOverride implements GenericOverrideInterface<String> {
@TestAnnotation1
public void method(String argument) {
}
}
static interface GenericOverrideInterface<T extends CharSequence> {
interface GenericOverrideInterface<T extends CharSequence> {
@TestAnnotation2
void method(T argument);
}
static abstract class GenericNonOverride
@@ -810,16 +775,13 @@ public class AnnotationsScannerTests {
@TestAnnotation1
public void method(StringBuilder argument) {
}
}
static interface GenericNonOverrideInterface<T extends CharSequence> {
interface GenericNonOverrideInterface<T extends CharSequence> {
@TestAnnotation2
void method(T argument);
}
}

View File

@@ -23,7 +23,6 @@ import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import org.junit.Test;
@@ -31,8 +30,7 @@ import org.junit.Test;
import org.springframework.core.annotation.MergedAnnotation.MapValues;
import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.*;
/**
* Tests for {@link MergedAnnotationCollectors}.
@@ -93,18 +91,10 @@ public class MergedAnnotationCollectorsTests {
assertThat(map.get("finished")).containsExactly(true);
}
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void toFinishedMultiValueMapWhenFinisherIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> stream().collect(
MergedAnnotationCollectors.toMultiValueMap((Function) null))).withMessage(
"Finisher must not be null");
private Stream<MergedAnnotation<TestAnnotation>> stream() {
return MergedAnnotations.from(WithTestAnnotations.class).stream(TestAnnotation.class);
}
private Stream<MergedAnnotation<TestAnnotation>> stream() {
return MergedAnnotations.from(WithTestAnnotations.class).stream(
TestAnnotation.class);
}
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(TestAnnotations.class)
@@ -124,14 +114,12 @@ public class MergedAnnotationCollectorsTests {
@interface TestAnnotations {
TestAnnotation[] value();
}
@TestAnnotation("a")
@TestAnnotation(name = "b", extra = String.class)
@TestAnnotation(name = "c", extra = Integer.class)
static class WithTestAnnotations {
}
}

View File

@@ -16,20 +16,17 @@
package org.springframework.core.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.*;
/**
* Tests for {@link MergedAnnotationPredicates}.
@@ -54,35 +51,18 @@ public class MergedAnnotationPredicatesTests {
MissingAnnotation.class.getName())).rejects(annotation);
}
@Test
public void typeInStringArrayWhenStringArraysIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> MergedAnnotationPredicates.typeIn((String[]) null)).withMessage(
"TypeNames must not be null");
}
@Test
public void typeInClassArrayWhenNameMatchesAccepts() {
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
WithTestAnnotation.class).get(TestAnnotation.class);
assertThat(MergedAnnotationPredicates.typeIn(TestAnnotation.class)).accepts(
annotation);
MergedAnnotation<TestAnnotation> annotation =
MergedAnnotations.from(WithTestAnnotation.class).get(TestAnnotation.class);
assertThat(MergedAnnotationPredicates.typeIn(TestAnnotation.class)).accepts(annotation);
}
@Test
public void typeInClassArrayWhenNameDoesNotMatchRejects() {
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
WithTestAnnotation.class).get(TestAnnotation.class);
assertThat(MergedAnnotationPredicates.typeIn(MissingAnnotation.class)).rejects(
annotation);
}
@Test
public void typeInClassArrayWhenClassArraysIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> MergedAnnotationPredicates.typeIn(
(Class<Annotation>[]) null)).withMessage(
"Types must not be null");
MergedAnnotation<TestAnnotation> annotation =
MergedAnnotations.from(WithTestAnnotation.class).get(TestAnnotation.class);
assertThat(MergedAnnotationPredicates.typeIn(MissingAnnotation.class)).rejects(annotation);
}
@Test
@@ -90,8 +70,7 @@ public class MergedAnnotationPredicatesTests {
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
WithTestAnnotation.class).get(TestAnnotation.class);
assertThat(MergedAnnotationPredicates.typeIn(
Collections.singleton(TestAnnotation.class.getName()))).accepts(
annotation);
Collections.singleton(TestAnnotation.class.getName()))).accepts(annotation);
}
@Test
@@ -107,15 +86,7 @@ public class MergedAnnotationPredicatesTests {
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
WithTestAnnotation.class).get(TestAnnotation.class);
assertThat(MergedAnnotationPredicates.typeIn(Arrays.asList(
MissingAnnotation.class.getName(), MissingAnnotation.class))).rejects(
annotation);
}
@Test
public void typeInCollectionWhenCollectionIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> MergedAnnotationPredicates.typeIn(
(Collection<?>) null)).withMessage("Types must not be null");
MissingAnnotation.class.getName(), MissingAnnotation.class))).rejects(annotation);
}
@Test
@@ -125,15 +96,13 @@ public class MergedAnnotationPredicatesTests {
MergedAnnotationPredicates.firstRunOf(
this::firstCharOfValue)).collect(Collectors.toList());
assertThat(filtered.stream().map(
annotation -> annotation.getString("value"))).containsExactly("a1", "a2",
"a3");
annotation -> annotation.getString("value"))).containsExactly("a1", "a2", "a3");
}
@Test
public void firstRunOfWhenValueExtractorIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> MergedAnnotationPredicates.firstRunOf(null)).withMessage(
"ValueExtractor must not be null");
() -> MergedAnnotationPredicates.firstRunOf(null));
}
@Test
@@ -143,42 +112,38 @@ public class MergedAnnotationPredicatesTests {
MergedAnnotationPredicates.unique(
this::firstCharOfValue)).collect(Collectors.toList());
assertThat(filtered.stream().map(
annotation -> annotation.getString("value"))).containsExactly("a1", "b1",
"c1");
annotation -> annotation.getString("value"))).containsExactly("a1", "b1", "c1");
}
@Test
public void uniqueWhenKeyExtractorIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> MergedAnnotationPredicates.unique(null)).withMessage(
"KeyExtractor must not be null");
() -> MergedAnnotationPredicates.unique(null));
}
private char firstCharOfValue(MergedAnnotation<TestAnnotation> annotation) {
return annotation.getString("value").charAt(0);
}
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(TestAnnotations.class)
static @interface TestAnnotation {
@interface TestAnnotation {
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnotations {
@interface TestAnnotations {
TestAnnotation[] value();
}
static @interface MissingAnnotation {
@interface MissingAnnotation {
}
@TestAnnotation("test")
static class WithTestAnnotation {
}
@TestAnnotation("a1")
@@ -191,7 +156,6 @@ public class MergedAnnotationPredicatesTests {
@TestAnnotation("c2")
@TestAnnotation("c3")
static class WithMultipleTestAnnotation {
}
}

View File

@@ -24,19 +24,16 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Resource;
import org.junit.Test;
@@ -74,44 +71,41 @@ public class MergedAnnotationsTests {
@Test
public void streamWhenFromNonAnnotatedClass() {
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).stream(
TransactionalComponent.class)).isEmpty();
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).
stream(TransactionalComponent.class)).isEmpty();
}
@Test
public void streamWhenFromClassWithMetaDepth1() {
Stream<String> names = MergedAnnotations.from(
TransactionalComponent.class).stream().map(MergedAnnotation::getType);
Stream<String> names = MergedAnnotations.from(TransactionalComponent.class)
.stream().map(MergedAnnotation::getType);
assertThat(names).containsExactly(Transactional.class.getName(),
Component.class.getName(), Indexed.class.getName());
}
@Test
public void streamWhenFromClassWithMetaDepth2() {
Stream<String> names = MergedAnnotations.from(
ComposedTransactionalComponent.class).stream().map(
MergedAnnotation::getType);
Stream<String> names = MergedAnnotations.from(ComposedTransactionalComponent.class)
.stream().map(MergedAnnotation::getType);
assertThat(names).containsExactly(TransactionalComponent.class.getName(),
Transactional.class.getName(), Component.class.getName(),
Indexed.class.getName());
Transactional.class.getName(), Component.class.getName(), Indexed.class.getName());
}
@Test
public void isPresentWhenFromNonAnnotatedClass() {
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).isPresent(
Transactional.class)).isFalse();
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).
isPresent(Transactional.class)).isFalse();
}
@Test
public void isPresentWhenFromAnnotationClassWithMetaDepth0() {
assertThat(MergedAnnotations.from(TransactionalComponent.class).isPresent(
TransactionalComponent.class)).isFalse();
assertThat(MergedAnnotations.from(TransactionalComponent.class).
isPresent(TransactionalComponent.class)).isFalse();
}
@Test
public void isPresentWhenFromAnnotationClassWithMetaDepth1() {
MergedAnnotations annotations = MergedAnnotations.from(
TransactionalComponent.class);
MergedAnnotations annotations = MergedAnnotations.from(TransactionalComponent.class);
assertThat(annotations.isPresent(Transactional.class)).isTrue();
assertThat(annotations.isPresent(Component.class)).isTrue();
}
@@ -204,8 +198,6 @@ public class MergedAnnotationsTests {
* type within the class hierarchy. Such undesirable behavior would cause
* the logic in
* {@link org.springframework.context.annotation.ProfileCondition} to fail.
*
* @see org.springframework.core.env.EnvironmentSystemIntegrationTests#mostSpecificDerivedClassDrivesEnvironment_withDevEnvAndDerivedDevConfigClass
*/
@Test
public void collectMultiValueMapFromClassWithLocalAnnotationThatShadowsAnnotationFromSuperclass() {
@@ -218,8 +210,6 @@ public class MergedAnnotationsTests {
/**
* Note: this functionality is required by
* {@link org.springframework.context.annotation.ProfileCondition}.
*
* @see org.springframework.core.env.EnvironmentSystemIntegrationTests
*/
@Test
public void collectMultiValueMapFromClassWithMultipleComposedAnnotations() {
@@ -629,38 +619,26 @@ public class MergedAnnotationsTests {
}
@Test
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaConvention()
throws Exception {
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaConvention() throws Exception {
testGetWithExhaustiveWebMapping(
WebController.class.getMethod("postMappedWithPathAttribute"));
}
@Test
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaAliasFor()
throws Exception {
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaAliasFor() throws Exception {
testGetWithExhaustiveWebMapping(
WebController.class.getMethod("getMappedWithValueAttribute"));
testGetWithExhaustiveWebMapping(
WebController.class.getMethod("getMappedWithPathAttribute"));
}
private void testGetWithExhaustiveWebMapping(AnnotatedElement element)
throws ArrayComparisonFailure {
private void testGetWithExhaustiveWebMapping(AnnotatedElement element) throws ArrayComparisonFailure {
MergedAnnotation<?> annotation = MergedAnnotations.from(element,
SearchStrategy.EXHAUSTIVE).get(RequestMapping.class);
assertThat(annotation.getStringArray("value")).containsExactly("/test");
assertThat(annotation.getStringArray("path")).containsExactly("/test");
}
@Test
public void getDirectWithJavaLangAnnotationType() throws Exception {
Constructor<?> deprecatedConstructor = Date.class.getConstructor(String.class);
MergedAnnotation<?> annotation = MergedAnnotations.from(deprecatedConstructor,
SearchStrategy.DIRECT, RepeatableContainers.standardRepeatables(),
AnnotationFilter.NONE).get(Deprecated.class);
assertThat(annotation.isPresent()).isTrue();
}
@Test
public void getDirectWithJavaxAnnotationType() throws Exception {
assertThat(MergedAnnotations.from(ResourceHolder.class).get(
@@ -1267,14 +1245,6 @@ public class MergedAnnotationsTests {
Ordered.LOWEST_PRECEDENCE);
}
@Test
public void getRepeatableOnComposedAnnotation() {
MergedAnnotation<?> annotation = MergedAnnotations.from(MyRepeatableMeta1.class,
SearchStrategy.EXHAUSTIVE, RepeatableContainers.none(),
AnnotationFilter.NONE).get(Repeatable.class);
assertThat(annotation.getClass("value")).isEqualTo(MyRepeatableContainer.class);
}
@Test
public void getRepeatableDeclaredOnMethod() throws Exception {
Method method = InterfaceWithRepeated.class.getMethod("foo");
@@ -1286,8 +1256,7 @@ public class MergedAnnotationsTests {
}
@Test
public void getRepeatableDeclaredOnClassWithMissingAttributeAliasDeclaration()
throws Exception {
public void getRepeatableDeclaredOnClassWithMissingAttributeAliasDeclaration() {
RepeatableContainers containers = RepeatableContainers.of(
BrokenContextConfiguration.class, BrokenHierarchy.class);
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(