Browse Source
Rename to a class that isn't focused on the synthesis implementation detail. Also add Security to the front of the name to clarify that it is only intended for security annotations, reminiscent of SecurityMetadataSource. Refine method signatures to better articulate supported use cases. Issue gh-15286pull/15685/head
20 changed files with 298 additions and 233 deletions
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
/* |
||||
* Copyright 2002-2024 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.core.annotation; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
import java.lang.reflect.AnnotatedElement; |
||||
import java.lang.reflect.Method; |
||||
import java.lang.reflect.Parameter; |
||||
|
||||
import org.springframework.core.annotation.MergedAnnotation; |
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* An abstract class to hide the {@link MergedAnnotation} implementation details. |
||||
* |
||||
* <p> |
||||
* Also handy for allowing each scanner to delegate to another without needing to |
||||
* synthesize twice. |
||||
*/ |
||||
abstract class AbstractSecurityAnnotationScanner<A extends Annotation> implements SecurityAnnotationScanner<A> { |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
**/ |
||||
@Nullable |
||||
@Override |
||||
public A scan(Method method, Class<?> targetClass) { |
||||
Assert.notNull(targetClass, "targetClass cannot be null"); |
||||
MergedAnnotation<A> annotation = merge(method, targetClass); |
||||
if (annotation == null) { |
||||
return null; |
||||
} |
||||
return annotation.synthesize(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
**/ |
||||
@Nullable |
||||
@Override |
||||
public A scan(Parameter parameter) { |
||||
MergedAnnotation<A> annotation = merge(parameter, null); |
||||
if (annotation == null) { |
||||
return null; |
||||
} |
||||
return annotation.synthesize(); |
||||
} |
||||
|
||||
abstract MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass); |
||||
|
||||
} |
||||
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2024 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.core.annotation; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
import java.lang.reflect.AnnotatedElement; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Factory for creating {@link AnnotationSynthesizer} instances. |
||||
* |
||||
* @author Josh Cummings |
||||
* @since 6.4 |
||||
*/ |
||||
public final class AnnotationSynthesizers { |
||||
|
||||
private AnnotationSynthesizers() { |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link AnnotationSynthesizer} that requires synthesized annotations to be |
||||
* unique on the given {@link AnnotatedElement}. |
||||
* @param type the annotation type |
||||
* @param <A> the annotation type |
||||
* @return the default {@link AnnotationSynthesizer} |
||||
*/ |
||||
public static <A extends Annotation> AnnotationSynthesizer<A> requireUnique(Class<A> type) { |
||||
return new UniqueMergedAnnotationSynthesizer<>(type); |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link AnnotationSynthesizer} that requires synthesized annotations to be |
||||
* unique on the given {@link AnnotatedElement}. |
||||
* |
||||
* <p> |
||||
* When a {@link AnnotationTemplateExpressionDefaults} is provided, it will return a |
||||
* synthesizer that supports placeholders in the annotation's attributes in addition |
||||
* to the meta-annotation synthesizing provided by {@link #requireUnique(Class)}. |
||||
* @param type the annotation type |
||||
* @param templateDefaults the defaults for resolving placeholders in the annotation's |
||||
* attributes |
||||
* @param <A> the annotation type |
||||
* @return the default {@link AnnotationSynthesizer} |
||||
*/ |
||||
public static <A extends Annotation> AnnotationSynthesizer<A> requireUnique(Class<A> type, |
||||
AnnotationTemplateExpressionDefaults templateDefaults) { |
||||
if (templateDefaults == null) { |
||||
return new UniqueMergedAnnotationSynthesizer<>(type); |
||||
} |
||||
return new ExpressionTemplateAnnotationSynthesizer<>(type, templateDefaults); |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link AnnotationSynthesizer} that requires synthesized annotations to be |
||||
* unique on the given {@link AnnotatedElement}. Supplying multiple types implies that |
||||
* the synthesized annotation must be unique across all specified types. |
||||
* @param types the annotation types |
||||
* @return the default {@link AnnotationSynthesizer} |
||||
*/ |
||||
public static AnnotationSynthesizer<Annotation> requireUnique(List<Class<? extends Annotation>> types) { |
||||
List<Class<Annotation>> casted = new ArrayList<>(); |
||||
types.forEach((type) -> casted.add((Class<Annotation>) type)); |
||||
return new UniqueMergedAnnotationSynthesizer<>(casted); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
/* |
||||
* Copyright 2002-2024 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.core.annotation; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
import java.lang.reflect.AnnotatedElement; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Factory for creating {@link SecurityAnnotationScanner} instances. |
||||
* |
||||
* @author Josh Cummings |
||||
* @since 6.4 |
||||
*/ |
||||
public final class SecurityAnnotationScanners { |
||||
|
||||
private SecurityAnnotationScanners() { |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link SecurityAnnotationScanner} that requires synthesized annotations to |
||||
* be unique on the given {@link AnnotatedElement}. |
||||
* @param type the annotation type |
||||
* @param <A> the annotation type |
||||
* @return the default {@link SecurityAnnotationScanner} |
||||
*/ |
||||
public static <A extends Annotation> SecurityAnnotationScanner<A> requireUnique(Class<A> type) { |
||||
return new UniqueSecurityAnnotationScanner<>(type); |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link SecurityAnnotationScanner} that requires synthesized annotations to |
||||
* be unique on the given {@link AnnotatedElement}. |
||||
* |
||||
* <p> |
||||
* When a {@link AnnotationTemplateExpressionDefaults} is provided, it will return a |
||||
* scanner that supports placeholders in the annotation's attributes in addition to |
||||
* the meta-annotation synthesizing provided by {@link #requireUnique(Class)}. |
||||
* @param type the annotation type |
||||
* @param templateDefaults the defaults for resolving placeholders in the annotation's |
||||
* attributes |
||||
* @param <A> the annotation type |
||||
* @return the default {@link SecurityAnnotationScanner} |
||||
*/ |
||||
public static <A extends Annotation> SecurityAnnotationScanner<A> requireUnique(Class<A> type, |
||||
AnnotationTemplateExpressionDefaults templateDefaults) { |
||||
if (templateDefaults == null) { |
||||
return new UniqueSecurityAnnotationScanner<>(type); |
||||
} |
||||
return new ExpressionTemplateSecurityAnnotationScanner<>(type, templateDefaults); |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link SecurityAnnotationScanner} that requires synthesized annotations to |
||||
* be unique on the given {@link AnnotatedElement}. Supplying multiple types implies |
||||
* that the synthesized annotation must be unique across all specified types. |
||||
* @param types the annotation types |
||||
* @return the default {@link SecurityAnnotationScanner} |
||||
*/ |
||||
public static SecurityAnnotationScanner<Annotation> requireUnique(List<Class<? extends Annotation>> types) { |
||||
List<Class<Annotation>> casted = new ArrayList<>(); |
||||
types.forEach((type) -> casted.add((Class<Annotation>) type)); |
||||
return new UniqueSecurityAnnotationScanner<>(casted); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue