public static Method getMatchingAccessibleMethod()

in src/main/java/org/apache/commons/beanutils2/MethodUtils.java [440:535]


    public static Method getMatchingAccessibleMethod(
                                                final Class<?> clazz,
                                                final String methodName,
                                                final Class<?>[] parameterTypes) {
        // trace logging
        if (LOG.isTraceEnabled()) {
            LOG.trace("Matching name=" + methodName + " on " + clazz);
        }
        final MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes, false);

        // see if we can find the method directly
        // most of the time this works and it's much faster
        try {
            // Check the cache first
            Method method = getCachedMethod(md);
            if (method != null) {
                return method;
            }

            method = clazz.getMethod(methodName, parameterTypes);
            if (LOG.isTraceEnabled()) {
                LOG.trace("Found straight match: " + method);
                LOG.trace("isPublic:" + Modifier.isPublic(method.getModifiers()));
            }

            setMethodAccessible(method); // Default access superclass workaround

            cacheMethod(md, method);
            return method;

        } catch (final NoSuchMethodException e) { /* SWALLOW */ }

        // search through all methods
        final int paramSize = parameterTypes.length;
        Method bestMatch = null;
        final Method[] methods = clazz.getMethods();
        float bestMatchCost = Float.MAX_VALUE;
        float myCost = Float.MAX_VALUE;
        for (final Method method2 : methods) {
            if (method2.getName().equals(methodName)) {
                // log some trace information
                if (LOG.isTraceEnabled()) {
                    LOG.trace("Found matching name:");
                    LOG.trace(method2);
                }

                // compare parameters
                final Class<?>[] methodsParams = method2.getParameterTypes();
                final int methodParamSize = methodsParams.length;
                if (methodParamSize == paramSize) {
                    boolean match = true;
                    for (int n = 0 ; n < methodParamSize; n++) {
                        if (LOG.isTraceEnabled()) {
                            LOG.trace("Param=" + parameterTypes[n].getName());
                            LOG.trace("Method=" + methodsParams[n].getName());
                        }
                        if (!isAssignmentCompatible(methodsParams[n], parameterTypes[n])) {
                            if (LOG.isTraceEnabled()) {
                                LOG.trace(methodsParams[n] + " is not assignable from "
                                            + parameterTypes[n]);
                            }
                            match = false;
                            break;
                        }
                    }

                    if (match) {
                        // get accessible version of method
                        final Method method = getAccessibleMethod(clazz, method2);
                        if (method != null) {
                            if (LOG.isTraceEnabled()) {
                                LOG.trace(method + " accessible version of "
                                            + method2);
                            }
                            setMethodAccessible(method); // Default access superclass workaround
                            myCost = getTotalTransformationCost(parameterTypes, method.getParameterTypes());
                            if ( myCost < bestMatchCost ) {
                               bestMatch = method;
                               bestMatchCost = myCost;
                            }
                        }

                        LOG.trace("Couldn't find accessible method.");
                    }
                }
            }
        }
        if (bestMatch != null) {
            cacheMethod(md, bestMatch);
        } else {
            // didn't find a match
            LOG.trace("No match found.");
        }

        return bestMatch;
    }