org.jiemamy.utils.reflect.MethodUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.jiemamy.utils.reflect.MethodUtil.java

Source

/*
 * Copyright 2007-2012 Jiemamy Project and the Others.
 *
 * This file is part of Jiemamy.
 *
 * 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.
 */
package org.jiemamy.utils.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.lang.Validate;

/**
 * {@link Method}?
 * 
 * @version $Id$
 * @author j5ik2o
 */
public final class MethodUtil {

    /** ? */
    private static final int BUFF_SIZE = 100;

    private static final Method IS_BRIDGE_METHOD = getIsBridgeMethod();

    private static final Method IS_SYNTHETIC_METHOD = getIsSyntheticMethod();

    /** {@link #getElementTypeOfCollectionFromParameterType(Method, int)}??? */
    private static final Method GET_ELEMENT_TYPE_OF_COLLECTION_FROM_PARAMETER_METHOD = getElementTypeFromParameterMethod(
            "Collection");

    /** {@link #getElementTypeOfCollectionFromReturnType(Method)}??? */
    private static final Method GET_ELEMENT_TYPE_OF_COLLECTION_FROM_RETURN_METHOD = getElementTypeFromReturnMethod(
            "Collection");

    /** {@link #getElementTypeOfListFromParameterType(Method, int)}??? */
    private static final Method GET_ELEMENT_TYPE_OF_LIST_FROM_PARAMETER_METHOD = getElementTypeFromParameterMethod(
            "List");

    /** {@link #getElementTypeOfListFromReturnType(Method)}??? */
    private static final Method GET_ELEMENT_TYPE_OF_LIST_FROM_RETURN_METHOD = getElementTypeFromReturnMethod(
            "List");

    /** {@link #getElementTypeOfSetFromParameterType(Method, int)}??? */
    private static final Method GET_ELEMENT_TYPE_OF_SET_FROM_PARAMETER_METHOD = getElementTypeFromParameterMethod(
            "Set");

    /** {@link #getElementTypeOfSetFromReturnType(Method)}??? */
    private static final Method GET_ELEMENT_TYPE_OF_SET_FROM_RETURN_METHOD = getElementTypeFromReturnMethod("Set");

    /**
     * ? (??)????
     * 
     * @param method 
     * @param position ????????
     * @return ?????????????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ???????
     * @throws IllegalArgumentException ???????
     */
    public static Class<?> getElementTypeOfCollectionFromParameterType(Method method, int position)
            throws IllegalAccessException, InvocationTargetException {
        return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_COLLECTION_FROM_PARAMETER_METHOD, null,
                new Object[] { method, Integer.valueOf(position) });
    }

    /**
     * ???????????????
     * 
     * @param method 
     * @return ?????????????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ???????
     * @throws IllegalArgumentException ???????
     */
    public static Class<?> getElementTypeOfCollectionFromReturnType(Method method)
            throws IllegalAccessException, InvocationTargetException {
        return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_COLLECTION_FROM_RETURN_METHOD, null, new Object[] { method });
    }

    /**
     * ? (??) ????
     * 
     * @param method 
     * @param position ????????
     * @return ?????????????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ???????
     * @throws IllegalArgumentException ???????
     */
    public static Class<?> getElementTypeOfListFromParameterType(Method method, int position)
            throws IllegalAccessException, InvocationTargetException {
        return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_LIST_FROM_PARAMETER_METHOD, null,
                new Object[] { method, Integer.valueOf(position) });
    }

    /**
     * ???????????????
     * 
     * @param method 
     * @return ?????????????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ???????
     * @throws IllegalArgumentException ???????
     */
    public static Class<?> getElementTypeOfListFromReturnType(Method method)
            throws IllegalAccessException, InvocationTargetException {
        return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_LIST_FROM_RETURN_METHOD, null, new Object[] { method });
    }

    /**
     * ? (??) ????
     * 
     * @param method 
     * @param position ????????
     * @return ?????????????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ???????
     * @throws IllegalArgumentException ???????
     */
    public static Class<?> getElementTypeOfSetFromParameterType(Method method, int position)
            throws IllegalAccessException, InvocationTargetException {
        return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_SET_FROM_PARAMETER_METHOD, null,
                new Object[] { method, Integer.valueOf(position) });
    }

    /**
     * ???????????????
     * 
     * @param method 
     * @return ?????????????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ???????
     * @throws IllegalArgumentException ???????
     */
    public static Class<?> getElementTypeOfSetFromReturnType(Method method)
            throws IllegalAccessException, InvocationTargetException {
        if (GET_ELEMENT_TYPE_OF_SET_FROM_RETURN_METHOD == null) {
            return null;
        }
        return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_SET_FROM_RETURN_METHOD, null, new Object[] { method });
    }

    /**
     * ???
     * 
     * <p> {@code getSignature(java.lang.String, java.lang.Class[])}</p>
     * 
     * @param methodName ??
     * @param argTypes 
     * @return ?
     */
    public static String getSignature(String methodName, Class<?>[] argTypes) {
        StringBuilder sb = new StringBuilder(BUFF_SIZE);
        sb.append(methodName);
        sb.append("(");
        if (argTypes != null) {
            for (int i = 0; i < argTypes.length; ++i) {
                if (i > 0) {
                    sb.append(", ");
                }
                sb.append(argTypes[i].getName());
            }
        }
        sb.append(")");
        return sb.toString();
    }

    /**
     * ???
     * 
     * @param methodName ??
     * @param methodArgs ?
     * @return ?
     */
    public static String getSignature(String methodName, Object[] methodArgs) {
        StringBuilder sb = new StringBuilder(BUFF_SIZE);
        sb.append(methodName);
        sb.append("(");
        if (methodArgs != null) {
            for (int i = 0; i < methodArgs.length; ++i) {
                if (i > 0) {
                    sb.append(", ");
                }
                if (methodArgs[i] != null) {
                    sb.append(methodArgs[i].getClass().getName());
                } else {
                    sb.append("null");
                }
            }
        }
        sb.append(")");
        return sb.toString();
    }

    /**
     * {@link Method#invoke(Object, Object[])}???
     * 
     * @param method 
     * @param target 
     * @param args 
     * @return 
     * @throws IllegalAccessException ???????
     * @throws IllegalArgumentException ???????
     * @throws InvocationTargetException ???
     * @see Method#invoke(Object, Object[])
     * @throws IllegalArgumentException {@code method}?{@code null}???
     */
    public static Object invoke(Method method, Object target, Object[] args)
            throws IllegalAccessException, InvocationTargetException {
        Validate.notNull(method);
        try {
            return method.invoke(target, args);
        } catch (InvocationTargetException ex) {
            Throwable t = ex.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            }
            if (t instanceof Error) {
                throw (Error) t;
            }
            throw ex;
        }
    }

    /**
     * ??????
     * 
     * @param method {@link Method}
     * @return ????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ??
     * @throws IllegalArgumentException ???????
     */
    public static boolean isBridgeMethod(Method method) throws IllegalAccessException, InvocationTargetException {
        if (IS_BRIDGE_METHOD == null) {
            return false;
        }
        return ((Boolean) invoke(IS_BRIDGE_METHOD, method, null)).booleanValue();
    }

    /**
     * {@link #equals(Object)}??????
     * 
     * @param method {@link Method}
     * @return equals????
     */
    public static boolean isEqualsMethod(Method method) {
        return method != null && method.getName().equals("equals") && method.getReturnType() == boolean.class
                && method.getParameterTypes().length == 1 && method.getParameterTypes()[0] == Object.class;
    }

    /**
     * {@link #hashCode()}??????
     * 
     * @param method {@link Method}
     * @return hashCode????
     */
    public static boolean isHashCodeMethod(Method method) {
        return method != null && method.getName().equals("hashCode") && method.getReturnType() == int.class
                && method.getParameterTypes().length == 0;
    }

    /**
     * ????????
     * 
     * @param method {@link Method}
     * @return ??????
     * @throws InvocationTargetException ???
     * @throws IllegalAccessException ??
     * @throws IllegalArgumentException ???????
     */
    public static boolean isSyntheticMethod(Method method)
            throws IllegalAccessException, InvocationTargetException {
        if (IS_SYNTHETIC_METHOD == null) {
            return false;
        }
        return ((Boolean) invoke(IS_SYNTHETIC_METHOD, method, null)).booleanValue();
    }

    /**
     * {@link #toString()}??????
     * 
     * @param method {@link Method}
     * @return toString????
     */
    public static boolean isToStringMethod(Method method) {
        return method != null && method.getName().equals("toString") && method.getReturnType() == String.class
                && method.getParameterTypes().length == 0;
    }

    /**
     * {@code ReflectionUtil#getElementTypeOf<var>Xxx</var>FromParameter}?{@link Method}??
     * 
     * @param type ???????
     * @return {@link Method}
     */
    protected static Method getElementTypeFromParameterMethod(String type) {
        try {
            Class<?> reflectionUtilClass = ReflectionUtil.class;
            return reflectionUtilClass.getMethod("getElementTypeOf" + type + "FromParameterType",
                    new Class[] { Method.class, int.class });
        } catch (Throwable ignore) {
            // ignore
        }
        return null;
    }

    /**
     * {@code ReflectionUtil#getElementTypeOf<var>Xxx</var>FromReturn}?{@link Method}??
     * 
     * @param type ???????
     * @return {@link Method}
     */
    protected static Method getElementTypeFromReturnMethod(String type) {
        try {
            Class<?> reflectionUtilClass = ReflectionUtil.class;
            return reflectionUtilClass.getMethod("getElementTypeOf" + type + "FromReturnType",
                    new Class[] { Method.class });
        } catch (Throwable ignore) {
            // ignore
        }
        return null;
    }

    private static Method getIsBridgeMethod() {
        try {
            return Method.class.getMethod("isBridge", new Class<?>[] { null });
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

    private static Method getIsSyntheticMethod() {
        try {
            return Method.class.getMethod("isSynthetic", new Class<?>[] { null });
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

    private MethodUtil() {
    }

}