Author: jochen Date: Mon May 22 13:31:57 2006 New Revision: 408757 URL: http://svn.apache.org/viewvc?rev=408757&view=rev Log: Added support for method overloading.
Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java?rev=408757&r1=408756&r2=408757&view=diff ============================================================================== --- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java (original) +++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java Mon May 22 13:31:57 2006 @@ -37,7 +37,7 @@ * messages only. * @param pInstance The instance, which will be invoked for * executing the handler. - * @param pMethod The method, which will be invoked for + * @param pMethods The method, which will be invoked for * executing the handler. * @param pSignatures The signature, which will be returned by * [EMAIL PROTECTED] #getSignatures()}. @@ -45,9 +45,9 @@ * by [EMAIL PROTECTED] #getMethodHelp()}. */ public ReflectiveXmlRpcMetaDataHandler(AbstractReflectiveHandlerMapping pMapping, - Class pClass, Object pInstance, Method pMethod, + Class pClass, Object pInstance, Method[] pMethods, String[][] pSignatures, String pMethodHelp) { - super(pMapping, pClass, pInstance, pMethod); + super(pMapping, pClass, pInstance, pMethods); signatures = pSignatures; methodHelp = pMethodHelp; } Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java?rev=408757&r1=408756&r2=408757&view=diff ============================================================================== --- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java (original) +++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java Mon May 22 13:31:57 2006 @@ -17,6 +17,7 @@ import java.io.Serializable; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -94,13 +95,30 @@ return null; } - /** Returns a signature for the given method. - * @param pMethod Method, for which a signature is + /** Returns a signature for the given methods. + * @param pMethods Methods, for which a signature is * being queried. * @return Signature string, or null, if no signature * is available. */ - public static String[] getSignature(Method pMethod) { + public static String[][] getSignature(Method[] pMethods) { + final List result = new ArrayList(); + for (int i = 0; i < pMethods.length; i++) { + String[] sig = getSignature(pMethods[i]); + if (sig != null) { + result.add(sig); + } + } + return (String[][]) result.toArray(new String[result.size()][]); + } + + /** Returns a signature for the given methods. + * @param pMethod Method, for which a signature is + * being queried. + * @return Signature string, or null, if no signature + * is available. + */ + public static String[] getSignature(Method pMethod) { Class[] paramClasses = pMethod.getParameterTypes(); String[] sig = new String[paramClasses.length + 1]; String s = getSignatureType(pMethod.getReturnType()); @@ -118,7 +136,35 @@ return sig; } - /** Returns a help string for the given method, which + /** Returns a help string for the given method, which + * is applied to the given class. + */ + public static String getMethodHelp(Class pClass, Method[] pMethods) { + final List result = new ArrayList(); + for (int i = 0; i < pMethods.length; i++) { + String help = getMethodHelp(pClass, pMethods[i]); + if (help != null) { + result.add(help); + } + } + switch (result.size()) { + case 0: + return null; + case 1: + return (String) result.get(0); + default: + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < result.size(); i++) { + sb.append(i+1); + sb.append(": "); + sb.append(result.get(i)); + sb.append("\n"); + } + return sb.toString(); + } + } + + /** Returns a help string for the given method, which * is applied to the given class. */ public static String getMethodHelp(Class pClass, Method pMethod) { @@ -138,4 +184,78 @@ sb.append(")."); return sb.toString(); } + + /** Returns, whether the given methods signature is matched by + * the given parameter set. + */ + public static boolean isMatching(Method method, Object[] args) { + Class[] parameterClasses = method.getParameterTypes(); + if (parameterClasses.length != args.length) { + return false; + } + for (int i = 0; i < args.length; i++) { + if (!isMatching(parameterClasses[i], args[i])) { + return false; + } + } + return true; + } + + /** Returns, whether the given parameter matches the given + * type. + */ + public static boolean isMatching(Class pParameterType, Object pArg) { + if (pArg == null) { + return !pParameterType.isPrimitive(); + } + final Class c; + if (pParameterType.isPrimitive()) { + c = getObjectClass(pParameterType); + } else { + c = pParameterType; + } + return c.isAssignableFrom(pArg.getClass()); + } + + /** Given a primitive class, returns the corresponding object class. + */ + public static Class getObjectClass(Class pPrimitiveClass) { + if (byte.class.equals(pPrimitiveClass)) { + return Byte.class; + } else if (short.class.equals(pPrimitiveClass)) { + return Short.class; + } else if (int.class.equals(pPrimitiveClass)) { + return Integer.class; + } else if (long.class.equals(pPrimitiveClass)) { + return Long.class; + } else if (float.class.equals(pPrimitiveClass)) { + return Float.class; + } else if (double.class.equals(pPrimitiveClass)) { + return Double.class; + } else if (char.class.equals(pPrimitiveClass)) { + return Character.class; + } else if (boolean.class.equals(pPrimitiveClass)) { + return Boolean.class; + } else { + throw new IllegalStateException("Invalid primitive class: " + pPrimitiveClass.getName()); + } + } + + /** Returns a signature for the given parameter set. This is used + * in error messages. + */ + public static String getSignature(Object[] args) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + if (args[i] == null) { + sb.append("null"); + } else { + sb.append(args[i].getClass().getName()); + } + } + return sb.toString(); + } } Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java?rev=408757&r1=408756&r2=408757&view=diff ============================================================================== --- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java (original) +++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java Mon May 22 13:31:57 2006 @@ -91,6 +91,7 @@ if (pInstance == null) { throw new NullPointerException("The object instance must not be null."); } + Map map = new HashMap(); Method[] methods = pType.getMethods(); for (int i = 0; i < methods.length; i++) { final Method method = methods[i]; @@ -107,9 +108,23 @@ continue; // Ignore methods from Object.class } String name = pKey + "." + method.getName(); - if (!pMap.containsKey(name)) { - pMap.put(name, newXmlRpcHandler(pType, pInstance, method)); + Method[] mArray; + Method[] oldMArray = (Method[]) map.get(name); + if (oldMArray == null) { + mArray = new Method[]{method}; + } else { + mArray = new Method[oldMArray.length+1]; + System.arraycopy(oldMArray, 0, mArray, 0, oldMArray.length); + mArray[oldMArray.length] = method; } + map.put(name, mArray); + } + + for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry entry = (Map.Entry) iter.next(); + String name = (String) entry.getKey(); + Method[] mArray = (Method[]) entry.getValue(); + pMap.put(name, newXmlRpcHandler(pType, pInstance, mArray)); } } @@ -120,33 +135,33 @@ * @param pInstance The object, which is being invoked by * the created handler. Typically an instance of * <code>pClass</code>. - * @param pMethod The method being invoked. + * @param pMethods The method being invoked. */ protected XmlRpcHandler newXmlRpcHandler(final Class pClass, - final Object pInstance, final Method pMethod) { + final Object pInstance, final Method[] pMethods) { if (pInstance == null) { throw new NullPointerException("The object instance must not be null."); } - String[] sig = getSignature(pMethod); - String help = getMethodHelp(pClass, pMethod); + String[][] sig = getSignature(pMethods); + String help = getMethodHelp(pClass, pMethods); if (sig == null || help == null) { - return new ReflectiveXmlRpcHandler(this, pClass, pInstance, pMethod); + return new ReflectiveXmlRpcHandler(this, pClass, pInstance, pMethods); } return new ReflectiveXmlRpcMetaDataHandler(this, pClass, pInstance, - pMethod, new String[][]{sig}, help); + pMethods, sig, help); } /** Creates a signature for the given method. */ - protected String[] getSignature(Method pMethod) { - return Util.getSignature(pMethod); + protected String[][] getSignature(Method[] pMethods) { + return Util.getSignature(pMethods); } /** Creates a help string for the given method, when applied * to the given class. */ - protected String getMethodHelp(Class pClass, Method pMethod) { - return Util.getMethodHelp(pClass, pMethod); + protected String getMethodHelp(Class pClass, Method[] pMethods) { + return Util.getMethodHelp(pClass, pMethods); } /** Returns the [EMAIL PROTECTED] XmlRpcHandler} with the given name. Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java?rev=408757&r1=408756&r2=408757&view=diff ============================================================================== --- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java (original) +++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java Mon May 22 13:31:57 2006 @@ -22,6 +22,7 @@ import org.apache.xmlrpc.XmlRpcHandler; import org.apache.xmlrpc.XmlRpcRequest; import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException; +import org.apache.xmlrpc.metadata.Util; import org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping.AuthenticationHandler; @@ -31,7 +32,7 @@ private final AbstractReflectiveHandlerMapping mapping; private final Class clazz; private final Object instance; - private final Method method; + private final Method[] methods; /** Creates a new instance. * @param pMapping The mapping, which creates this handler. @@ -41,15 +42,15 @@ * messages only. * @param pInstance The instance, which will be invoked for * executing the handler. - * @param pMethod The method, which will be invoked for + * @param pMethods The method, which will be invoked for * executing the handler. */ public ReflectiveXmlRpcHandler(AbstractReflectiveHandlerMapping pMapping, - Class pClass, Object pInstance, Method pMethod) { + Class pClass, Object pInstance, Method[] pMethods) { mapping = pMapping; clazz = pClass; instance = pInstance; - method = pMethod; + methods = pMethods; } public Object execute(XmlRpcRequest pRequest) throws XmlRpcException { @@ -61,20 +62,33 @@ for (int j = 0; j < args.length; j++) { args[j] = pRequest.getParameter(j); } - try { - return method.invoke(instance, args); + if (methods.length == 1) { + return invoke(methods[0], args); + } else { + for (int i = 0; i < methods.length; i++) { + if (Util.isMatching(methods[i], args)) { + return invoke(methods[i], args); + } + } + throw new XmlRpcException("No method matching arguments: " + Util.getSignature(args)); + } + } + + private Object invoke(Method pMethod, Object[] pArgs) throws XmlRpcException { + try { + return pMethod.invoke(instance, pArgs); } catch (IllegalAccessException e) { throw new XmlRpcException("Illegal access to method " - + method.getName() + " in class " + + pMethod.getName() + " in class " + clazz.getName(), e); } catch (IllegalArgumentException e) { throw new XmlRpcException("Illegal argument for method " - + method.getName() + " in class " + + pMethod.getName() + " in class " + clazz.getName(), e); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); throw new XmlRpcException("Failed to invoke method " - + method.getName() + " in class " + + pMethod.getName() + " in class " + clazz.getName() + ": " + t.getMessage(), t); } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]