AnnotationReader.java
- package com.gh.mygreen.xlsmapper.xml;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.HashMap;
- import java.util.Map;
- import com.gh.mygreen.xlsmapper.xml.bind.AnnotationInfo;
- import com.gh.mygreen.xlsmapper.xml.bind.ClassInfo;
- import com.gh.mygreen.xlsmapper.xml.bind.FieldInfo;
- import com.gh.mygreen.xlsmapper.xml.bind.MethodInfo;
- import com.gh.mygreen.xlsmapper.xml.bind.AnnotationMappingInfo;
- /**
- * フィールド、メソッドのアノテーションへアクセスするためのクラス。
- * <p>Javaソースに直接アノテーションを付与する場合と、XMLで定義する方法の両方をサポートする。
- *
- * @version 2.0
- * @author Naoki Takezoe
- * @author T.TSUCHIE
- *
- */
- public class AnnotationReader {
-
- /**
- * XMLで定義した情報。
- * nullでもよい。
- */
- private final AnnotationMappingInfo xmlInfo;
-
- /**
- * アノテーションを動的に組み立てるクラス。
- */
- private DynamicAnnotationBuilder annotationBuilder = DynamicAnnotationBuilder.getInstance();
-
- /**
- * XMLで定義した情報を指定するコンストラクタ。
- * @param xmlInfo XMLで定義したアノテーションの情報。{@link XmlIO}で読み込んで取得した値。指定しない場合はnull。
- */
- public AnnotationReader(final AnnotationMappingInfo xmlInfo) {
- this.xmlInfo = xmlInfo;
- }
-
- /**
- * Returns all class annotations.
- *
- * @param clazz the target class
- * @return all annotations present on target class
- * @throws AnnotationReadException
- */
- public Annotation[] getAnnotations(final Class<?> clazz) throws AnnotationReadException {
-
- if(xmlInfo != null && xmlInfo.containsClassInfo(clazz.getName())) {
- final ClassInfo classInfo = xmlInfo.getClassInfo(clazz.getName());
- final Map<String, Annotation> map = new HashMap<>();
-
- if(classInfo.isOverride()) {
- for(Annotation ann : clazz.getAnnotations()) {
- map.put(ann.annotationType().getName(), ann);
- }
- }
-
- for(AnnotationInfo annInfo: classInfo.getAnnotationInfos()) {
- try {
- map.put(annInfo.getClassName(),
- annotationBuilder.buildAnnotation(Class.forName(annInfo.getClassName()), annInfo));
- } catch (ClassNotFoundException e) {
- throw new AnnotationReadException(String.format("not found class '%s'", annInfo.getClassName()), e);
- }
- }
-
- return map.values().toArray(new Annotation[map.size()]);
- }
-
- return clazz.getAnnotations();
- }
-
- /**
- * Returns a class annotation for the specified type if such an annotation is present, else null.
- *
- * @param <A> the type of the annotation
- * @param clazz the target class
- * @param annClass the Class object corresponding to the annotation type
- * @return the target class's annotation for the specified annotation type if present on this element, else null
- * @throws AnnotationReadException
- */
- @SuppressWarnings("unchecked")
- public <A extends Annotation> A getAnnotation(final Class<?> clazz, final Class<A> annClass) throws AnnotationReadException {
- if(xmlInfo != null && xmlInfo.containsClassInfo(clazz.getName())) {
- final ClassInfo classInfo = xmlInfo.getClassInfo(clazz.getName());
-
- if(classInfo.containsAnnotationInfo(annClass.getName())) {
- AnnotationInfo annInfo = classInfo.getAnnotationInfo(annClass.getName());
- try {
- return (A)annotationBuilder.buildAnnotation(Class.forName(annInfo.getClassName()), annInfo);
- } catch (ClassNotFoundException e) {
- throw new AnnotationReadException(String.format("not found class '%s'", annInfo.getClassName()), e);
- }
- }
- }
-
- return clazz.getAnnotation(annClass);
- }
-
- /**
- * メソッドに付与された指定したアノテーションを取得する。
- *
- * @param method 取得対象のメソッド。
- * @param annClas 取得対象のアノテーションのタイプ。
- * @return
- * @throws AnnotationReadException
- */
- @SuppressWarnings("unchecked")
- public <A extends Annotation> A getAnnotation(final Method method, final Class<A> annClas) throws AnnotationReadException {
-
- final Class<?> clazz = method.getDeclaringClass();
-
- if(xmlInfo != null && xmlInfo.containsClassInfo(clazz.getName())) {
- final ClassInfo classInfo = xmlInfo.getClassInfo(clazz.getName());
-
- if(classInfo.containsMethodInfo(method.getName())) {
- MethodInfo methodInfo = classInfo.getMethodInfo(method.getName());
- if(methodInfo != null && methodInfo.containsAnnotationInfo(annClas.getName())) {
- AnnotationInfo annInfo = methodInfo.getAnnotationInfo(annClas.getName());
- try {
- return (A)annotationBuilder.buildAnnotation(Class.forName(annInfo.getClassName()), annInfo);
- } catch (ClassNotFoundException e) {
- throw new AnnotationReadException(String.format("not found class '%s'", annInfo.getClassName()), e);
- }
- }
- }
- }
- return method.getAnnotation(annClas);
- }
-
- /**
- * メソッドに付与されたアノテーションを持つか判定します。
- * @since 2.0
- * @param method 判定対象のメソッド
- * @param annClass アノテーションのタイプ
- * @return trueの場合、アノテーションを持ちます。
- */
- public <A extends Annotation> boolean hasAnnotation(final Method method, final Class<A> annClass) {
- return getAnnotation(method, annClass) != null;
- }
-
- /**
- * メソッドに付与されたアノテーションを全て取得する。
- *
- * @param method 取得対象のメソッド。
- * @return 取得対象のアノテーションのタイプ。
- * @throws AnnotationReadException
- */
- public Annotation[] getAnnotations(final Method method) throws AnnotationReadException {
-
- final Class<?> clazz = method.getDeclaringClass();
-
- if(xmlInfo != null && xmlInfo.containsClassInfo(clazz.getName())) {
- final ClassInfo classInfo = xmlInfo.getClassInfo(clazz.getName());
-
- if(classInfo.containsMethodInfo(method.getName())) {
- final MethodInfo methodInfo = classInfo.getMethodInfo(method.getName());
- final Map<String, Annotation> map = new HashMap<>();
-
- if(methodInfo.isOverride()) {
- for(Annotation ann : method.getAnnotations()) {
- map.put(ann.annotationType().getName(), ann);
- }
- }
-
- for(AnnotationInfo annInfo: methodInfo.getAnnotationInfos()){
- try {
- map.put(annInfo.getClassName(),
- annotationBuilder.buildAnnotation(Class.forName(annInfo.getClassName()), annInfo));
- } catch (ClassNotFoundException e) {
- throw new AnnotationReadException(String.format("not found class '%s'", annInfo.getClassName()), e);
- }
- }
-
- return map.values().toArray(new Annotation[map.size()]);
- }
- }
- return method.getAnnotations();
- }
-
- /**
- * フィールドに付与されたアノテーションを指定して取得する。
- * @param field 取得対象のフィールド
- * @param annClass アノテーションのタイプ
- * @return
- * @throws AnnotationReadException
- */
- @SuppressWarnings("unchecked")
- public <A extends Annotation> A getAnnotation(final Field field, final Class<A> annClass) throws AnnotationReadException {
-
- final Class<?> clazz = field.getDeclaringClass();
-
- if(xmlInfo != null && xmlInfo.containsClassInfo(clazz.getName())) {
- final ClassInfo classInfo = xmlInfo.getClassInfo(clazz.getName());
-
- if(classInfo.containsFieldInfo(field.getName())) {
- FieldInfo fieldInfo = classInfo.getFieldInfo(field.getName());
- if(fieldInfo != null && fieldInfo.containsAnnotationInfo(annClass.getName())){
- AnnotationInfo annInfo = fieldInfo.getAnnotationInfo(annClass.getName());
- try {
- return (A)annotationBuilder.buildAnnotation(Class.forName(annInfo.getClassName()), annInfo);
- } catch (ClassNotFoundException e) {
- throw new AnnotationReadException(String.format("not found class '%s'", annInfo.getClassName()), e);
- }
- }
- }
- }
- return field.getAnnotation(annClass);
- }
-
- /**
- * フィールドに付与されたアノテーションを持つか判定します。
- * @since 2.0
- * @param field 判定対象のフィールド
- * @param annClass アノテーションのタイプ
- * @return trueの場合、アノテーションを持ちます。
- */
- public <A extends Annotation> boolean hasAnnotation(final Field field, final Class<A> annClass) {
- return getAnnotation(field, annClass) != null;
- }
-
- /**
- * フィールドに付与されたアノテーションを全て取得する。
- * @param field 取得対象のフィールド
- * @return
- * @throws AnnotationReadException
- */
- public Annotation[] getAnnotations(final Field field) throws AnnotationReadException {
-
- final Class<?> clazz = field.getDeclaringClass();
-
- if(xmlInfo != null && xmlInfo.containsClassInfo(clazz.getName())) {
- final ClassInfo classInfo = xmlInfo.getClassInfo(clazz.getName());
-
- if(classInfo.containsFieldInfo(field.getName())) {
- final FieldInfo fieldInfo = classInfo.getFieldInfo(field.getName());
- final Map<String, Annotation> map = new HashMap<>();
-
- if(fieldInfo.isOverride()) {
- for(Annotation ann : field.getAnnotations()) {
- map.put(ann.annotationType().getName(), ann);
- }
- }
-
- for(AnnotationInfo annInfo: fieldInfo.getAnnotationInfos()){
- try {
- map.put(annInfo.getClassName(),
- annotationBuilder.buildAnnotation(Class.forName(annInfo.getClassName()), annInfo));
- } catch (ClassNotFoundException e) {
- throw new AnnotationReadException(String.format("not found class '%s'", annInfo.getClassName()), e);
- }
- }
- return map.values().toArray(new Annotation[map.size()]);
- }
- }
- return field.getAnnotations();
- }
-
- public DynamicAnnotationBuilder getAnnotationBuilder() {
- return annotationBuilder;
- }
-
- public void setAnnotationBuilder(DynamicAnnotationBuilder annotationBuilder) {
- this.annotationBuilder = annotationBuilder;
- }
-
- }