All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.gsonfire.util.reflection.AnnotationInspector Maven / Gradle / Ivy

package io.gsonfire.util.reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Class responsible for returning a set of members that are annotated with a particular {@link Annotation} class.
 * The returned members can be mapped to a different type.
 *
 * The result after mapping will be cached for performance reasons
 * @autor: julio
 */
public abstract class AnnotationInspector {

    private final ConcurrentMap, Collection>> cache = new ConcurrentHashMap, Collection>>();

    public Collection getAnnotatedMembers(Class clazz, Class annotation){
        if(clazz != null) {
            Collection members = getFromCache(clazz, annotation);
            if (members != null) {
                return members;
            }

            //Cache miss, we need to use reflections to get the fields
            members = getFromCache(clazz, annotation);
            if (members == null) {

                Set memberList = new LinkedHashSet();
                //Add methods declared in the class
                for (T m : getDeclaredMembers(clazz)) {
                    if (m.isAnnotationPresent(annotation)) {
                        m.setAccessible(true);
                        memberList.add(map(m));
                    }
                }

                //Add methods from super class
                memberList.addAll(getAnnotatedMembers(clazz.getSuperclass(), annotation));

                //Add methods from interfaces
                for (Class interfaceClass : clazz.getInterfaces()) {
                    memberList.addAll(getAnnotatedMembers(interfaceClass, annotation));
                }

                ConcurrentMap, Collection> newAnnotationMap = new ConcurrentHashMap, Collection>();
                ConcurrentMap, Collection> storedAnnotationMap = cache.putIfAbsent(clazz, newAnnotationMap);
                storedAnnotationMap = storedAnnotationMap == null ? newAnnotationMap : storedAnnotationMap;
                storedAnnotationMap.put(annotation, memberList);
                return memberList;
            }
        }


        return Collections.emptyList();
    }

    protected abstract T[] getDeclaredMembers(Class clazz);
    protected abstract M map(T member);

    private Collection getFromCache(Class clazz, Class annotation) {
        Map, Collection> annotationMap = cache.get(clazz);
        if(annotationMap != null){
            Collection methods = annotationMap.get(annotation);
            if(methods != null){
                return methods;
            }
        }
        return null;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy