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]

Reply via email to