package org.etk.reflect.core; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Map; import org.etk.reflect.api.ClassTypeInfo; import org.etk.reflect.api.annotation.AnnotationInfo; import org.etk.reflect.api.definition.ClassKind; import org.etk.reflect.api.metadata.AnnotationMetadata; /** * Anntation delegate which uses for responsibilities to resolve the annotation of <code>ClassInfo</code>, * <code>Method</code>, <code>Field</code>, and <code>Variable</code>. * * @author thanh_vucong * * @param <T> TypeInfo which delegates to resolve. * @param <M> MethodInfo which delegates to resolve. * @param <A> AnnotationInfo which delegates to resolve * @param <P> * @param <F> FieldInfo which delegates to resolve * @param <E> Element which provides to resolve. */ public class AnnotatedDelegate<T, M, A, P, F, E> extends ReflectedObject<T, M, A, P, F>{ final AnnotationMetadata<T, E, A, P> annotationModel; private final E element; private Map<ClassTypeInfo, AnnotationInfo> annotations; public AnnotatedDelegate(TypeResolverImpl<T, M, A, P, F> domain, AnnotationMetadata<T, E, A, P> annotationModel, E element) { super(domain); this.annotationModel = annotationModel; this.element = element; } /** * Retrieve these annotations which were declared in the method, field, or class. * @param <AN> Generic type of Annotation * @param element * @param annotationType * @return */ public <AN> AN getDeclaredAnnotation(E element, AnnotationType<AN, ?> annotationType) { Object type = annotationType.getType(); if (type instanceof Class<?>) { return (AN) annotationModel.resolveDeclaredAnnotation(element, (Class<Annotation>)type); } else if (type instanceof ClassTypeInfo) { ClassTypeInfo cti = (ClassTypeInfo) type; if (cti.getKind() != ClassKind.ANNOTATION) { throw new IllegalArgumentException("The provided class type info is not an annotation."); } if (annotations == null) { Map<ClassTypeInfo, AnnotationInfo> annotations = new HashMap<ClassTypeInfo, AnnotationInfo>(); for(A a : annotationModel.getDeclaredAnnotation(element)) { T ant = annotationModel.getAnnotationType(a); ClassTypeInfo aaaa = (ClassTypeInfo) domain.resolve(ant); annotations.put(aaaa, new AnnotationInfoImpl<T, M, A, P, F, E>(this, aaaa, a)); } this.annotations = annotations; } return (AN) annotations.get(cti); } else { throw new AssertionError(); } } }