Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 package org.apache.xmlrpc.server;
00020
00021 import java.lang.reflect.InvocationTargetException;
00022 import java.lang.reflect.Method;
00023
00024 import org.apache.xmlrpc.XmlRpcException;
00025 import org.apache.xmlrpc.XmlRpcHandler;
00026 import org.apache.xmlrpc.XmlRpcRequest;
00027 import org.apache.xmlrpc.common.TypeConverter;
00028 import org.apache.xmlrpc.common.TypeConverterFactory;
00029 import org.apache.xmlrpc.common.XmlRpcInvocationException;
00030 import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException;
00031 import org.apache.xmlrpc.metadata.Util;
00032 import org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping.AuthenticationHandler;
00033 import org.apache.xmlrpc.server.RequestProcessorFactoryFactory.RequestProcessorFactory;
00034
00035
00038 public class ReflectiveXmlRpcHandler implements XmlRpcHandler {
00039 private static class MethodData {
00040 final Method method;
00041 final TypeConverter[] typeConverters;
00042 MethodData(Method pMethod, TypeConverterFactory pTypeConverterFactory) {
00043 method = pMethod;
00044 Class[] paramClasses = method.getParameterTypes();
00045 typeConverters = new TypeConverter[paramClasses.length];
00046 for (int i = 0; i < paramClasses.length; i++) {
00047 typeConverters[i] = pTypeConverterFactory.getTypeConverter(paramClasses[i]);
00048 }
00049 }
00050 }
00051 private final AbstractReflectiveHandlerMapping mapping;
00052 private final MethodData[] methods;
00053 private final Class clazz;
00054 private final RequestProcessorFactory requestProcessorFactory;
00055
00065 public ReflectiveXmlRpcHandler(AbstractReflectiveHandlerMapping pMapping,
00066 TypeConverterFactory pTypeConverterFactory,
00067 Class pClass, RequestProcessorFactory pFactory, Method[] pMethods) {
00068 mapping = pMapping;
00069 clazz = pClass;
00070 methods = new MethodData[pMethods.length];
00071 requestProcessorFactory = pFactory;
00072 for (int i = 0; i < methods.length; i++) {
00073 methods[i] = new MethodData(pMethods[i], pTypeConverterFactory);
00074 }
00075 }
00076
00077 private Object getInstance(XmlRpcRequest pRequest) throws XmlRpcException {
00078 return requestProcessorFactory.getRequestProcessor(pRequest);
00079 }
00080
00081 public Object execute(XmlRpcRequest pRequest) throws XmlRpcException {
00082 AuthenticationHandler authHandler = mapping.getAuthenticationHandler();
00083 if (authHandler != null && !authHandler.isAuthorized(pRequest)) {
00084 throw new XmlRpcNotAuthorizedException("Not authorized");
00085 }
00086 Object[] args = new Object[pRequest.getParameterCount()];
00087 for (int j = 0; j < args.length; j++) {
00088 args[j] = pRequest.getParameter(j);
00089 }
00090 Object instance = getInstance(pRequest);
00091 for (int i = 0; i < methods.length; i++) {
00092 MethodData methodData = methods[i];
00093 TypeConverter[] converters = methodData.typeConverters;
00094 if (args.length == converters.length) {
00095 boolean matching = true;
00096 for (int j = 0; j < args.length; j++) {
00097 if (!converters[j].isConvertable(args[j])) {
00098 matching = false;
00099 break;
00100 }
00101 }
00102 if (matching) {
00103 for (int j = 0; j < args.length; j++) {
00104 args[j] = converters[j].convert(args[j]);
00105 }
00106 return invoke(instance, methodData.method, args);
00107 }
00108 }
00109 }
00110 throw new XmlRpcException("No method " + pRequest.getMethodName() + " matching arguments: " + Util.getSignature(args));
00111 }
00112
00113 private Object invoke(Object pInstance, Method pMethod, Object[] pArgs) throws XmlRpcException {
00114 try {
00115 return pMethod.invoke(pInstance, pArgs);
00116 } catch (IllegalAccessException e) {
00117 throw new XmlRpcException("Illegal access to method "
00118 + pMethod.getName() + " in class "
00119 + clazz.getName(), e);
00120 } catch (IllegalArgumentException e) {
00121 throw new XmlRpcException("Illegal argument for method "
00122 + pMethod.getName() + " in class "
00123 + clazz.getName(), e);
00124 } catch (InvocationTargetException e) {
00125 Throwable t = e.getTargetException();
00126 if (t instanceof XmlRpcException) {
00127 throw (XmlRpcException) t;
00128 }
00129 throw new XmlRpcInvocationException("Failed to invoke method "
00130 + pMethod.getName() + " in class "
00131 + clazz.getName() + ": "
00132 + t.getMessage(), t);
00133 }
00134 }
00135 }