@SuppressWarnings("unchecked")
public RPCResponse invoke(Object object, Map data) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException, JSONException,
InstantiationException, NoSuchMethodException, IntrospectionException {
RPCResponse response = new RPCResponse();
//validate id
Object id = data.get("id");
if (id == null) {
String message = "'id' is required for JSON RPC";
response.setError(new RPCError(message, RPCErrorCode.METHOD_NOT_FOUND));
return response;
}
//could be a numeric value
response.setId(id.toString());
// the map is going to have: 'params', 'method' and 'id' (what is the id for?)
Class clazz = object.getClass();
//parameters
List parameters = (List) data.get("params");
int parameterCount = parameters != null ? parameters.size() : 0;
//method
String methodName = (String) data.get("method");
if (methodName == null) {
String message = "'method' is required for JSON RPC";
response.setError(new RPCError(message, RPCErrorCode.MISSING_METHOD));
return response;
}
Method method = this.getMethod(clazz, methodName, parameterCount);
if (method == null) {
String message = "Method " + methodName +
" could not be found in action class.";
response.setError(new RPCError(message, RPCErrorCode.METHOD_NOT_FOUND));
return response;
}
//parameters
if (parameterCount > 0) {
Class[] parameterTypes = method.getParameterTypes();
Type[] genericTypes = method.getGenericParameterTypes();
List invocationParameters = new ArrayList();
//validate size
if (parameterTypes.length != parameterCount) {
//size mismatch
String message = "Parameter count in request, " + parameterCount +
" do not match expected parameter count for " + methodName + ", " +
parameterTypes.length;
response.setError(new RPCError(message, RPCErrorCode.PARAMETERS_MISMATCH));
return response;
}
//convert parameters
for (int i = 0; i < parameters.size(); i++) {
Object parameter = parameters.get(i);
Class paramType = parameterTypes[i];
Type genericType = genericTypes[i];
//clean up the values
if (dataCleaner != null)
parameter = dataCleaner.clean("[" + i + "]", parameter);
Object converted = populator.convert(paramType, genericType, parameter, method);
invocationParameters.add(converted);
}
response.setResult(method.invoke(object, invocationParameters.toArray()));
} else {
response.setResult(method.invoke(object, new Object[0]));
}
return response;
}