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

se.hiq.oss.commons.reflection.util.MethodUtils Maven / Gradle / Ivy

The newest version!
package se.hiq.oss.commons.reflection.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import se.hiq.oss.commons.reflection.filter.builder.MethodFilterBuilder;
import se.hiq.oss.commons.reflection.filter.MethodFilter;
import se.hiq.oss.commons.reflection.filter.impl.MethodFilterList;

/**
 * Utility class for Method based introspection.
 *
 * @author rikardwi
 **/
public final class MethodUtils {

    private MethodUtils() {
    }


    /**
     * Returns the named method from class clazz, does not throw checked exceptions.
     *
     * @param clazz  The class to inspect
     * @param name   The name of the method to get
     * @param params Parameter types for the method
     *
     * @return Returns the named method from class clazz.
     * @throws IllegalArgumentException if method could not be found or security
     *                                  issues occurred, when trying to retrieve the method.
     */
    public static Method getDeclaredMethod(Class clazz, String name, Class... params) {
        try {
            return clazz.getDeclaredMethod(name, params);
        } catch (Exception e) {
            throw new IllegalArgumentException("Could not access method: " + name + " on " + clazz, e);
        }
    }

    /**
     * Returns the named public method from class clazz or any of its super classes, does not throw checked exceptions.
     *
     * @param clazz  The class to inspect
     * @param name   The name of the method to get
     * @param params Parameter types for the method
     *
     * @return Returns the named method from class clazz.
     * @throws IllegalArgumentException if method could not be found or security
     *                                  issues occurred when trying to retrieve the method.
     */
    public static Method getMethod(Class clazz, String name, Class... params) {
        try {
            return clazz.getMethod(name, params);
        } catch (Exception e) {
            throw new IllegalArgumentException("Could not access method: " + name + " on " + clazz, e);
        }
    }


    /**
     * Returns the methods declared by clazz which matches the supplied
     * method filter.
     *
     * @param clazz        The class to inspect
     * @param methodFilter The method filter to apply.
     *
     * @return methods that match which matches the supplied
     * method filter.
     **/
    public static Set getDeclaredMethods(Class clazz, MethodFilter methodFilter) {
        Method[] methods = clazz.getDeclaredMethods();
        Set matches = new HashSet();
        for (Method method : methods) {
            if (methodFilter.apply(method)) {
                matches.add(method);
            }
        }
        return matches;
    }

    /**
     * Returns the methods declared by the target class and any of its super classes, which matches the supplied
     * methodFilter.
     *
     * @param target  The class to inspect.
     * @param methodFilter The method filter to apply.
     *
     * @return methods that match the methodFilter.
     **/
    public static Set getMethods(Class target, MethodFilter methodFilter) {
        Class clazz = target;
        Set matches = getDeclaredMethods(clazz, methodFilter);
        while ((clazz = clazz.getSuperclass()) != null) {
            matches.addAll(getDeclaredMethods(clazz, methodFilter));
        }
        return matches;
    }

    /**
     * Returns the method declared by the target class and any of its super classes, which matches the supplied
     * methodFilter, if method is found null is returned. If more than one method is found the
     * first in the resulting set iterator is returned.
     *
     * @param target The class to inspect.
     * @param methodFilter The method filter to apply.
     *
     * @return method that match the methodFilter or null if no such method was found.
     **/
    public static Method getMethod(Class target, MethodFilter methodFilter) {
        Set methods = getMethods(target, methodFilter);
        if (!methods.isEmpty()) {
            return methods.iterator().next();
        }
        return null;
    }

    /**
     * Returns a map of methods annotated with an annotation from the annotations parameter.
     *
     * @param clazz        The class to inspect.
     * @param methodFilter Filter for methods, may be null to include all annotated methods.
     * @param annotations  Method annotations to find methods for
     *
     * @return Methods that is annotated with the supplied annotation set.
     **/
    public static Map, Set> findAnnotatedMethods(Class clazz,
                                                                                     MethodFilter methodFilter,
                                                                                     Collection> annotations) {

        Map, Set> annotatedMethods = new HashMap, Set>();
        for (Class annotation : annotations) {
            MethodFilter annotationFilter = new MethodFilterBuilder().annotated(annotation).build();
            if (methodFilter != null) {
                annotationFilter = new MethodFilterList(annotationFilter, methodFilter);
            }
            Set methods = getMethods(clazz, annotationFilter);
            annotatedMethods.put(annotation, methods);
        }

        return annotatedMethods;
    }


    /**
     * Returns true if method has no return type.
     *
     * @param method The method to inspect
     * @return true if return type is void
     **/
    public static boolean hasMethodNoReturnType(Method method) {
        return method.getReturnType().equals(Void.TYPE);
    }

    /**
     * Verify that the supplied method's signature matches return type and
     * parameters types.
     *
     * @param method     Method to inspect
     * @param returnType Return type to match
     * @param parameters Parameter types to match
     * @throws IllegalArgumentException if method fails to match return type or parameters types
     */
    public static void verifyMethodSignature(Method method, Class returnType, Class... parameters) {
        if (method == null) {
            throw new IllegalArgumentException("Method is null");
        }
        if (!method.getReturnType().equals(returnType)) {
            throw new IllegalArgumentException("Method " + method + " return type " + method.getReturnType()
                    + " does not match: " + returnType);
        }
        Class[] actualParameters = method.getParameterTypes();
        if (actualParameters.length != parameters.length) {
            throw new IllegalArgumentException("Method " + method + " number of parameters " + actualParameters.length
                    + " does not match: " + parameters.length);
        }
        if (!Arrays.equals(actualParameters, parameters)) {
            throw new IllegalArgumentException("Method " + method + " types of parameters "
                    + Arrays.toString(actualParameters) + " does not match: " + Arrays.toString(parameters));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy