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;
}