public Method getMethod()

in core/src/main/java/flex/messaging/util/MethodMatcher.java [58:169]


    public Method getMethod(Class c, String methodName, List parameters) {
        // Keep track of the best method match found
        Match bestMatch = new Match(methodName);

        // Determine supplied parameter types.
        Class[] suppliedParamTypes = paramTypes(parameters);

        // Create a key to search our method cache
        MethodKey methodKey = new MethodKey(c, methodName, suppliedParamTypes);

        Method method = null;
        if (methodCache.containsKey(methodKey)) {
            method = methodCache.get(methodKey);

            String thisMethodName = method.getName();
            bestMatch.matchedMethodName = thisMethodName;
        } else {
            try // First, try an exact match.
            {
                method = c.getMethod(methodName, suppliedParamTypes);
                synchronized (methodCache) {
                    Method method2 = methodCache.get(methodKey);
                    if (method2 == null)
                        methodCache.put(methodKey, method);
                    else
                        method = method2;
                }
            } catch (SecurityException e) {
                // NOWARN
            } catch (NoSuchMethodException e) {
                // NOWARN
            }

            if (method == null) // Otherwise, search the long way.
            {
                Method[] methods = c.getMethods();
                for (Method thisMethod : c.getMethods()) {
                    String thisMethodName = thisMethod.getName();

                    // FIXME: Do we want to do this case-insensitively in Flex 2.0?
                    // First, search by name; for backwards compatibility
                    // we continue to check case-insensitively
                    if (!thisMethodName.equalsIgnoreCase(methodName))
                        continue;

                    // Next, search on params
                    Match currentMatch = new Match(methodName);
                    currentMatch.matchedMethodName = thisMethodName;

                    // If we've not yet had a match, this is our best match so far.
                    if (bestMatch.matchedMethodName == null)
                        bestMatch = currentMatch;

                    // Number of parameters must match.
                    Class[] desiredParamTypes = thisMethod.getParameterTypes();
                    currentMatch.methodParamTypes = desiredParamTypes;

                    if (desiredParamTypes.length != suppliedParamTypes.length)
                        continue;

                    currentMatch.matchedByNumberOfParams = true;

                    // If we've not yet matched any params, this is our best match so far.
                    if (!bestMatch.matchedByNumberOfParams && bestMatch.matchedParamCount == 0)
                        bestMatch = currentMatch;

                    // Parameter types must also be compatible. Don't actually convert
                    // the parameter just yet, only count the matches and exact matches.
                    convertParams(parameters, desiredParamTypes, currentMatch, false);

                    // If we've not yet had this many params match, this is our best match so far.
                    if (currentMatch.matchedParamCount >= bestMatch.matchedParamCount
                            && currentMatch.exactMatchedParamCount >= bestMatch.exactMatchedParamCount)
                        bestMatch = currentMatch;

                    // If all types were compatible, we have a match.
                    if (currentMatch.matchedParamCount == desiredParamTypes.length
                            && bestMatch == currentMatch) {
                        method = thisMethod;
                        synchronized (methodCache) {
                            Method method2 = methodCache.get(methodKey);
                            if (method2 == null || method2 != method)
                                methodCache.put(methodKey, method);
                            else
                                method = method2;
                        }
                        // Don't break as there might be other methods with the
                        // same number of arguments but with better match count.
                        // break;
                    }
                }
            }
        }

        if (method == null) {
            methodNotFound(methodName, suppliedParamTypes, bestMatch);
        } else if (bestMatch.paramTypeConversionFailure != null) {
            //Error occurred while attempting to convert an input argument's type.
            MessageException me = new MessageException();
            me.setMessage(ARGUMENT_CONVERSION_ERROR);
            me.setCode("Server.Processing");
            me.setRootCause(bestMatch.paramTypeConversionFailure);
            throw me;
        }

        // Call convertParams one last time before returning method. This ensures
        // that parameters List is converted using bestMatch.
        Class<?>[] desiredParamTypes = method.getParameterTypes();
        bestMatch.methodParamTypes = desiredParamTypes;
        convertParams(parameters, desiredParamTypes, bestMatch, true);
        return method;
    }