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

jetbrick.bean.ExecutableUtils Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
/**
 * Copyright 2013-2016 Guoqiang Chen, Shanghai, China. All rights reserved.
 *
 *   Author: Guoqiang Chen
 *    Email: [email protected]
 *   WebURL: https://github.com/subchen
 *
 * 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 jetbrick.bean;

import java.util.List;

import jetbrick.util.ClassUtils;

public final class ExecutableUtils {

    /**
     * 查找完全匹配的方法或者构造函数.
     *
     * @param executables - 带查找的 list
     * @param name - 方法名称(如果查找构造函数,那么name可以是null)
     * @param parameterTypes - 方法或者构造函数参数(完全匹配)
     * @return 找到的方法或者构造函数,找不到返回 null.
     */
    public static  T getExecutable(List executables, String name, Class... parameterTypes) {
        for (T info : executables) {
            if (name == null || info.getName().equals(name)) {
                Class[] types = info.getParameterTypes();
                if (parameterTypes.length == types.length) {
                    boolean match = true;
                    for (int i = 0; i < parameterTypes.length; i++) {
                        if (types[i] != parameterTypes[i]) {
                            match = false;
                            break;
                        }
                    }
                    if (match) {
                        return info;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 查找最佳匹配的方法或者构造函数。
     *
     * @param executables - 带查找的 list
     * @param name - 方法名称(如果查找构造函数,那么name可以是null)
     * @param parameterTypes - 方法或者构造函数参数(支持类型转换)
     * @return 找到的方法或者构造函数,找不到返回 null.
     */
    public static  T searchExecutable(List executables, String name, Class... parameterTypes) {
        T best = null;
        Class[] bestParametersTypes = null;

        for (T execute : executables) {
            if (name != null && !execute.getName().equals(name)) continue;

            Class[] types = execute.getParameterTypes();
            if (isParameterTypesCompatible(types, parameterTypes, execute.isVarArgs(), false)) {
                // 可能有多个方法与实际参数类型兼容。采用就近兼容原则。
                if (best == null) {
                    best = execute;
                    bestParametersTypes = types;
                } else if (best.isVarArgs() && (!execute.isVarArgs())) {
                    best = execute; // 不可变参数的函数优先
                    bestParametersTypes = types;
                } else if ((!best.isVarArgs()) && execute.isVarArgs()) {
                    // no change
                } else {
                    if (isParameterTypesCompatible(bestParametersTypes, types, best.isVarArgs(), execute.isVarArgs())) {
                        best = execute;
                        bestParametersTypes = types;
                    }
                }
            }
        }
        return best;
    }

    /**
     * 判断参数列表是否兼容, 支持可变参数.
     *
     * @param lhs - left operand
     * @param rhs - right operand
     * @param lhsVarArgs - lhs 是否是可变参数
     * @param rhsVarArgs - rhs 是否是可变参数
     * @return 是否兼容
     */
    public static boolean isParameterTypesCompatible(Class[] lhs, Class[] rhs, boolean lhsVarArgs, boolean rhsVarArgs) {
        if (lhs == null) {
            return rhs == null || rhs.length == 0;
        }
        if (rhs == null) {
            return lhs.length == 0;
        }

        if (lhsVarArgs && rhsVarArgs) {
            if (lhs.length != rhs.length) {
                return false;
            }
            //校验前面的固定参数
            for (int i = 0; i < lhs.length - 1; i++) {
                if (!ClassUtils.isAssignable(lhs[i], rhs[i])) {
                    return false;
                }
            }
            // 校验最后一个可变参数
            Class c1 = lhs[lhs.length - 1].getComponentType();
            Class c2 = rhs[rhs.length - 1].getComponentType();
            if (!ClassUtils.isAssignable(c1, c2)) {
                return false;
            }
        } else if (lhsVarArgs) {
            if (lhs.length - 1 > rhs.length) {
                return false;
            }
            //校验前面的固定参数
            for (int i = 0; i < lhs.length - 1; i++) {
                if (!ClassUtils.isAssignable(lhs[i], rhs[i])) {
                    return false;
                }
            }
            // 校验最后一个可变参数
            Class varType = lhs[lhs.length - 1].getComponentType();
            for (int i = lhs.length - 1; i < rhs.length; i++) {
                if (!ClassUtils.isAssignable(varType, rhs[i])) {
                    return false;
                }
            }
        } else {
            if (lhs.length != rhs.length) {
                return false;
            }
            for (int i = 0; i < lhs.length; i++) {
                if (!ClassUtils.isAssignable(lhs[i], rhs[i])) {
                    return false;
                }
            }
        }
        return true;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy