Merge an array with annotations (list B) into a list with annotations (list A). - Java java.lang.annotation

Java examples for java.lang.annotation:Annotation Attribute

Description

Merge an array with annotations (list B) into a list with annotations (list A).

Demo Code

/**/*from   ww  w  .  ja  v  a  2s.com*/
 * @file AnnotationUtil.java
 * 
 *       AnnotationUtil is a utility to get all annotations of a class, its
 *       methods,
 *       and the method parameters. Returned annotations include all annotations
 *       of
 *       the classes interfaces and super classes.
 *       Requested classes are cached, so requesting a classes annotations
 *       repeatedly
 *       is fast.
 * 
 *       Example usage:
 * 
 *       AnnotatedClass annotatedClass = AnnotationUtil.get(MyClass.class);
 *       List<AnnotatedMethod> methods = annotatedClass.getMethods();
 *       for (AnnotatedMethod method : methods) {
 *       System.out.println("Method: " + method.getName());
 *       List<Annotation> annotations = method.getAnnotations();
 *       for (Annotation annotation : annotations) {
 *       System.out.println("    Annotation: " + annotation.toString());
 *       }
 *       }
 * 
 * @brief
 *        AnnotationUtil is a utility to retrieve merged annotations from a
 *        class
 *        including all its superclasses and interfaces.
 * 
 * @license
 *          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
 * 
 *          http://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.
 * 
 *          Copyright (c) 2013 Almende B.V.
 * 
 * @author Jos de Jong, <jos@almende.org>
 * @date 2013-01-21
 */
import java.lang.annotation.Annotation;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.WrongMethodTypeException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main{
    private static final Logger LOG = Logger.getLogger(AnnotationUtil.class
            .getName());
    /**
     * Merge an array with annotations (listB) into a list with
     * annotations (listA).
     * 
     * @param listA
     *            the list a
     * @param listB
     *            the list b
     */
    private static void merge(final List<Annotation> listA,
            final Annotation[] listB) {
        for (final Annotation b : listB) {
            boolean found = false;
            for (final Annotation a : listA) {
                if (a.getClass() == b.getClass()) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                listA.add(b);
            }
        }
    }
    /**
     * Merge an array of methods (listB) into a list with method
     * annotations (listA).
     * 
     * @param listA
     *            the list a
     * @param listB
     *            the list b
     * @throws IllegalAccessException
     */
    private static void merge(final List<AnnotatedMethod> listA,
            final Method[] listB) {
        for (final Method b : listB) {
            AnnotatedMethod methodAnnotations = null;
            for (final AnnotatedMethod a : listA) {
                if (areEqual(a.method, b)) {
                    methodAnnotations = a;
                    break;
                }
            }

            if (methodAnnotations != null) {
                methodAnnotations.merge(b);
            } else {
                try {
                    listA.add(new AnnotatedMethod(b));
                } catch (IllegalAccessException e) {
                    LOG.log(Level.SEVERE,
                            "Failed to obtain AnnotatedMethod:"
                                    + b.getName(), e);
                }
            }
        }
    }
    /**
     * Merge an array with annotations (listB) into a list with
     * annotations (listA).
     * 
     * @param listA
     *            the list a
     * @param listB
     *            the list b
     */
    private static void merge(final List<AnnotatedField> listA,
            final Field[] listB) {
        for (final Field b : listB) {
            AnnotatedField fieldAnnotations = null;
            for (final AnnotatedField a : listA) {
                if (areEqual(a.field, b)) {
                    fieldAnnotations = a;
                    break;
                }
            }

            if (fieldAnnotations != null) {
                fieldAnnotations.merge(b);
            } else {
                listA.add(new AnnotatedField(b));
            }
        }
    }
    /**
     * Test if two methods have equal names, return type, param count,
     * and param types.
     * 
     * @param a
     *            the a
     * @param b
     *            the b
     * @return true, if successful
     */
    private static boolean areEqual(final Method a, final Method b) {
        // http://stackoverflow.com/q/10062957/1262753
        if (!a.getName().equals(b.getName())) {
            return false;
        }
        if (a.getReturnType() != b.getReturnType()) {
            return false;
        }

        final Class<?>[] paramsa = a.getParameterTypes();
        final Class<?>[] paramsb = b.getParameterTypes();
        if (paramsa.length != paramsb.length) {
            return false;
        }
        for (int i = 0; i < paramsa.length; i++) {
            if (paramsa[i] != paramsb[i]) {
                return false;
            }
        }

        return true;
    }
    /**
     * Test if two fields have equal names and types.
     * 
     * @param a
     *            the a
     * @param b
     *            the b
     * @return true, if successful
     */
    private static boolean areEqual(final Field a, final Field b) {
        // http://stackoverflow.com/q/10062957/1262753
        if (!a.getName().equals(b.getName())) {
            return false;
        }
        if (a.getType() != b.getType()) {
            return false;
        }
        return true;
    }
}

Related Tutorials