* there is not a match.
*/
public AccessibleObject resolveMethod(final Map methodMap,
final String methodName, final JSONArray arguments,
final JSONSerializerController serializer) {
final Logger logger = getLogger();
// first, match soley by the method name and number of arguments passed in
// if there is a single match, return the single match
// if there is no match at all, return null
// if there are multiple matches, fall through to the second matching phase
// below
final AccessibleObjectKey methodKey = new AccessibleObjectKey(
methodName,
arguments.length());
// of AccessibleObject
final List accessibleObjects = (List) methodMap.get(methodKey);
if (CollectionUtils.isEmpty(accessibleObjects)) {
return null;
} else if (accessibleObjects.size() == 1) {
return (AccessibleObject) CollectionUtils.getFirst(accessibleObjects);
} else {
// second matching phase: there were overloaded methods on the object
// we are invoking so try and find the best match based on the types of
// the arguments passed in.
// try and unmarshall the arguments against each candidate method
// to determine which one matches the best
final List<AccessibleObjectCandidate> candidates = new ArrayList<AccessibleObjectCandidate>();
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "looking for method {0}({1})",
new Object[]{methodName, argSignature(arguments)});
}
for (int i = 0; i < accessibleObjects.size(); i++) {
AccessibleObject accessibleObject = (AccessibleObject) accessibleObjects.get(i);
Class[] parameterTypes = null;
if (accessibleObject instanceof Method) {
parameterTypes = ((Method) accessibleObject).getParameterTypes();
} else if (accessibleObject instanceof Constructor) {
parameterTypes = ((Constructor) accessibleObject).getParameterTypes();
}
try {
final AccessibleObjectCandidate candidate = tryUnmarshallArgs(
accessibleObject, arguments,
parameterTypes, serializer);
if (null != candidate) {
candidates.add(candidate);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE,
"+++ possible match with method {0}({1})",
new Object[]{methodName, argSignature(accessibleObject)});
}
}
} catch (Exception e) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE,
"xxx {0} in {1}({2})",
new Object[]{e.getMessage(), methodName, argSignature(accessibleObject)});
}
}
}
// now search through all the candidates and find one which matches
// the json arguments the closest
AccessibleObjectCandidate best = null;
for (int i = 0; i < candidates.size(); i++) {
AccessibleObjectCandidate c = (AccessibleObjectCandidate) candidates.get(i);
if (best == null) {
best = c;
continue;
}
final ObjectMatch bestMatch = best.getMatch();
final ObjectMatch cMatch = c.getMatch();
if (bestMatch.getMismatch() > cMatch.getMismatch()) {
best = c;
} else if (bestMatch.getMismatch() == cMatch.getMismatch()) {
best = betterSignature(best, c);
}
}
if (best != null) {
AccessibleObject ao = best.getAccessibleObject();
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "found method {0}({1})",
new Object[]{methodName, argSignature(ao)});
}
return ao;
}
}