mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
合成聚合注解支持处理多个根注解,并且可选择是否扫描根注解的元注解
This commit is contained in:
parent
d873b6e9da
commit
c27c74f192
@ -1,5 +1,6 @@
|
||||
package cn.hutool.core.annotation;
|
||||
|
||||
import cn.hutool.core.annotation.scanner.AnnotationScanner;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
@ -43,21 +44,32 @@ public abstract class AbstractAnnotationSynthesizer<T> implements AnnotationSynt
|
||||
*/
|
||||
protected final Collection<SynthesizedAnnotationPostProcessor> postProcessors;
|
||||
|
||||
/**
|
||||
* 注解扫描器
|
||||
*/
|
||||
protected final AnnotationScanner annotationScanner;
|
||||
|
||||
/**
|
||||
* 构造一个注解合成器
|
||||
*
|
||||
* @param source 当前查找的注解对象
|
||||
* @param annotationSelector 合成注解选择器
|
||||
* @param annotationPostProcessors 注解后置处理器
|
||||
* @param annotationScanner 注解扫描器,该扫描器需要支持扫描注解类
|
||||
*/
|
||||
protected AbstractAnnotationSynthesizer(
|
||||
T source, SynthesizedAnnotationSelector annotationSelector, Collection<SynthesizedAnnotationPostProcessor> annotationPostProcessors) {
|
||||
T source,
|
||||
SynthesizedAnnotationSelector annotationSelector,
|
||||
Collection<SynthesizedAnnotationPostProcessor> annotationPostProcessors,
|
||||
AnnotationScanner annotationScanner) {
|
||||
Assert.notNull(source, "source must not null");
|
||||
Assert.notNull(annotationSelector, "annotationSelector must not null");
|
||||
Assert.notNull(annotationPostProcessors, "annotationPostProcessors must not null");
|
||||
Assert.notNull(annotationPostProcessors, "annotationScanner must not null");
|
||||
|
||||
this.source = source;
|
||||
this.annotationSelector = annotationSelector;
|
||||
this.annotationScanner = annotationScanner;
|
||||
this.postProcessors = CollUtil.unmodifiable(
|
||||
CollUtil.sort(annotationPostProcessors, Comparator.comparing(SynthesizedAnnotationPostProcessor::order))
|
||||
);
|
||||
|
@ -355,7 +355,7 @@ public class AnnotationUtil {
|
||||
*/
|
||||
public static <T extends Annotation> T getSynthesizedAnnotation(Annotation annotation, Class<T> annotationType) {
|
||||
// TODO 缓存合成注解信息,避免重复解析
|
||||
return SynthesizedAggregateAnnotation.from(annotation).synthesize(annotationType);
|
||||
return aggregatingFromAnnotationWithMeta(annotation).synthesize(annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -470,4 +470,24 @@ public class AnnotationUtil {
|
||||
return method.getParameterCount() == 0 && method.getReturnType() != void.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对指定注解对象进行聚合
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @return 聚合注解
|
||||
*/
|
||||
static SynthesizedAggregateAnnotation aggregatingFromAnnotation(Annotation annotation) {
|
||||
return new GenericSynthesizedAggregateAnnotation(Collections.singletonList(annotation), EmptyAnnotationScanner.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对指定注解对象及其元注解进行聚合
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @return 聚合注解
|
||||
*/
|
||||
static SynthesizedAggregateAnnotation aggregatingFromAnnotationWithMeta(Annotation annotation) {
|
||||
return new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.hutool.core.annotation;
|
||||
|
||||
import cn.hutool.core.annotation.scanner.AnnotationScanner;
|
||||
import cn.hutool.core.annotation.scanner.MetaAnnotationScanner;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Opt;
|
||||
@ -7,16 +8,14 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* {@link SynthesizedAggregateAnnotation}的基本实现,表示一个根注解与根注解上的多层元注解的聚合得到的注解
|
||||
* {@link SynthesizedAggregateAnnotation}的基本实现,表示基于多个注解对象,
|
||||
* 或多个根注解对象与他们的多层元注解对象的聚合得到的注解。
|
||||
*
|
||||
* <p>假设现有注解A,A上存在元注解B,B上存在元注解C,则对注解A进行解析,
|
||||
* 将得到包含根注解A,以及其元注解B、C在内的合成元注解聚合{@link SynthesizedMetaAggregateAnnotation}。
|
||||
* <p>假设现有注解A,若指定的{@link #annotationScanner}支持扫描注解A的元注解,
|
||||
* 且A上存在元注解B,B上存在元注解C,则对注解A进行解析,将得到包含根注解A,以及其元注解B、C在内的合成元注解聚合{@link GenericSynthesizedAggregateAnnotation}。
|
||||
* 从{@link AnnotatedElement}的角度来说,得到的合成注解是一个同时承载有ABC三个注解对象的被注解元素,
|
||||
* 因此通过调用{@link AnnotatedElement}的相关方法将返回对应符合语义的注解对象。
|
||||
*
|
||||
@ -37,7 +36,7 @@ import java.util.Map;
|
||||
* </ul>
|
||||
* 若用户需要自行扩展,则需要保证上述三个处理器被正确注入当前实例。
|
||||
*
|
||||
* <p>{@link SynthesizedMetaAggregateAnnotation}支持通过{@link #getAttributeValue(String, Class)},
|
||||
* <p>{@link GenericSynthesizedAggregateAnnotation}支持通过{@link #getAttributeValue(String, Class)},
|
||||
* 或通过{@link #synthesize(Class)}获得注解代理对象后获取指定类型的注解属性值,
|
||||
* 返回的属性值将根据合成注解中对应原始注解属性上的{@link Alias}与{@link Link}注解而有所变化。
|
||||
* 通过当前实例获取属性值时,将经过{@link SynthesizedAnnotationAttributeProcessor}的处理。<br>
|
||||
@ -46,9 +45,16 @@ import java.util.Map;
|
||||
*
|
||||
* @author huangchengxing
|
||||
* @see AnnotationUtil
|
||||
* @see SynthesizedAnnotationProxy
|
||||
* @see SynthesizedAnnotationSelector
|
||||
* @see SynthesizedAnnotationAttributeProcessor
|
||||
* @see SynthesizedAnnotationPostProcessor
|
||||
* @see AnnotationSynthesizer
|
||||
* @see AnnotationScanner
|
||||
*/
|
||||
public class SynthesizedMetaAggregateAnnotation extends AbstractAnnotationSynthesizer<Annotation> implements SynthesizedAggregateAnnotation {
|
||||
public class GenericSynthesizedAggregateAnnotation
|
||||
extends AbstractAnnotationSynthesizer<List<Annotation>>
|
||||
implements SynthesizedAggregateAnnotation {
|
||||
|
||||
/**
|
||||
* 根对象
|
||||
@ -71,13 +77,25 @@ public class SynthesizedMetaAggregateAnnotation extends AbstractAnnotationSynthe
|
||||
private final SynthesizedAnnotationAttributeProcessor attributeProcessor;
|
||||
|
||||
/**
|
||||
* 基于指定根注解,为其层级结构中的全部注解构造一个合成注解。
|
||||
* 基于指定根注解,为其与其元注解的层级结构中的全部注解构造一个合成注解。
|
||||
* 当层级结构中出现了相同的注解对象时,将优先选择以距离根注解最近,且优先被扫描的注解对象,
|
||||
* 当获取值时,同样遵循该规则。
|
||||
*
|
||||
* @param source 源注解
|
||||
*/
|
||||
public SynthesizedMetaAggregateAnnotation(Annotation source) {
|
||||
public GenericSynthesizedAggregateAnnotation(Annotation... source) {
|
||||
this(Arrays.asList(source), new MetaAnnotationScanner());
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于指定根注解,为其层级结构中的全部注解构造一个合成注解。
|
||||
* 若扫描器支持对注解的层级结构进行扫描,则若层级结构中出现了相同的注解对象时,
|
||||
* 将优先选择以距离根注解最近,且优先被扫描的注解对象,并且当获取注解属性值时同样遵循该规则。
|
||||
*
|
||||
* @param source 源注解
|
||||
* @param annotationScanner 注解扫描器,该扫描器必须支持扫描注解类
|
||||
*/
|
||||
public GenericSynthesizedAggregateAnnotation(List<Annotation> source, AnnotationScanner annotationScanner) {
|
||||
this(
|
||||
source, SynthesizedAnnotationSelector.NEAREST_AND_OLDEST_PRIORITY,
|
||||
new CacheableSynthesizedAnnotationAttributeProcessor(),
|
||||
@ -85,26 +103,29 @@ public class SynthesizedMetaAggregateAnnotation extends AbstractAnnotationSynthe
|
||||
SynthesizedAnnotationPostProcessor.ALIAS_ANNOTATION_POST_PROCESSOR,
|
||||
SynthesizedAnnotationPostProcessor.MIRROR_LINK_ANNOTATION_POST_PROCESSOR,
|
||||
SynthesizedAnnotationPostProcessor.ALIAS_LINK_ANNOTATION_POST_PROCESSOR
|
||||
)
|
||||
),
|
||||
annotationScanner
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于指定根注解,为其层级结构中的全部注解构造一个合成注解
|
||||
*
|
||||
* @param annotation 当前查找的注解对象
|
||||
* @param source 当前查找的注解对象
|
||||
* @param annotationSelector 合成注解选择器
|
||||
* @param attributeProcessor 注解属性处理器
|
||||
* @param annotationPostProcessors 注解后置处理器
|
||||
* @param annotationScanner 注解扫描器,该扫描器必须支持扫描注解类
|
||||
*/
|
||||
public SynthesizedMetaAggregateAnnotation(
|
||||
Annotation annotation,
|
||||
public GenericSynthesizedAggregateAnnotation(
|
||||
List<Annotation> source,
|
||||
SynthesizedAnnotationSelector annotationSelector,
|
||||
SynthesizedAnnotationAttributeProcessor attributeProcessor,
|
||||
Collection<SynthesizedAnnotationPostProcessor> annotationPostProcessors) {
|
||||
Collection<SynthesizedAnnotationPostProcessor> annotationPostProcessors,
|
||||
AnnotationScanner annotationScanner) {
|
||||
this(
|
||||
null, 0, 0,
|
||||
annotation, annotationSelector, attributeProcessor, annotationPostProcessors
|
||||
source, annotationSelector, attributeProcessor, annotationPostProcessors, annotationScanner
|
||||
);
|
||||
}
|
||||
|
||||
@ -114,18 +135,20 @@ public class SynthesizedMetaAggregateAnnotation extends AbstractAnnotationSynthe
|
||||
* @param root 根对象
|
||||
* @param verticalDistance 距离根对象的水平距离
|
||||
* @param horizontalDistance 距离根对象的垂直距离
|
||||
* @param source 当前查找的注解对象
|
||||
* @param source 当前查找的注解对象
|
||||
* @param annotationSelector 合成注解选择器
|
||||
* @param attributeProcessor 注解属性处理器
|
||||
* @param annotationPostProcessors 注解后置处理器
|
||||
* @param annotationScanner 注解扫描器,该扫描器必须支持扫描注解类
|
||||
*/
|
||||
SynthesizedMetaAggregateAnnotation(
|
||||
GenericSynthesizedAggregateAnnotation(
|
||||
Object root, int verticalDistance, int horizontalDistance,
|
||||
Annotation source,
|
||||
List<Annotation> source,
|
||||
SynthesizedAnnotationSelector annotationSelector,
|
||||
SynthesizedAnnotationAttributeProcessor attributeProcessor,
|
||||
Collection<SynthesizedAnnotationPostProcessor> annotationPostProcessors) {
|
||||
super(source, annotationSelector, annotationPostProcessors);
|
||||
Collection<SynthesizedAnnotationPostProcessor> annotationPostProcessors,
|
||||
AnnotationScanner annotationScanner) {
|
||||
super(source, annotationSelector, annotationPostProcessors, annotationScanner);
|
||||
Assert.notNull(attributeProcessor, "attributeProcessor must not null");
|
||||
|
||||
this.root = ObjectUtil.defaultIfNull(root, this);
|
||||
@ -169,21 +192,31 @@ public class SynthesizedMetaAggregateAnnotation extends AbstractAnnotationSynthe
|
||||
*/
|
||||
@Override
|
||||
protected Map<Class<? extends Annotation>, SynthesizedAnnotation> loadAnnotations() {
|
||||
Assert.isFalse(SynthesizedAnnotationProxy.isProxyAnnotation(source.getClass()), "source [{}] has been synthesized");
|
||||
Map<Class<? extends Annotation>, SynthesizedAnnotation> annotationMap = new LinkedHashMap<>();
|
||||
annotationMap.put(source.annotationType(), new MetaAnnotation(source, source, 0, 0));
|
||||
new MetaAnnotationScanner().scan(
|
||||
(index, annotation) -> {
|
||||
SynthesizedAnnotation oldAnnotation = annotationMap.get(annotation.annotationType());
|
||||
SynthesizedAnnotation newAnnotation = new MetaAnnotation(source, annotation, index, annotationMap.size());
|
||||
if (ObjectUtil.isNull(oldAnnotation)) {
|
||||
annotationMap.put(annotation.annotationType(), newAnnotation);
|
||||
} else {
|
||||
annotationMap.put(annotation.annotationType(), annotationSelector.choose(oldAnnotation, newAnnotation));
|
||||
}
|
||||
},
|
||||
source.annotationType(), null
|
||||
);
|
||||
|
||||
// 根注解默认水平坐标为0,根注解的元注解坐标从1开始
|
||||
for (int i = 0; i < source.size(); i++) {
|
||||
final Annotation sourceAnnotation = source.get(i);
|
||||
Assert.isFalse(AnnotationUtil.isSynthesizedAnnotation(sourceAnnotation), "source [{}] has been synthesized");
|
||||
annotationMap.put(sourceAnnotation.annotationType(), new MetaAnnotation(sourceAnnotation, sourceAnnotation, 0, i));
|
||||
Assert.isTrue(
|
||||
annotationScanner.support(sourceAnnotation.annotationType()),
|
||||
"annotation scanner [{}] cannot support scan [{}]",
|
||||
annotationScanner, sourceAnnotation.annotationType()
|
||||
);
|
||||
annotationScanner.scan(
|
||||
(index, annotation) -> {
|
||||
SynthesizedAnnotation oldAnnotation = annotationMap.get(annotation.annotationType());
|
||||
SynthesizedAnnotation newAnnotation = new MetaAnnotation(sourceAnnotation, annotation, index + 1, annotationMap.size());
|
||||
if (ObjectUtil.isNull(oldAnnotation)) {
|
||||
annotationMap.put(annotation.annotationType(), newAnnotation);
|
||||
} else {
|
||||
annotationMap.put(annotation.annotationType(), annotationSelector.choose(oldAnnotation, newAnnotation));
|
||||
}
|
||||
},
|
||||
sourceAnnotation.annotationType(), null
|
||||
);
|
||||
}
|
||||
return annotationMap;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import java.lang.annotation.Annotation;
|
||||
* @see SynthesizedAnnotationSelector
|
||||
* @see SynthesizedAnnotationAttributeProcessor
|
||||
* @see SynthesizedAnnotationPostProcessor
|
||||
* @see SynthesizedMetaAggregateAnnotation
|
||||
* @see GenericSynthesizedAggregateAnnotation
|
||||
*/
|
||||
public interface SynthesizedAggregateAnnotation extends AggregateAnnotation, Hierarchical, AnnotationSynthesizer, AnnotationAttributeValueProvider {
|
||||
|
||||
@ -99,15 +99,4 @@ public interface SynthesizedAggregateAnnotation extends AggregateAnnotation, Hie
|
||||
@Override
|
||||
Object getAttributeValue(String attributeName, Class<?> attributeType);
|
||||
|
||||
/**
|
||||
* 基于指定根注解,构建包括其元注解在内的合成注解
|
||||
*
|
||||
* @param rootAnnotation 根注解
|
||||
* @param <T> 注解类型
|
||||
* @return 合成注解
|
||||
*/
|
||||
static <T extends Annotation> SynthesizedAggregateAnnotation from(T rootAnnotation) {
|
||||
return new SynthesizedMetaAggregateAnnotation(rootAnnotation);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,18 +33,17 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
|
||||
|
||||
/**
|
||||
* 创建一个代理注解,生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类。
|
||||
* <ul>
|
||||
* <li>当作为{@code annotationType}所指定的类型使用时,其属性将通过合成它的{@link SynthesizedAggregateAnnotation}获取;</li>
|
||||
* <li>当作为{@link SyntheticProxyAnnotation}或{@link SynthesizedAnnotation}使用时,将可以获得原始注解实例的相关信息;</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param annotationType 注解类型
|
||||
* @param annotationAttributeValueProvider 注解属性值获取器
|
||||
* @param annotation 合成注解
|
||||
* @return 代理注解
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Annotation> T create(
|
||||
Class<T> annotationType, AnnotationAttributeValueProvider annotationAttributeValueProvider, SynthesizedAnnotation annotation) {
|
||||
Class<T> annotationType,
|
||||
AnnotationAttributeValueProvider annotationAttributeValueProvider,
|
||||
SynthesizedAnnotation annotation) {
|
||||
if (ObjectUtil.isNull(annotation)) {
|
||||
return null;
|
||||
}
|
||||
@ -59,6 +58,18 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个代理注解,生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类。
|
||||
*
|
||||
* @param annotationType 注解类型
|
||||
* @param annotation 合成注解
|
||||
* @return 代理注解
|
||||
*/
|
||||
public static <T extends Annotation> T create(
|
||||
Class<T> annotationType, SynthesizedAnnotation annotation) {
|
||||
return create(annotationType, annotation, annotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 该类是否为通过{@link SynthesizedAnnotationProxy}生成的代理类
|
||||
*
|
||||
|
@ -0,0 +1,33 @@
|
||||
package cn.hutool.core.annotation.scanner;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 默认不扫描任何元素的扫描器
|
||||
*
|
||||
* @author huangchengxing
|
||||
*/
|
||||
public class EmptyAnnotationScanner implements AnnotationScanner {
|
||||
|
||||
public static final EmptyAnnotationScanner INSTANCE = new EmptyAnnotationScanner();
|
||||
|
||||
@Override
|
||||
public boolean support(AnnotatedElement annotatedEle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Annotation> getAnnotations(AnnotatedElement annotatedEle) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scan(BiConsumer<Integer, Annotation> consumer, AnnotatedElement annotatedEle, Predicate<Annotation> filter) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
@ -10,13 +10,14 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 合成注解{@link SynthesizedMetaAggregateAnnotation}的测试用例
|
||||
* 合成注解{@link GenericSynthesizedAggregateAnnotation}的测试用例
|
||||
*
|
||||
* @author huangchengxing
|
||||
*/
|
||||
public class SyntheticMetaAnnotationTest {
|
||||
public class GenericSynthesizedAggregateAnnotationTest {
|
||||
|
||||
@Test
|
||||
public void baseSynthesisAnnotationWorkTest() {
|
||||
@ -25,10 +26,10 @@ public class SyntheticMetaAnnotationTest {
|
||||
final GrandParentAnnotation grandParentAnnotation = ChildAnnotation.class.getAnnotation(GrandParentAnnotation.class);
|
||||
final ParentAnnotation parentAnnotation = ChildAnnotation.class.getAnnotation(ParentAnnotation.class);
|
||||
final ChildAnnotation childAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class);
|
||||
final SynthesizedMetaAggregateAnnotation syntheticMetaAnnotation = new SynthesizedMetaAggregateAnnotation(childAnnotation);
|
||||
final GenericSynthesizedAggregateAnnotation syntheticMetaAnnotation = new GenericSynthesizedAggregateAnnotation(childAnnotation);
|
||||
|
||||
// Annotation & AnnotatedElement
|
||||
Assert.assertEquals(SynthesizedMetaAggregateAnnotation.class, syntheticMetaAnnotation.annotationType());
|
||||
Assert.assertEquals(GenericSynthesizedAggregateAnnotation.class, syntheticMetaAnnotation.annotationType());
|
||||
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(GrandParentAnnotation.class));
|
||||
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ParentAnnotation.class));
|
||||
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ChildAnnotation.class));
|
||||
@ -55,9 +56,9 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void synthesisAnnotationAttributeTest() {
|
||||
final ChildAnnotation rootAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class);
|
||||
SynthesizedMetaAggregateAnnotation syntheticMetaAnnotation = new SynthesizedMetaAggregateAnnotation(rootAnnotation);
|
||||
Assert.assertEquals(syntheticMetaAnnotation.getSource(), rootAnnotation);
|
||||
Assert.assertEquals(syntheticMetaAnnotation.annotationType(), SynthesizedMetaAggregateAnnotation.class);
|
||||
GenericSynthesizedAggregateAnnotation syntheticMetaAnnotation = new GenericSynthesizedAggregateAnnotation(rootAnnotation);
|
||||
Assert.assertEquals(syntheticMetaAnnotation.getSource(), Collections.singletonList(rootAnnotation));
|
||||
Assert.assertEquals(syntheticMetaAnnotation.annotationType(), GenericSynthesizedAggregateAnnotation.class);
|
||||
Assert.assertEquals(3, syntheticMetaAnnotation.getAnnotations().length);
|
||||
|
||||
Assert.assertEquals("Child!", syntheticMetaAnnotation.getAttributeValue("childValue", String.class));
|
||||
@ -69,7 +70,7 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void syntheticAnnotationTest() {
|
||||
final ChildAnnotation rootAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class);
|
||||
SynthesizedMetaAggregateAnnotation syntheticMetaAnnotation = new SynthesizedMetaAggregateAnnotation(rootAnnotation);
|
||||
GenericSynthesizedAggregateAnnotation syntheticMetaAnnotation = new GenericSynthesizedAggregateAnnotation(rootAnnotation);
|
||||
|
||||
final ChildAnnotation childAnnotation = syntheticMetaAnnotation.synthesize(ChildAnnotation.class);
|
||||
SynthesizedAnnotation childSyntheticAnnotation = syntheticMetaAnnotation.getSynthesizedAnnotation(ChildAnnotation.class);
|
||||
@ -82,7 +83,7 @@ public class SyntheticMetaAnnotationTest {
|
||||
Assert.assertEquals("Child!", childAnnotation.childValue());
|
||||
Assert.assertEquals("Child!", childAnnotation.childValueAlias());
|
||||
Assert.assertEquals(childAnnotation.grandParentType(), Integer.class);
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> new SynthesizedMetaAggregateAnnotation(childAnnotation));
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> new GenericSynthesizedAggregateAnnotation(childAnnotation));
|
||||
|
||||
final ParentAnnotation parentAnnotation = syntheticMetaAnnotation.synthesize(ParentAnnotation.class);
|
||||
SynthesizedAnnotation parentSyntheticAnnotation = syntheticMetaAnnotation.getSynthesizedAnnotation(ParentAnnotation.class);
|
||||
@ -93,7 +94,7 @@ public class SyntheticMetaAnnotationTest {
|
||||
Assert.assertNotNull(parentAnnotation);
|
||||
Assert.assertEquals("Child's Parent!", parentAnnotation.parentValue());
|
||||
Assert.assertEquals("java.lang.Void", parentAnnotation.grandParentType());
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> new SynthesizedMetaAggregateAnnotation(parentAnnotation));
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> new GenericSynthesizedAggregateAnnotation(parentAnnotation));
|
||||
|
||||
final GrandParentAnnotation grandParentAnnotation = syntheticMetaAnnotation.synthesize(GrandParentAnnotation.class);
|
||||
SynthesizedAnnotation grandParentSyntheticAnnotation = syntheticMetaAnnotation.getSynthesizedAnnotation(GrandParentAnnotation.class);
|
||||
@ -105,13 +106,13 @@ public class SyntheticMetaAnnotationTest {
|
||||
Assert.assertNotNull(grandParentAnnotation);
|
||||
Assert.assertEquals("Child's GrandParent!", grandParentAnnotation.grandParentValue());
|
||||
Assert.assertEquals(grandParentAnnotation.grandParentType(), Integer.class);
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> new SynthesizedMetaAggregateAnnotation(grandParentAnnotation));
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> new GenericSynthesizedAggregateAnnotation(grandParentAnnotation));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void linkTest() {
|
||||
final Method method = ReflectUtil.getMethod(AnnotationForLinkTest.class, "value");
|
||||
final SynthesizedAggregateAnnotation synthesizedAnnotationAggregator = new SynthesizedMetaAggregateAnnotation(method.getAnnotation(AliasFor.class));
|
||||
final SynthesizedAggregateAnnotation synthesizedAnnotationAggregator = new GenericSynthesizedAggregateAnnotation(method.getAnnotation(AliasFor.class));
|
||||
final Link link = synthesizedAnnotationAggregator.synthesize(Link.class);
|
||||
Assert.assertEquals(AnnotationForLinkTest.class, link.annotation());
|
||||
Assert.assertEquals("name", link.attribute());
|
||||
@ -120,19 +121,19 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void mirrorAttributeTest() {
|
||||
AnnotationForMirrorTest annotation = ClassForMirrorTest.class.getAnnotation(AnnotationForMirrorTest.class);
|
||||
SynthesizedAggregateAnnotation synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
SynthesizedAggregateAnnotation synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
AnnotationForMirrorTest syntheticAnnotation = synthetic.synthesize(AnnotationForMirrorTest.class);
|
||||
Assert.assertEquals("Foo", syntheticAnnotation.name());
|
||||
Assert.assertEquals("Foo", syntheticAnnotation.value());
|
||||
|
||||
annotation = ClassForMirrorTest2.class.getAnnotation(AnnotationForMirrorTest.class);
|
||||
synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
syntheticAnnotation = synthetic.synthesize(AnnotationForMirrorTest.class);
|
||||
Assert.assertEquals("Foo", syntheticAnnotation.name());
|
||||
Assert.assertEquals("Foo", syntheticAnnotation.value());
|
||||
|
||||
annotation = ClassForMirrorTest3.class.getAnnotation(AnnotationForMirrorTest.class);
|
||||
synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
syntheticAnnotation = synthetic.synthesize(AnnotationForMirrorTest.class);
|
||||
AnnotationForMirrorTest finalSyntheticAnnotation = syntheticAnnotation;
|
||||
Assert.assertThrows(IllegalArgumentException.class, finalSyntheticAnnotation::name);
|
||||
@ -141,14 +142,14 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void aliasForTest() {
|
||||
AnnotationForAliasForTest annotation = ClassForAliasForTest.class.getAnnotation(AnnotationForAliasForTest.class);
|
||||
SynthesizedAggregateAnnotation synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
SynthesizedAggregateAnnotation synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
MetaAnnotationForAliasForTest metaAnnotation = synthetic.synthesize(MetaAnnotationForAliasForTest.class);
|
||||
Assert.assertEquals("Meta", metaAnnotation.name());
|
||||
AnnotationForAliasForTest childAnnotation = synthetic.synthesize(AnnotationForAliasForTest.class);
|
||||
Assert.assertEquals("", childAnnotation.value());
|
||||
|
||||
annotation = ClassForAliasForTest2.class.getAnnotation(AnnotationForAliasForTest.class);
|
||||
synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
metaAnnotation = synthetic.synthesize(MetaAnnotationForAliasForTest.class);
|
||||
Assert.assertEquals("Foo", metaAnnotation.name());
|
||||
childAnnotation = synthetic.synthesize(AnnotationForAliasForTest.class);
|
||||
@ -158,14 +159,14 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void forceAliasForTest() {
|
||||
AnnotationForceForAliasForTest annotation = ClassForForceAliasForTest.class.getAnnotation(AnnotationForceForAliasForTest.class);
|
||||
SynthesizedAggregateAnnotation synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
SynthesizedAggregateAnnotation synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
MetaAnnotationForForceAliasForTest metaAnnotation = synthetic.synthesize(MetaAnnotationForForceAliasForTest.class);
|
||||
Assert.assertEquals("", metaAnnotation.name());
|
||||
AnnotationForceForAliasForTest childAnnotation = synthetic.synthesize(AnnotationForceForAliasForTest.class);
|
||||
Assert.assertEquals("", childAnnotation.value());
|
||||
|
||||
annotation = ClassForForceAliasForTest2.class.getAnnotation(AnnotationForceForAliasForTest.class);
|
||||
synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
metaAnnotation = synthetic.synthesize(MetaAnnotationForForceAliasForTest.class);
|
||||
Assert.assertEquals("Foo", metaAnnotation.name());
|
||||
childAnnotation = synthetic.synthesize(AnnotationForceForAliasForTest.class);
|
||||
@ -175,7 +176,7 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void aliasForAndMirrorTest() {
|
||||
AnnotationForMirrorThenAliasForTest annotation = ClassForAliasForAndMirrorTest.class.getAnnotation(AnnotationForMirrorThenAliasForTest.class);
|
||||
SynthesizedAggregateAnnotation synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
SynthesizedAggregateAnnotation synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
MetaAnnotationForMirrorThenAliasForTest metaAnnotation = synthetic.synthesize(MetaAnnotationForMirrorThenAliasForTest.class);
|
||||
Assert.assertEquals("test", metaAnnotation.name());
|
||||
Assert.assertEquals("test", metaAnnotation.value());
|
||||
@ -186,7 +187,7 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void multiAliasForTest() {
|
||||
final AnnotationForMultiAliasForTest annotation = ClassForMultiAliasForTest.class.getAnnotation(AnnotationForMultiAliasForTest.class);
|
||||
final SynthesizedAggregateAnnotation synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
final SynthesizedAggregateAnnotation synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
|
||||
final MetaAnnotationForMultiAliasForTest1 metaAnnotation1 = synthetic.synthesize(MetaAnnotationForMultiAliasForTest1.class);
|
||||
Assert.assertEquals("test", metaAnnotation1.name());
|
||||
@ -200,7 +201,7 @@ public class SyntheticMetaAnnotationTest {
|
||||
@Test
|
||||
public void implicitAliasTest() {
|
||||
final AnnotationForImplicitAliasTest annotation = ClassForImplicitAliasTest.class.getAnnotation(AnnotationForImplicitAliasTest.class);
|
||||
final SynthesizedAggregateAnnotation synthetic = new SynthesizedMetaAggregateAnnotation(annotation);
|
||||
final SynthesizedAggregateAnnotation synthetic = new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
|
||||
final MetaAnnotationForImplicitAliasTest metaAnnotation = synthetic.synthesize(MetaAnnotationForImplicitAliasTest.class);
|
||||
Assert.assertEquals("Meta", metaAnnotation.name());
|
Loading…
x
Reference in New Issue
Block a user