butek 02/02/15 10:20:10 Modified: java/src/org/apache/axis/message RPCHandler.java java/src/org/apache/axis/providers/java RPCProvider.java java/src/org/apache/axis/utils/cache JavaClass.java JavaMethod.java java/test/utils/cache TestJavaClass.java TestJavaMethod.java java/test/wsdl/clash clash.wsdl Log: Overloaded operation work: 1. (done) fix WSDL2Java 2. (done) get WSDL4J fix 3. fix runtime (this commit does some work that should satisfy most cases, but there's a lot of resolution work that needs doing, yet) 4. fix Java2WSDL Revision Changes Path 1.25 +8 -6 xml-axis/java/src/org/apache/axis/message/RPCHandler.java Index: RPCHandler.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCHandler.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- RPCHandler.java 8 Feb 2002 03:09:25 -0000 1.24 +++ RPCHandler.java 15 Feb 2002 18:20:10 -0000 1.25 @@ -96,7 +96,7 @@ { this.call = call; } - + private void determineDefaultParams(String methodName, DeserializationContext context) { MessageContext msgContext = context.getMessageContext(); @@ -116,11 +116,13 @@ "lookup00", methodName, clsName)); } - // try to find the method without knowing the number of - // parameters. If we are successful, we can make better - // decisions about what deserializers to use for parameters - Method method = jc.getMethod(methodName, -1); - if (method != null) defaultParamTypes = method.getParameterTypes(); + // If we find only one method of this name, we can use it + // to make better decisions about what deserializers to use + // for parameters. + Method[] method = jc.getMethod(methodName); + if (method != null && method.length == 1) { + defaultParamTypes = method[0].getParameterTypes(); + } // !!! This should be smart enough to deal with overloaded // methods - we should really be keeping a list of all of 1.37 +70 -57 xml-axis/java/src/org/apache/axis/providers/java/RPCProvider.java Index: RPCProvider.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/providers/java/RPCProvider.java,v retrieving revision 1.36 retrieving revision 1.37 diff -u -r1.36 -r1.37 --- RPCProvider.java 29 Jan 2002 21:30:13 -0000 1.36 +++ RPCProvider.java 15 Feb 2002 18:20:10 -0000 1.37 @@ -174,63 +174,69 @@ // wsdl. Thus the following code only works if there is no // overloading. int numberOfBodyArgs = args.size(); - Method method = getMethod(jc, mName, args); + Method[] method = getMethod(jc, mName); // If the method wasn't found, maybe it needs some Java mangling (ie., it's a Java // keyword or it's capitalized and the java mapping requires lowercase). if (method == null) { mName = JavaUtils.xmlNameToJava(mName); - method = getMethod(jc, mName, args); + method = getMethod(jc, mName); } if ( method == null ) throw new AxisFault( "AxisServer.error", JavaUtils.getMessage("noMethod00", mName, msgContext.getTargetService()), null, null ); - - Class params[] = method.getParameterTypes(); - - // The number of method parameters must match the - // arguments taking into consideration a MessageContext argument - // and output parameters. - Object[] newArgValues = new Object[params.length]; - int old = 0; - boolean problem = false; - for (int n = 0; n < newArgValues.length; n++) { - Class heldType = JavaUtils.getHolderValueType(params[n]); - if (params[n] == MessageContext.class) { - newArgValues[n] = msgContext; - } else if (argValues != null && old < argValues.length) { - newArgValues[n] = argValues[old++]; - } else if (heldType == null) { - // The parameters that don't match the argValues must - // be Holders. Indicate problem occurred. - problem = true; - } else { - newArgValues[n] = null; - } - // Create holders for each argument that is null that should be a holder - if (newArgValues[n] == null && heldType != null) { - newArgValues[n] = JavaUtils.convert(newArgValues[n], params[n]); + Object objRes = null; + Class[] params = null; + Exception ex = null; + + // There might be more than one method with this name, try them all. + int m = 0; + for (m = 0; m < method.length; ++m) { + ex = null; + params = method[m].getParameterTypes(); + + + // The number of method parameters must match the + // arguments taking into consideration a MessageContext argument + // and output parameters. + Object[] newArgValues = new Object[params.length]; + int old = 0; + boolean problem = false; + for (int n = 0; n < newArgValues.length; n++) { + Class heldType = JavaUtils.getHolderValueType(params[n]); + if (params[n] == MessageContext.class) { + newArgValues[n] = msgContext; + } else if (argValues != null && old < argValues.length) { + newArgValues[n] = argValues[old++]; + } else if (heldType == null) { + // The parameters that don't match the argValues must + // be Holders. Indicate problem occurred. + problem = true; + } else { + newArgValues[n] = null; + } + // Create holders for each argument that is null that should be a holder + if (newArgValues[n] == null && heldType != null) { + newArgValues[n] = JavaUtils.convert(newArgValues[n], params[n]); + } + } + if (!problem) { + argValues = newArgValues; // Use newArgValues array if no problems } - } - if (!problem) { - argValues = newArgValues; // Use newArgValues array if no problems - } - // Invoke the method and capture the returned object. - // Note that if the method returns a primitive, invoke(...) automatically - // wraps it in a java.lang class representing the primitive. - Object objRes; - try { - objRes = method.invoke(obj, argValues); - } catch (IllegalArgumentException e) { - - { + // Invoke the method and capture the returned object. + // Note that if the method returns a primitive, invoke(...) automatically + // wraps it in a java.lang class representing the primitive. + try { + objRes = method[m].invoke(obj, argValues); + break; + } catch (IllegalArgumentException e) { // Hm - maybe we can help this with a conversion or two... for (int i = 0; argValues != null && i < argValues.length && - i < params.length; i++) { + i < params.length; i++) { Object thisArg = argValues[i]; if (!params[i].isAssignableFrom(thisArg.getClass())) { // Attempt conversion for each non-assignable argument @@ -239,31 +245,38 @@ argValues[i] = newArg; } } - + // OK, now try again... try { - objRes = method.invoke( obj, argValues ); + objRes = method[m].invoke( obj, argValues ); + break; } catch (IllegalArgumentException exp) { StringBuffer argbuf = new StringBuffer(); String sep= ""; for(int i = 0; argValues != null && - i < argValues.length; ++i) { + i < argValues.length; ++i) { argbuf.append(sep); sep = ", "; argbuf.append(argValues[i] == null ? "null" : argValues[i].getClass().getName()); } String objName = obj == null ? "null" : - obj.getClass().getName(); + obj.getClass().getName(); String msg = JavaUtils.getMessage("triedArgs00", new String[] { - exp.getMessage(), - objName, - method.getName(), - argbuf.toString()}); - throw new IllegalArgumentException(msg); + exp.getMessage(), + objName, + method[m].getName(), + argbuf.toString()}); + ex = new IllegalArgumentException(msg); + continue; } } } + // If we've gone through all methods with the given name and there's + // an exception left over, throw that exception. + if (ex != null) { + throw ex; + } if (category.isDebugEnabled()) category.debug(JavaUtils.getMessage("result00", "" + objRes)); @@ -283,17 +296,17 @@ resBody.addParam ((RPCParam) list.get (i)); } else { - resBody.addParam (new RPCParam (getParameterName(obj, method,i, mName), + resBody.addParam (new RPCParam (getParameterName(obj, method[m],i, mName), list.get (i))); } } } else { - RPCParam param = new RPCParam(getParameterName(obj, method,-1, mName), objRes); + RPCParam param = new RPCParam(getParameterName(obj, method[m],-1, mName), objRes); resBody.addParam(param); } - } else if (method.getReturnType() != Void.TYPE) { - RPCParam param = new RPCParam(getParameterName(obj, method,-1, mName), objRes); + } else if (method[m].getReturnType() != Void.TYPE) { + RPCParam param = new RPCParam(getParameterName(obj, method[m],-1, mName), objRes); resBody.addParam(param); } @@ -305,7 +318,7 @@ // Create an RPCParam by converting the Holder back into // the held type. resBody.addParam (new RPCParam (getParameterName(obj, - method, + method[m], i, mName, args), @@ -320,9 +333,9 @@ } } - protected Method getMethod(JavaClass jc, String mName, Vector args) + protected Method[] getMethod(JavaClass jc, String mName) { - return jc.getMethod(mName, args.size()); + return jc.getMethod(mName); } /** 1.7 +4 -4 xml-axis/java/src/org/apache/axis/utils/cache/JavaClass.java Index: JavaClass.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/cache/JavaClass.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- JavaClass.java 30 Oct 2001 16:46:41 -0000 1.6 +++ JavaClass.java 15 Feb 2002 18:20:10 -0000 1.7 @@ -101,17 +101,17 @@ } /** - * Lookup a method based on name and number of arguments + * Lookup a method based on name. This method returns an array just in + * case there is more than one. * @param name name of method - * @param numargs number of arguments */ - public Method getMethod(String name, int numargs) { + public Method[] getMethod(String name) { JavaMethod jm = (JavaMethod) methods.get(name); if (jm == null) { methods.put(name, jm=new JavaMethod(jc, name)); } - return jm.getMethod(numargs); + return jm.getMethod(); } }; 1.9 +9 -32 xml-axis/java/src/org/apache/axis/utils/cache/JavaMethod.java Index: JavaMethod.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/cache/JavaMethod.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- JavaMethod.java 30 Oct 2001 16:46:41 -0000 1.8 +++ JavaMethod.java 15 Feb 2002 18:20:10 -0000 1.9 @@ -65,9 +65,7 @@ */ public class JavaMethod { - // at most, one of the following two are non-null, depending - // on the number of methods by this name found in the class - private Method unique = null; + // The list of the methods in the given class with the given name. private Method[] methods = null; /** @@ -77,50 +75,29 @@ */ public JavaMethod(Class jc, String name) { Method[] methods = jc.getMethods(); - Vector workinglist = null; + Vector workinglist = new Vector(); // scan for matching names, saving the match if it is unique, // otherwise accumulating a list for (int i=0; i<methods.length; i++) { if (methods[i].getName().equals(name)) { - if (unique != null) { - workinglist = new Vector(); - workinglist.addElement(unique); - workinglist.addElement(methods[i]); - unique = null; - } else if (workinglist != null) { - workinglist.addElement(methods[i]); - } else { - unique = methods[i]; - } + workinglist.addElement(methods[i]); } } // If a list was found, convert it into an array - if (workinglist != null) { + if (workinglist.size() > 0) { this.methods = new Method[workinglist.size()]; workinglist.copyInto(this.methods); } } /** - * Attempt to find the closest matching method based on the number - * of arguments only. Note: if there are multiple matches, one - * will be picked randomly. If the name is unique, it is simply - * returned without checking as attempts to invoke a method based - * on this will undoubtably fail anyway. - * @param numargs number of arguments. Use -1 to indicate "don't care". - * @return closest match + * Lookup a method based on name. This method returns an array just in + * case there is more than one. + * @param name name of method */ - public Method getMethod(int numargs) { - if (methods != null) { - for (int i=0; i<methods.length; i++) { - if (methods[i].getParameterTypes().length == numargs) { - return methods[i]; - } - } - } - - return unique; + public Method[] getMethod() { + return methods; } }; 1.7 +19 -25 xml-axis/java/test/utils/cache/TestJavaClass.java Index: TestJavaClass.java =================================================================== RCS file: /home/cvs/xml-axis/java/test/utils/cache/TestJavaClass.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- TestJavaClass.java 18 Oct 2001 13:28:39 -0000 1.6 +++ TestJavaClass.java 15 Feb 2002 18:20:10 -0000 1.7 @@ -38,44 +38,38 @@ JavaClass jcVec = new JavaClass(v); JavaClass jcST = new JavaClass(st); - Method countTkns = jcST.getMethod("countTokens", 0); - Method nextTkn = jcST.getMethod("nextToken", 1); + Method countTkns = jcST.getMethod("countTokens")[0]; + Method nextTkn = jcST.getMethod("nextToken")[0]; - Method add1 = jcVec.getMethod("add", 1); - Method add2 = jcVec.getMethod("add", 2); + Method[] adds = jcVec.getMethod("add"); assertEquals("countTkns name was not 'countTokens', it is: " + countTkns.getName(), "countTokens", countTkns.getName()); assertEquals("nextTkn name was not 'nextToken', it is: " + nextTkn.getName(), "nextToken", nextTkn.getName()); - assertEquals("Return type was not 'boolean', it was: " + add1.getReturnType().getName(), - "boolean", add1.getReturnType().getName()); - assertEquals("Return type was not 'void', it was: " + add2.getReturnType().getName(), - "void", add2.getReturnType().getName()); - } - - public void testNoSuchMethod() - { - Class v = new java.util.Vector().getClass(); - JavaClass jcVec = new JavaClass(v); + assertEquals("There are not 2 add methods as expected, there are " + adds.length, 2, adds.length); - Method add7 = jcVec.getMethod("add", 7); - assertNull("add7 was not null", add7); + for (int i = 0; i < adds.length; ++i) { + if (adds[i].getReturnType().equals(boolean.class)) { + assertEquals("Unexpected boolean add signature", + "public synchronized boolean java.util.Vector.add(java.lang.Object)", + adds[i].toString()); + } + else { + assertEquals("Unexpected void add signature", + "public void java.util.Vector.add(int,java.lang.Object)", + adds[i].toString()); + } + } } - public void testUnknownNumberOfArgs() + public void testNoSuchMethod() { Class v = new java.util.Vector().getClass(); JavaClass jcVec = new JavaClass(v); - Method add7 = jcVec.getMethod("add", -1); - assertNull("add7 was not null", add7); - - Method insertElementAt = jcVec.getMethod("insertElementAt", -1); - assertEquals("Length was not 2, it was: " + insertElementAt.getParameterTypes().length, - 2, insertElementAt.getParameterTypes().length); - assertEquals("Return type was not 'void', it was: " + insertElementAt.getReturnType().getName(), - "void", insertElementAt.getReturnType().getName()); + Method[] gorp = jcVec.getMethod("gorp"); + assertNull("gorp was not null", gorp); } } 1.5 +19 -24 xml-axis/java/test/utils/cache/TestJavaMethod.java Index: TestJavaMethod.java =================================================================== RCS file: /home/cvs/xml-axis/java/test/utils/cache/TestJavaMethod.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- TestJavaMethod.java 18 Oct 2001 13:28:39 -0000 1.4 +++ TestJavaMethod.java 15 Feb 2002 18:20:10 -0000 1.5 @@ -25,40 +25,34 @@ Class vector = new java.util.Vector().getClass(); JavaMethod jmAdd = new JavaMethod(vector, "add"); assertNotNull("jmAdd was null", jmAdd); - - Method methodWithOneParam = jmAdd.getMethod(1); - assertEquals("Method with one param was not 'add'", "add", methodWithOneParam.getName()); - Method methodWithTwoParams = jmAdd.getMethod(2); - assertEquals("Method with two params was not 'add'", "add", methodWithTwoParams.getName()); - assertEquals("Method with one param return type was not 'boolean'", "boolean", methodWithOneParam.getReturnType().getName()); - assertEquals("Method with two params return type was not 'void'", "void", methodWithTwoParams.getReturnType().getName()); - - boolean gotError = false; - try { - Method nonceMethod = jmAdd.getMethod(0); //should be no add() method with 0 params - nonceMethod.getName(); - } - catch (NullPointerException ex) { - gotError = true; - } - assertTrue("Expected NullPointerException", gotError); + Method[] adds = jmAdd.getMethod(); + assertEquals("There are not 2 add methods as expected, there are " + adds.length, 2, adds.length); - //on the other hand, make sure methods with 0 params work... - JavaMethod jmCapacity = new JavaMethod(vector, "capacity"); - Method methodWithNoParams = jmCapacity.getMethod(0); - assertEquals("Method with no params was not 'capacity'", "capacity", methodWithNoParams.getName()); + for (int i = 0; i < adds.length; ++i) { + if (adds[i].getReturnType().equals(boolean.class)) { + assertEquals("Unexpected boolean add signature", + "public synchronized boolean java.util.Vector.add(java.lang.Object)", + adds[i].toString()); + } + else { + assertEquals("Unexpected void add signature", + "public void java.util.Vector.add(int,java.lang.Object)", + adds[i].toString()); + } + } } public void testGetMethodWithOverloadedStringValueOf() { +/* RJB - now that I've removed the numArgs parameter, is this test really testing anything? Class str = new String().getClass(); JavaMethod jm = new JavaMethod(str, "valueOf"); assertNotNull("JavaMethod is null", jm); - Method methodWithOneParam = jm.getMethod(1); + Method methodWithOneParam = jm.getMethod()[0]; assertEquals("Method with one param is not 'valueOf'", "valueOf",methodWithOneParam.getName()); - Method methodWithThreeParams = jm.getMethod(3); + Method methodWithThreeParams = jm.getMethod()[0]; assertEquals("Method with two params is not 'valueOf'", "valueOf",methodWithThreeParams.getName()); assertEquals("Method with one param return type is not 'java.lang.String'", "java.lang.String", methodWithOneParam.getReturnType().getName()); @@ -66,12 +60,13 @@ boolean gotError = false; try { - Method nonceMethod = jm.getMethod(2); //should be no valueOf() method with 2 params + Method nonceMethod = jm.getMethod()[0]; //should be no valueOf() method with 2 params nonceMethod.getName(); } catch (NullPointerException ex) { gotError = true; } assertTrue("Expected NullPointerException", gotError); +*/ } } 1.4 +29 -25 xml-axis/java/test/wsdl/clash/clash.wsdl Index: clash.wsdl =================================================================== RCS file: /home/cvs/xml-axis/java/test/wsdl/clash/clash.wsdl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- clash.wsdl 13 Feb 2002 15:27:47 -0000 1.3 +++ clash.wsdl 15 Feb 2002 18:20:10 -0000 1.4 @@ -19,11 +19,18 @@ <xsd:element name="sharedName" type="xsd:int"/> </xsd:all> </xsd:complexType> - <xsd:element name="myElement"> + <xsd:element name="sharedName"> <xsd:complexType> - <all> - <element name="sharedName" type="xsd:int"/> - </all> + <xsd:all> + <xsd:element name="sharedName" type="xsd:int"/> + </xsd:all> + </xsd:complexType> + </xsd:element> + <xsd:element name="another"> + <xsd:complexType> + <xsd:all> + <xsd:element name="sharedName" type="xsd:boolean"/> + </xsd:all> </xsd:complexType> </xsd:element> </xsd:schema> @@ -35,8 +42,14 @@ <message name="sharedName"> <part name="sharedName" type="tns:sharedName"/> </message> + <message name="anotherMessage"> + <part name="sharedName" type="xsd:int"/> + </message> <message name="literalMessage"> - <part name="literalPart" element="tns:myElement"/> + <part name="literalPart" element="tns:sharedName"/> + </message> + <message name="anotherLitMessage"> + <part name="sharedName" element="tns:another"/> </message> <!-- port type declns --> @@ -45,32 +58,29 @@ <input name="sharedName" message="tns:empty"/> <output name="sharedName" message="tns:sharedName"/> </operation> -<!-- a bug in WSDL4J doesn't allow overloaded operations <operation name="sharedName"> <input name="sharedName" message="tns:sharedName"/> <output name="empty" message="tns:empty"/> </operation> <operation name="sharedName"> - <input name="empty" message="tns:empty"/> - <output name="sharedName" message="tns:sharedName"/> + <input name="another" message="tns:anotherMessage"/> + <output name="empty" message="tns:empty"/> </operation> ---> </portType> + <portType name="literalPort"> <operation name="sharedName"> <input name="sharedName" message="tns:empty"/> <output name="sharedName" message="tns:literalMessage"/> </operation> -<!-- a bug in WSDL4J doesn't allow overloaded operations <operation name="sharedName"> <input name="sharedName" message="tns:literalMessage"/> <output name="empty" message="tns:empty"/> </operation> <operation name="sharedName"> - <input name="empty" message="tns:empty"/> - <output name="sharedName" message="tns:literalMessage"/> + <input name="another" message="tns:anotherLitMessage"/> + <output name="empty" message="tns:empty"/> </operation> ---> </portType> <!-- binding declns --> @@ -86,7 +96,6 @@ <soap:body use="encoded"/> </output> </operation> -<!-- a bug in WSDL4J doesn't allow overloaded operations <operation name="sharedName"> <input name="sharedName"> <soap:body use="encoded"/> @@ -96,14 +105,13 @@ </output> </operation> <operation name="sharedName"> - <input name="empty"> + <input name="another"> <soap:body use="encoded"/> </input> - <output name="sharedName"> + <output name="empty"> <soap:body use="encoded"/> </output> </operation> ---> </binding> <binding name="sharedName" type="tns:literalPort"> @@ -118,7 +126,6 @@ <soap:body use="literal"/> </output> </operation> -<!-- a bug in WSDL4J doesn't allow overloaded operations <operation name="sharedName"> <input name="sharedName"> <soap:body use="literal"/> @@ -128,14 +135,13 @@ </output> </operation> <operation name="sharedName"> - <input name="empty"> + <input name="another"> <soap:body use="literal"/> </input> - <output name="sharedName"> + <output name="empty"> <soap:body use="literal"/> </output> </operation> ---> </binding> <binding name="anotherNonSharedName" type="tns:sharedName"> @@ -150,7 +156,6 @@ <soap:body use="encoded"/> </output> </operation> -<!-- a bug in WSDL4J doesn't allow overloaded operations <operation name="sharedName"> <input name="sharedName"> <soap:body use="encoded"/> @@ -160,14 +165,13 @@ </output> </operation> <operation name="sharedName"> - <input name="empty"> + <input name="another"> <soap:body use="encoded"/> </input> - <output name="sharedName"> + <output name="empty"> <soap:body use="encoded"/> </output> </operation> ---> </binding> <!-- service decln -->