Introduce isSynthesizable in MergedAnnotation
This commit adds the ability to check if a the annotation managed by a MergedAnnotation is synthesizable. This makes it easier to register a JDK proxy hint if necessary See gh-28967
This commit is contained in:
@@ -477,6 +477,15 @@ public interface MergedAnnotation<A extends Annotation> {
|
||||
*/
|
||||
<T extends Map<String, Object>> T asMap(Function<MergedAnnotation<?>, T> factory, Adapt... adaptations);
|
||||
|
||||
/**
|
||||
* Determine if this merged annotation is <em>synthesizable</em>.
|
||||
* <p>Consult the documentation for {@link #synthesize()} for an explanation
|
||||
* of what is considered synthesizable.
|
||||
* @return {@code true} if the mapped annotation is synthesizable
|
||||
* @since 6.0
|
||||
*/
|
||||
boolean isSynthesizable();
|
||||
|
||||
/**
|
||||
* Create a type-safe synthesized version of this merged annotation that can
|
||||
* be used directly in code.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -134,6 +134,11 @@ final class MissingMergedAnnotation<A extends Annotation> extends AbstractMerged
|
||||
return factory.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSynthesizable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(missing)";
|
||||
|
||||
@@ -319,6 +319,17 @@ final class TypeMappedAnnotation<A extends Annotation> extends AbstractMergedAnn
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSynthesizable() {
|
||||
// Is this a mapped annotation for a composed annotation, and are there
|
||||
// annotation attributes (mirrors) that need to be merged?
|
||||
if (getDistance() > 0 && this.resolvedMirrors.length > 0) {
|
||||
return true;
|
||||
}
|
||||
// Is the mapped annotation itself synthesizable?
|
||||
return this.mapping.isSynthesizable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected A createSynthesizedAnnotation() {
|
||||
@@ -347,22 +358,15 @@ final class TypeMappedAnnotation<A extends Annotation> extends AbstractMergedAnn
|
||||
* Determine if the supplied annotation has not already been synthesized
|
||||
* <strong>and</strong> whether the mapped annotation is a composed annotation
|
||||
* that needs to have its attributes merged or the mapped annotation is
|
||||
* {@linkplain AnnotationTypeMapping#isSynthesizable() synthesizable} in general.
|
||||
* {@linkplain #isSynthesizable() synthesizable} in general.
|
||||
* @param annotation the annotation to check
|
||||
* @since 5.3.22
|
||||
*/
|
||||
private boolean isSynthesizable(Annotation annotation) {
|
||||
// Already synthesized?
|
||||
if (annotation instanceof SynthesizedAnnotation) {
|
||||
return false;
|
||||
}
|
||||
// Is this a mapped annotation for a composed annotation, and are there
|
||||
// annotation attributes (mirrors) that need to be merged?
|
||||
if (getDistance() > 0 && this.resolvedMirrors.length > 0) {
|
||||
return true;
|
||||
}
|
||||
// Is the mapped annotation itself synthesizable?
|
||||
return this.mapping.isSynthesizable();
|
||||
return isSynthesizable();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1504,6 +1504,13 @@ class MergedAnnotationsTests {
|
||||
assertThat(synthesizedComponent.value()).isEqualTo("webController");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isSynthesizableWithoutAttributeAliases() throws Exception {
|
||||
Component component = WebController.class.getAnnotation(Component.class);
|
||||
assertThat(component).isNotNull();
|
||||
assertThat(MergedAnnotation.from(component).isSynthesizable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void synthesizeAlreadySynthesized() throws Exception {
|
||||
Method method = WebController.class.getMethod("handleMappedWithValueAttribute");
|
||||
@@ -1567,10 +1574,16 @@ class MergedAnnotationsTests {
|
||||
void synthesizeShouldNotSynthesizeNonsynthesizableAnnotationsWhenUsingMergedAnnotationsFromApi() {
|
||||
MergedAnnotations mergedAnnotations = MergedAnnotations.from(SecurityConfig.class);
|
||||
|
||||
EnableWebSecurity enableWebSecurity = mergedAnnotations.get(EnableWebSecurity.class).synthesize();
|
||||
MergedAnnotation<EnableWebSecurity> enableWebSecurityAnnotation =
|
||||
mergedAnnotations.get(EnableWebSecurity.class);
|
||||
assertThat(enableWebSecurityAnnotation.isSynthesizable()).isFalse();
|
||||
EnableWebSecurity enableWebSecurity = enableWebSecurityAnnotation.synthesize();
|
||||
assertThat(enableWebSecurity).isNotInstanceOf(SynthesizedAnnotation.class);
|
||||
|
||||
EnableGlobalAuthentication enableGlobalAuthentication = mergedAnnotations.get(EnableGlobalAuthentication.class).synthesize();
|
||||
MergedAnnotation<EnableGlobalAuthentication> enableGlobalAuthenticationMergedAnnotation =
|
||||
mergedAnnotations.get(EnableGlobalAuthentication.class);
|
||||
assertThat(enableGlobalAuthenticationMergedAnnotation.isSynthesizable()).isFalse();
|
||||
EnableGlobalAuthentication enableGlobalAuthentication = enableGlobalAuthenticationMergedAnnotation.synthesize();
|
||||
assertThat(enableGlobalAuthentication).isNotInstanceOf(SynthesizedAnnotation.class);
|
||||
}
|
||||
|
||||
@@ -1718,8 +1731,9 @@ class MergedAnnotationsTests {
|
||||
ImplicitAliasesTestConfiguration config = clazz.getAnnotation(
|
||||
ImplicitAliasesTestConfiguration.class);
|
||||
assertThat(config).isNotNull();
|
||||
ImplicitAliasesTestConfiguration synthesized = MergedAnnotation.from(
|
||||
config).synthesize();
|
||||
MergedAnnotation<ImplicitAliasesTestConfiguration> mergedAnnotation = MergedAnnotation.from(config);
|
||||
assertThat(mergedAnnotation.isSynthesizable()).isTrue();
|
||||
ImplicitAliasesTestConfiguration synthesized = mergedAnnotation.synthesize();
|
||||
assertThat(synthesized).isInstanceOf(SynthesizedAnnotation.class);
|
||||
assertThat(synthesized.value()).isEqualTo(expected);
|
||||
assertThat(synthesized.location1()).isEqualTo(expected);
|
||||
@@ -1746,8 +1760,11 @@ class MergedAnnotationsTests {
|
||||
ImplicitAliasesWithImpliedAliasNamesOmittedTestConfiguration config = clazz.getAnnotation(
|
||||
ImplicitAliasesWithImpliedAliasNamesOmittedTestConfiguration.class);
|
||||
assertThat(config).isNotNull();
|
||||
MergedAnnotation<ImplicitAliasesWithImpliedAliasNamesOmittedTestConfiguration> mergedAnnotation =
|
||||
MergedAnnotation.from(config);
|
||||
assertThat(mergedAnnotation.isSynthesizable()).isTrue();
|
||||
ImplicitAliasesWithImpliedAliasNamesOmittedTestConfiguration synthesized =
|
||||
MergedAnnotation.from(config).synthesize();
|
||||
mergedAnnotation.synthesize();
|
||||
assertThat(synthesized).isInstanceOf(SynthesizedAnnotation.class);
|
||||
assertThat(synthesized.value()).isEqualTo(expected);
|
||||
assertThat(synthesized.location()).isEqualTo(expected);
|
||||
|
||||
@@ -255,6 +255,11 @@ class MissingMergedAnnotationTests {
|
||||
assertThat(this.missing.getDefaultValue("value", Integer.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isSynthesizableReturnsFalse() {
|
||||
assertThat(this.missing.isSynthesizable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void synthesizeThrowsNoSuchElementException() {
|
||||
assertThatNoSuchElementException().isThrownBy(this.missing::synthesize);
|
||||
|
||||
Reference in New Issue
Block a user