Hide MergedAnnotation Implementation Details
Issue gh-15286
This commit is contained in:
parent
095929f6e8
commit
cc6de8fa5d
|
@ -17,29 +17,30 @@
|
||||||
package org.springframework.security.core.annotation;
|
package org.springframework.security.core.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.AnnotatedElement;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Parameter;
|
import java.lang.reflect.Parameter;
|
||||||
|
|
||||||
import org.springframework.core.annotation.MergedAnnotation;
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for synthesizing an annotation from an {@link AnnotatedElement}.
|
* An interface to search for and synthesize an annotation on a type, method, or method
|
||||||
|
* parameter into an annotation of type {@code <A>}.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Implementations should support meta-annotations. This is usually by way of the
|
||||||
|
* {@link org.springframework.core.annotation.MergedAnnotations} API.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Synthesis generally refers to the process of taking an annotation's meta-annotations
|
* Synthesis generally refers to the process of taking an annotation's meta-annotations
|
||||||
* and placeholders, resolving them, and then combining these elements into a facade of
|
* and placeholders, resolving them, and then combining these elements into a facade of
|
||||||
* the raw annotation instance.
|
* the raw annotation instance.
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Since the process of synthesizing an annotation can be expensive, it is recommended to
|
* Since the process of synthesizing an annotation can be expensive, it's recommended to
|
||||||
* cache the synthesized annotation to prevent multiple computations.
|
* cache the synthesized annotation to prevent multiple computations.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param <A> the annotation type
|
* @param <A> the annotation to search for and synthesize
|
||||||
* @author Josh Cummings
|
* @author Josh Cummings
|
||||||
* @since 6.4
|
* @since 6.4
|
||||||
* @see UniqueMergedAnnotationSynthesizer
|
* @see UniqueMergedAnnotationSynthesizer
|
||||||
|
@ -48,41 +49,36 @@ import org.springframework.util.Assert;
|
||||||
public interface AnnotationSynthesizer<A extends Annotation> {
|
public interface AnnotationSynthesizer<A extends Annotation> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synthesize an annotation of type {@code A} from the given {@link AnnotatedElement}.
|
* Synthesize an annotation of type {@code A} from the given method.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Implementations should fail if they encounter more than one annotation of that type
|
* Implementations should fail if they encounter more than one annotation of that type
|
||||||
* on the element.
|
* attributable to the method.
|
||||||
* </p>
|
*
|
||||||
|
* <p>
|
||||||
|
* Implementations should describe their strategy for searching the element and any
|
||||||
|
* surrounding class, interfaces, or super-class.
|
||||||
|
* @param method the method to search from
|
||||||
|
* @param targetClass the target class for the method
|
||||||
|
* @return the synthesized annotation or {@code null} if not found
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
A synthesize(Method method, Class<?> targetClass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synthesize an annotation of type {@code A} from the given method parameter.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Implementations should fail if they encounter more than one annotation of that type
|
||||||
|
* attributable to the parameter.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Implementations should describe their strategy for searching the element and any
|
* Implementations should describe their strategy for searching the element and any
|
||||||
* surrounding class, interfaces, or super-class.
|
* surrounding class, interfaces, or super-class.
|
||||||
* </p>
|
|
||||||
* @param element the element to search
|
* @param element the element to search
|
||||||
* @return the synthesized annotation or {@code null} if not found
|
* @return the synthesized annotation or {@code null} if not found
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default A synthesize(AnnotatedElement element, Class<?> targetClass) {
|
A synthesize(Parameter parameter);
|
||||||
Assert.notNull(targetClass, "targetClass cannot be null");
|
|
||||||
MergedAnnotation<A> annotation = merge(element, targetClass);
|
|
||||||
if (annotation == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return annotation.synthesize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
default A synthesize(AnnotatedElement element) {
|
|
||||||
if (element instanceof Method method) {
|
|
||||||
return synthesize(element, method.getDeclaringClass());
|
|
||||||
}
|
|
||||||
if (element instanceof Parameter parameter) {
|
|
||||||
return synthesize(parameter, parameter.getDeclaringExecutable().getDeclaringClass());
|
|
||||||
}
|
|
||||||
throw new UnsupportedOperationException("Unsupported element of type " + element.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,16 @@ import org.springframework.util.Assert;
|
||||||
import org.springframework.util.PropertyPlaceholderHelper;
|
import org.springframework.util.PropertyPlaceholderHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for synthesizing an annotation from an {@link AnnotatedElement} that
|
* Searches for and synthesizes an annotation on a type, method, or method parameter into
|
||||||
* supports meta-annotations with placeholders, like the following:
|
* an annotation of type {@code <A>}, resolving any placeholders in the annotation value.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note that in all cases, Spring Security does not allow for repeatable annotations. So
|
||||||
|
* this class delegates to {@link UniqueMergedAnnotationSynthesizer} in order to error if
|
||||||
|
* a repeat is discovered.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It supports meta-annotations with placeholders, like the following:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* @PreAuthorize("hasRole({role})")
|
* @PreAuthorize("hasRole({role})")
|
||||||
|
@ -46,19 +54,14 @@ import org.springframework.util.PropertyPlaceholderHelper;
|
||||||
* {@code @HasRole} annotation found on a given {@link AnnotatedElement}.
|
* {@code @HasRole} annotation found on a given {@link AnnotatedElement}.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Note that in all cases, Spring Security does not allow for repeatable annotations. So
|
|
||||||
* this class delegates to {@link UniqueMergedAnnotationSynthesizer} in order to error if
|
|
||||||
* a repeat is discovered.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Since the process of synthesis is expensive, it is recommended to cache the synthesized
|
* Since the process of synthesis is expensive, it is recommended to cache the synthesized
|
||||||
* result to prevent multiple computations.
|
* result to prevent multiple computations.
|
||||||
*
|
*
|
||||||
* @param <A> the annotation type
|
* @param <A> the annotation to search for and synthesize
|
||||||
* @author Josh Cummings
|
* @author Josh Cummings
|
||||||
* @since 6.4
|
* @since 6.4
|
||||||
*/
|
*/
|
||||||
final class ExpressionTemplateAnnotationSynthesizer<A extends Annotation> implements AnnotationSynthesizer<A> {
|
final class ExpressionTemplateAnnotationSynthesizer<A extends Annotation> extends AbstractAnnotationSynthesizer<A> {
|
||||||
|
|
||||||
private final Class<A> type;
|
private final Class<A> type;
|
||||||
|
|
||||||
|
@ -79,7 +82,7 @@ final class ExpressionTemplateAnnotationSynthesizer<A extends Annotation> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass) {
|
MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass) {
|
||||||
if (element instanceof Parameter parameter) {
|
if (element instanceof Parameter parameter) {
|
||||||
MergedAnnotation<A> annotation = this.uniqueParameterAnnotationCache.computeIfAbsent(parameter,
|
MergedAnnotation<A> annotation = this.uniqueParameterAnnotationCache.computeIfAbsent(parameter,
|
||||||
(p) -> this.unique.merge(p, targetClass));
|
(p) -> this.unique.merge(p, targetClass));
|
||||||
|
|
|
@ -34,8 +34,33 @@ import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for synthesizing an annotation from an {@link AnnotatedElement} that
|
* Searches for and synthesizes annotations found on types, methods, or method parameters
|
||||||
* supports meta-annotations, like the following:
|
* into an annotation of type {@code <A>}, ensuring that there is a unique match.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note that in all cases, Spring Security does not allow for repeatable annotations. As
|
||||||
|
* such, this class errors if a repeat is discovered.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* For example, if a class extends two interfaces, and each interface is annotated with
|
||||||
|
* `@PreAuthorize("hasRole('ADMIN')")` and `@PreAuthorize("hasRole('USER')")`
|
||||||
|
* respectively, it's not clear which of these should apply, and so this class will throw
|
||||||
|
* an exception.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If the given annotation can be applied to types or methods, this class will traverse
|
||||||
|
* the type hierarchy, starting from the target class and method; in case of a method
|
||||||
|
* parameter, it will only consider annotations on the parameter. In all cases, it will
|
||||||
|
* consider meta-annotations in its traversal.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* When traversing the type hierarchy, this class will first look for annotations on the
|
||||||
|
* given method, then on any methods that method overrides. If no annotations are found,
|
||||||
|
* it will then search for annotations on the given class, then on any classes that class
|
||||||
|
* extends and on any interfaces that class implements.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It supports meta-annotations, like the following:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* @PreAuthorize("hasRole('ROLE_ADMIN')")
|
* @PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
|
@ -46,33 +71,18 @@ import org.springframework.util.ClassUtils;
|
||||||
* <p>
|
* <p>
|
||||||
* In that case, you can use an {@link UniqueMergedAnnotationSynthesizer} of type
|
* In that case, you can use an {@link UniqueMergedAnnotationSynthesizer} of type
|
||||||
* {@link org.springframework.security.access.prepost.PreAuthorize} to synthesize any
|
* {@link org.springframework.security.access.prepost.PreAuthorize} to synthesize any
|
||||||
* {@code @HasRole} annotation found on a given {@link AnnotatedElement}.
|
* {@code @HasRole} annotation found on a given method or class into its
|
||||||
|
* {@link org.springframework.security.access.prepost.PreAuthorize} meta-annotation.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Note that in all cases, Spring Security does not allow for repeatable annotations. As
|
* Since the process of synthesis is expensive, it's recommended to cache the synthesized
|
||||||
* such, this class errors if a repeat is discovered.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* If the given annotation can be applied to types, this class will search for annotations
|
|
||||||
* across the entire {@link MergedAnnotations.SearchStrategy type hierarchy}; otherwise,
|
|
||||||
* it will only look for annotations {@link MergedAnnotations.SearchStrategy directly}
|
|
||||||
* attributed to the element.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* When traversing the type hierarchy, this class will first look for annotations on the
|
|
||||||
* given method, then on any methods that method overrides. If no annotations are found,
|
|
||||||
* it will then search for annotations on the given class, then on any classes that class
|
|
||||||
* extends and on any interfaces that class implements.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Since the process of synthesis is expensive, it is recommended to cache the synthesized
|
|
||||||
* result to prevent multiple computations.
|
* result to prevent multiple computations.
|
||||||
*
|
*
|
||||||
* @param <A> the annotation type
|
* @param <A> the annotation to search for and synthesize
|
||||||
* @author Josh Cummings
|
* @author Josh Cummings
|
||||||
* @since 6.4
|
* @since 6.4
|
||||||
*/
|
*/
|
||||||
final class UniqueMergedAnnotationSynthesizer<A extends Annotation> implements AnnotationSynthesizer<A> {
|
final class UniqueMergedAnnotationSynthesizer<A extends Annotation> extends AbstractAnnotationSynthesizer<A> {
|
||||||
|
|
||||||
private final List<Class<A>> types;
|
private final List<Class<A>> types;
|
||||||
|
|
||||||
|
@ -87,26 +97,18 @@ final class UniqueMergedAnnotationSynthesizer<A extends Annotation> implements A
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass) {
|
MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass) {
|
||||||
if (element instanceof Parameter parameter) {
|
if (element instanceof Parameter parameter) {
|
||||||
return handleParameterElement(parameter);
|
List<MergedAnnotation<A>> annotations = findDirectAnnotations(parameter);
|
||||||
|
return requireUnique(parameter, annotations);
|
||||||
}
|
}
|
||||||
if (element instanceof Method method) {
|
if (element instanceof Method method) {
|
||||||
return handleMethodElement(method, targetClass);
|
List<MergedAnnotation<A>> annotations = findMethodAnnotations(method, targetClass);
|
||||||
|
return requireUnique(method, annotations);
|
||||||
}
|
}
|
||||||
throw new AnnotationConfigurationException("Unsupported element of type " + element.getClass());
|
throw new AnnotationConfigurationException("Unsupported element of type " + element.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
private MergedAnnotation<A> handleParameterElement(Parameter parameter) {
|
|
||||||
List<MergedAnnotation<A>> annotations = findDirectAnnotations(parameter);
|
|
||||||
return requireUnique(parameter, annotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MergedAnnotation<A> handleMethodElement(Method method, Class<?> targetClass) {
|
|
||||||
List<MergedAnnotation<A>> annotations = findMethodAnnotations(method, targetClass);
|
|
||||||
return requireUnique(method, annotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MergedAnnotation<A> requireUnique(AnnotatedElement element, List<MergedAnnotation<A>> annotations) {
|
private MergedAnnotation<A> requireUnique(AnnotatedElement element, List<MergedAnnotation<A>> annotations) {
|
||||||
return switch (annotations.size()) {
|
return switch (annotations.size()) {
|
||||||
case 0 -> null;
|
case 0 -> null;
|
||||||
|
|
|
@ -37,35 +37,35 @@ public class UniqueMergedAnnotationSynthesizerTests {
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenAnnotationOnInterfaceThenResolves() throws Exception {
|
void synthesizeWhenAnnotationOnInterfaceThenResolves() throws Exception {
|
||||||
Method method = AnnotationOnInterface.class.getDeclaredMethod("method");
|
Method method = AnnotationOnInterface.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("one");
|
assertThat(preAuthorize.value()).isEqualTo("one");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenAnnotationOnMethodThenResolves() throws Exception {
|
void synthesizeWhenAnnotationOnMethodThenResolves() throws Exception {
|
||||||
Method method = AnnotationOnInterfaceMethod.class.getDeclaredMethod("method");
|
Method method = AnnotationOnInterfaceMethod.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("three");
|
assertThat(preAuthorize.value()).isEqualTo("three");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenAnnotationOnClassThenResolves() throws Exception {
|
void synthesizeWhenAnnotationOnClassThenResolves() throws Exception {
|
||||||
Method method = AnnotationOnClass.class.getDeclaredMethod("method");
|
Method method = AnnotationOnClass.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("five");
|
assertThat(preAuthorize.value()).isEqualTo("five");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenAnnotationOnClassMethodThenResolves() throws Exception {
|
void synthesizeWhenAnnotationOnClassMethodThenResolves() throws Exception {
|
||||||
Method method = AnnotationOnClassMethod.class.getDeclaredMethod("method");
|
Method method = AnnotationOnClassMethod.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("six");
|
assertThat(preAuthorize.value()).isEqualTo("six");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenInterfaceOverridingAnnotationOnInterfaceThenResolves() throws Exception {
|
void synthesizeWhenInterfaceOverridingAnnotationOnInterfaceThenResolves() throws Exception {
|
||||||
Method method = InterfaceMethodOverridingAnnotationOnInterface.class.getDeclaredMethod("method");
|
Method method = InterfaceMethodOverridingAnnotationOnInterface.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("eight");
|
assertThat(preAuthorize.value()).isEqualTo("eight");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,14 +73,14 @@ public class UniqueMergedAnnotationSynthesizerTests {
|
||||||
void synthesizeWhenInterfaceOverridingMultipleInterfaceInheritanceThenResolves() throws Exception {
|
void synthesizeWhenInterfaceOverridingMultipleInterfaceInheritanceThenResolves() throws Exception {
|
||||||
Method method = ClassInheritingInterfaceOverridingMultipleInterfaceInheritance.class
|
Method method = ClassInheritingInterfaceOverridingMultipleInterfaceInheritance.class
|
||||||
.getDeclaredMethod("method");
|
.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("ten");
|
assertThat(preAuthorize.value()).isEqualTo("ten");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenInterfaceMethodOverridingAnnotationOnInterfaceThenResolves() throws Exception {
|
void synthesizeWhenInterfaceMethodOverridingAnnotationOnInterfaceThenResolves() throws Exception {
|
||||||
Method method = InterfaceMethodOverridingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
Method method = InterfaceMethodOverridingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("eleven");
|
assertThat(preAuthorize.value()).isEqualTo("eleven");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,63 +88,63 @@ public class UniqueMergedAnnotationSynthesizerTests {
|
||||||
void synthesizeWhenClassMultipleInheritanceThenException() throws Exception {
|
void synthesizeWhenClassMultipleInheritanceThenException() throws Exception {
|
||||||
Method method = ClassAttemptingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
Method method = ClassAttemptingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
||||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||||
.isThrownBy(() -> this.synthesizer.synthesize(method));
|
.isThrownBy(() -> this.synthesizer.synthesize(method, method.getDeclaringClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// gh-15097
|
// gh-15097
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassOverridingMultipleInterfaceInheritanceThenResolves() throws Exception {
|
void synthesizeWhenClassOverridingMultipleInterfaceInheritanceThenResolves() throws Exception {
|
||||||
Method method = ClassOverridingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
Method method = ClassOverridingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("thirteen");
|
assertThat(preAuthorize.value()).isEqualTo("thirteen");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassMethodOverridingMultipleInterfaceInheritanceThenResolves() throws Exception {
|
void synthesizeWhenClassMethodOverridingMultipleInterfaceInheritanceThenResolves() throws Exception {
|
||||||
Method method = ClassMethodOverridingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
Method method = ClassMethodOverridingMultipleInterfaceInheritance.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("fourteen");
|
assertThat(preAuthorize.value()).isEqualTo("fourteen");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassInheritingInterfaceOverridingInterfaceAnnotationThenResolves() throws Exception {
|
void synthesizeWhenClassInheritingInterfaceOverridingInterfaceAnnotationThenResolves() throws Exception {
|
||||||
Method method = ClassInheritingInterfaceOverridingInterfaceAnnotation.class.getDeclaredMethod("method");
|
Method method = ClassInheritingInterfaceOverridingInterfaceAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("seven");
|
assertThat(preAuthorize.value()).isEqualTo("seven");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassOverridingGrandparentInterfaceAnnotationThenResolves() throws Exception {
|
void synthesizeWhenClassOverridingGrandparentInterfaceAnnotationThenResolves() throws Exception {
|
||||||
Method method = ClassOverridingGrandparentInterfaceAnnotation.class.getDeclaredMethod("method");
|
Method method = ClassOverridingGrandparentInterfaceAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("sixteen");
|
assertThat(preAuthorize.value()).isEqualTo("sixteen");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenMethodOverridingGrandparentInterfaceAnnotationThenResolves() throws Exception {
|
void synthesizeWhenMethodOverridingGrandparentInterfaceAnnotationThenResolves() throws Exception {
|
||||||
Method method = MethodOverridingGrandparentInterfaceAnnotation.class.getDeclaredMethod("method");
|
Method method = MethodOverridingGrandparentInterfaceAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("seventeen");
|
assertThat(preAuthorize.value()).isEqualTo("seventeen");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassInheritingMethodOverriddenAnnotationThenResolves() throws Exception {
|
void synthesizeWhenClassInheritingMethodOverriddenAnnotationThenResolves() throws Exception {
|
||||||
Method method = ClassInheritingMethodOverriddenAnnotation.class.getDeclaredMethod("method");
|
Method method = ClassInheritingMethodOverriddenAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("eight");
|
assertThat(preAuthorize.value()).isEqualTo("eight");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassOverridingMethodOverriddenAnnotationThenResolves() throws Exception {
|
void synthesizeWhenClassOverridingMethodOverriddenAnnotationThenResolves() throws Exception {
|
||||||
Method method = ClassOverridingMethodOverriddenAnnotation.class.getDeclaredMethod("method");
|
Method method = ClassOverridingMethodOverriddenAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("eight");
|
assertThat(preAuthorize.value()).isEqualTo("eight");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenMethodOverridingMethodOverriddenAnnotationThenResolves() throws Exception {
|
void synthesizeWhenMethodOverridingMethodOverriddenAnnotationThenResolves() throws Exception {
|
||||||
Method method = MethodOverridingMethodOverriddenAnnotation.class.getDeclaredMethod("method");
|
Method method = MethodOverridingMethodOverriddenAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("twenty");
|
assertThat(preAuthorize.value()).isEqualTo("twenty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,41 +152,41 @@ public class UniqueMergedAnnotationSynthesizerTests {
|
||||||
void synthesizeWhenClassInheritingMultipleInheritanceThenException() throws Exception {
|
void synthesizeWhenClassInheritingMultipleInheritanceThenException() throws Exception {
|
||||||
Method method = ClassInheritingMultipleInheritance.class.getDeclaredMethod("method");
|
Method method = ClassInheritingMultipleInheritance.class.getDeclaredMethod("method");
|
||||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||||
.isThrownBy(() -> this.synthesizer.synthesize(method));
|
.isThrownBy(() -> this.synthesizer.synthesize(method, method.getDeclaringClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassOverridingMultipleInheritanceThenResolves() throws Exception {
|
void synthesizeWhenClassOverridingMultipleInheritanceThenResolves() throws Exception {
|
||||||
Method method = ClassOverridingMultipleInheritance.class.getDeclaredMethod("method");
|
Method method = ClassOverridingMultipleInheritance.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("twentytwo");
|
assertThat(preAuthorize.value()).isEqualTo("twentytwo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenMethodOverridingMultipleInheritanceThenResolves() throws Exception {
|
void synthesizeWhenMethodOverridingMultipleInheritanceThenResolves() throws Exception {
|
||||||
Method method = MethodOverridingMultipleInheritance.class.getDeclaredMethod("method");
|
Method method = MethodOverridingMultipleInheritance.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("twentythree");
|
assertThat(preAuthorize.value()).isEqualTo("twentythree");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenInheritingInterfaceAndMethodAnnotationsThenResolves() throws Exception {
|
void synthesizeWhenInheritingInterfaceAndMethodAnnotationsThenResolves() throws Exception {
|
||||||
Method method = InheritingInterfaceAndMethodAnnotations.class.getDeclaredMethod("method");
|
Method method = InheritingInterfaceAndMethodAnnotations.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("three");
|
assertThat(preAuthorize.value()).isEqualTo("three");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassOverridingInterfaceAndMethodInheritanceThenResolves() throws Exception {
|
void synthesizeWhenClassOverridingInterfaceAndMethodInheritanceThenResolves() throws Exception {
|
||||||
Method method = ClassOverridingInterfaceAndMethodInheritance.class.getDeclaredMethod("method");
|
Method method = ClassOverridingInterfaceAndMethodInheritance.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("three");
|
assertThat(preAuthorize.value()).isEqualTo("three");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenMethodOverridingInterfaceAndMethodInheritanceThenResolves() throws Exception {
|
void synthesizeWhenMethodOverridingInterfaceAndMethodInheritanceThenResolves() throws Exception {
|
||||||
Method method = MethodOverridingInterfaceAndMethodInheritance.class.getDeclaredMethod("method");
|
Method method = MethodOverridingInterfaceAndMethodInheritance.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("twentysix");
|
assertThat(preAuthorize.value()).isEqualTo("twentysix");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,21 +194,21 @@ public class UniqueMergedAnnotationSynthesizerTests {
|
||||||
void synthesizeWhenMultipleMethodInheritanceThenException() throws Exception {
|
void synthesizeWhenMultipleMethodInheritanceThenException() throws Exception {
|
||||||
Method method = MultipleMethodInheritance.class.getDeclaredMethod("method");
|
Method method = MultipleMethodInheritance.class.getDeclaredMethod("method");
|
||||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||||
.isThrownBy(() -> this.synthesizer.synthesize(method));
|
.isThrownBy(() -> this.synthesizer.synthesize(method, method.getDeclaringClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// gh-13234
|
// gh-13234
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassInheritingInterfaceAnnotationThenResolves() throws Exception {
|
void synthesizeWhenClassInheritingInterfaceAnnotationThenResolves() throws Exception {
|
||||||
Method method = ClassInheritingInterfaceMethodAnnotation.class.getDeclaredMethod("method");
|
Method method = ClassInheritingInterfaceMethodAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("three");
|
assertThat(preAuthorize.value()).isEqualTo("three");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenMethodInheritingMethodOverridingInterfaceAndMethodInheritanceThenResolves() throws Exception {
|
void synthesizeWhenMethodInheritingMethodOverridingInterfaceAndMethodInheritanceThenResolves() throws Exception {
|
||||||
Method method = MethodInheritingMethodOverridingInterfaceAndMethodInheritance.class.getMethod("method");
|
Method method = MethodInheritingMethodOverridingInterfaceAndMethodInheritance.class.getMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("twentysix");
|
assertThat(preAuthorize.value()).isEqualTo("twentysix");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,13 +224,13 @@ public class UniqueMergedAnnotationSynthesizerTests {
|
||||||
void synthesizeWhenInterfaceInheritingAnnotationsAtDifferentLevelsThenException() throws Exception {
|
void synthesizeWhenInterfaceInheritingAnnotationsAtDifferentLevelsThenException() throws Exception {
|
||||||
Method method = InterfaceInheritingAnnotationsAtDifferentLevels.class.getMethod("method");
|
Method method = InterfaceInheritingAnnotationsAtDifferentLevels.class.getMethod("method");
|
||||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||||
.isThrownBy(() -> this.synthesizer.synthesize(method));
|
.isThrownBy(() -> this.synthesizer.synthesize(method, method.getDeclaringClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassMethodOverridingAnnotationOnMethodThenResolves() throws Exception {
|
void synthesizeWhenClassMethodOverridingAnnotationOnMethodThenResolves() throws Exception {
|
||||||
Method method = ClassMethodOverridingAnnotationOnMethod.class.getDeclaredMethod("method");
|
Method method = ClassMethodOverridingAnnotationOnMethod.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("twentyeight");
|
assertThat(preAuthorize.value()).isEqualTo("twentyeight");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ public class UniqueMergedAnnotationSynthesizerTests {
|
||||||
@Test
|
@Test
|
||||||
void synthesizeWhenClassInheritingInterfaceInheritingInterfaceMethodAnnotationThenResolves() throws Exception {
|
void synthesizeWhenClassInheritingInterfaceInheritingInterfaceMethodAnnotationThenResolves() throws Exception {
|
||||||
Method method = ClassInheritingInterfaceInheritingInterfaceMethodAnnotation.class.getDeclaredMethod("method");
|
Method method = ClassInheritingInterfaceInheritingInterfaceMethodAnnotation.class.getDeclaredMethod("method");
|
||||||
PreAuthorize preAuthorize = this.synthesizer.synthesize(method);
|
PreAuthorize preAuthorize = this.synthesizer.synthesize(method, method.getDeclaringClass());
|
||||||
assertThat(preAuthorize.value()).isEqualTo("three");
|
assertThat(preAuthorize.value()).isEqualTo("three");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue