You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by gd...@apache.org on 2002/03/27 18:53:08 UTC

cvs commit: xml-axis/java/test/wsdl/marrays MArrayTestsSOAPBindingImpl.java MArrayTestsServiceTestCase.java

gdaniels    02/03/27 09:53:08

  Modified:    java/samples/echo EchoServiceBindingStub.java
                        TestClient.java deploy.wsdd
               java/src/org/apache/axis/client Call.java Service.java
               java/src/org/apache/axis/deployment/wsdd WSDDOperation.java
               java/src/org/apache/axis/description OperationDesc.java
                        ServiceDesc.java
               java/src/org/apache/axis/encoding
                        DefaultTypeMappingImpl.java TypeMappingImpl.java
               java/src/org/apache/axis/encoding/ser
                        SimpleDeserializerFactory.java
               java/src/org/apache/axis/message RPCElement.java
                        RPCHandler.java
               java/src/org/apache/axis/providers/java RPCProvider.java
               java/src/org/apache/axis/utils JavaUtils.java
               java/src/org/apache/axis/wsdl/toJava JavaDeployWriter.java
               java/test/RPCDispatch TestRPC.java TestSerializedRPC.java
               java/test/encoding TestSer.java
               java/test/wsdl/marrays MArrayTestsSOAPBindingImpl.java
                        MArrayTestsServiceTestCase.java
  Log:
  Improvements / cleanup of the RPC infrastructure + service metadata.  Still
  needs some work, but this is much more like it.  Need to implement some edge-
  case tests for this code.
  
  Details:
  
  * Fix NPE in WSDDOperation - there can be 0 elementMappings
  
  * Slight change in TypeMappingImpl to only override the qname or class
    mapping for a registered type mapping if there is a serializer/deserializer
    present OR if there is no other mapping registered in that direction.
  
  * Mapping from xmlsoap:Map is now to HashMap, not Map.  We still happily
    serialize any Map to an xmlsoap:Map, but the deser mapping goes to the
    concrete class.
  
  * Add "isConvertable()" method to JavaUtils.
  
  * ServiceDesc is now much smarter about introspecting.  We introspect once
    for each method that we're interested in, and methods which never get called
    typically won't ever get introspected for.
  
  * Implement "synchronizing" OperationDescs which have been generated from
    deployment (WSDD) info with an implementation class on the server.  This
    means if we have a service with this deployment info:
        <service...>
           <operation name="method">
              <parameter name="a" type="xsd:string" mode="IN"/>
              <parameter name="b" type="xsd:string" mode="INOUT"/>
              <parameter name="c" type="xsd:string" mode="OUT"/>
           </operation>
        </service>
  
    ...and a method on the implementation class which looks like this:
  
        public void method(String a, StringHolder b, StringHolder c)
  
    we will match the two together, recording the correct Java classes for
    the parameters in the ParameterDescs, and keeping a pointer to the Method
    in the OperationDesc.  See next couple of bullets for why this is cool.
  
  * RPCProvider method search + dispatch code is now *much* cleaner.  We rely
    on "early binding" to dispatch to the correct method via a ServiceDesc,
    so by the time we've deserialized the RPCElement successfully, we know
    exactly which OperationDesc (and hence which Java Method) we're dealing with.
    That enables us to simply set up the parameters and call it.
  
  * RPCHandler now checks any actually received xsi:types against what is
    expected/desired by the appropriate ParameterDesc, and throws a fault
    if it can't map them.
  
  * RPCElement doesn't try to introspect every time anymore, it just makes sure
    the ServiceDesc has the right typemapping and implementation class if
    appropriate.  Then getOperationsByName() will introspect if necessary.
  
  * JavaDeployWriter now writes out <parameter> information into the WSDD
  
  * Put in missing mapping in samples/echo service, and put an <operation>
    into the deploy.wsdd so we get the OUT parameters right for
    echoStructAsSimpleTypes()
  
  * Enable accessing a Call's TypeMapping via getTypeMapping() - relies on the
    encodingStyle being set correctly.
  
  * Remove various try/catch blocks which were obscuring exceptions in tests.
    Tests in general should throw exceptions (and their associated stack traces)
    instead of eating them, unless there's a good reason to eat them.
  
  * Move code which understands primitives/wrappers into JavaUtils, since it's
    generally handy
  
  Revision  Changes    Path
  1.6       +7 -0      xml-axis/java/samples/echo/EchoServiceBindingStub.java
  
  Index: EchoServiceBindingStub.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/samples/echo/EchoServiceBindingStub.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- EchoServiceBindingStub.java	27 Mar 2002 16:46:55 -0000	1.5
  +++ EchoServiceBindingStub.java	27 Mar 2002 17:53:05 -0000	1.6
  @@ -62,6 +62,13 @@
               cachedSerFactories.add(arraysf);
               cachedDeserFactories.add(arraydf);
   
  +            qName = new javax.xml.rpc.namespace.QName("http://soapinterop.org/", "ArrayOf_tns2_Map");
  +            cachedSerQNames.add(qName);
  +            cls = java.util.HashMap[].class;
  +            cachedSerClasses.add(cls);
  +            cachedSerFactories.add(arraysf);
  +            cachedDeserFactories.add(arraydf);
  +
               qName = new javax.xml.rpc.namespace.QName("http://soapinterop.org/xsd", "ArrayOfstring");
               cachedSerQNames.add(qName);
               cls = java.lang.String[].class;
  
  
  
  1.57      +54 -138   xml-axis/java/samples/echo/TestClient.java
  
  Index: TestClient.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/samples/echo/TestClient.java,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- TestClient.java	27 Mar 2002 16:46:55 -0000	1.56
  +++ TestClient.java	27 Mar 2002 17:53:05 -0000	1.57
  @@ -181,72 +181,44 @@
   
           {
               String input = "abccdefg";
  -            try {
  -                output = binding.echoString(input);
  -                verify("echoString", input, output);
  -            } catch (Exception e) {
  -                verify("echoString", input, e);
  -            }
  +            output = binding.echoString(input);
  +            verify("echoString", input, output);
           }
           
           {
               String[] input = new String[] {"abc", "def"};
  -            try {
  -                output = binding.echoStringArray(input);
  -                verify("echoStringArray", input, output);
  -            } catch (Exception e) {
  -                verify("echoStringArray", input, e);
  -            }
  +            output = binding.echoStringArray(input);
  +            verify("echoStringArray", input, output);
           }
           
           {
               Integer input = new Integer(42);
  -            try {
  -                output = new Integer( binding.echoInteger(input.intValue()));
  -                verify("echoInteger", input, output);
  -            } catch (Exception e) {
  -                verify("echoInteger", input, e);
  -            }
  +            output = new Integer( binding.echoInteger(input.intValue()));
  +            verify("echoInteger", input, output);
           }
           
           {
               int[] input = new int[] {42};
  -            try {
  -                output = binding.echoIntegerArray(input);
  -                verify("echoIntegerArray", input, output);
  -            } catch (Exception e) {
  -                verify("echoIntegerArray", input, e);
  -            }
  +            output = binding.echoIntegerArray(input);
  +            verify("echoIntegerArray", input, output);
           }
           
           {
               Float input = new Float(3.7F);
  -            try {
  -                output = new Float(binding.echoFloat(input.floatValue()));
  -                verify("echoFloat", input, output);
  -            } catch (Exception e) {
  -                verify("echoFloat", input, e);
  -            }
  +            output = new Float(binding.echoFloat(input.floatValue()));
  +            verify("echoFloat", input, output);
           }
   
           {
               float[] input = new float[] {3.7F, 7F};
  -            try {
  -                output = binding.echoFloatArray(input);
  -                verify("echoFloatArray", input, output);
  -            } catch (Exception e) {
  -                verify("echoFloatArray", input, e);
  -            }
  +            output = binding.echoFloatArray(input);
  +            verify("echoFloatArray", input, output);
           }
   
           {
               SOAPStruct input = new SOAPStruct(5, "Hello", 103F);
  -            try {
  -                output = binding.echoStruct(input);
  -                verify("echoStruct", input, output);
  -            } catch (Exception e) {
  -                verify("echoStruct", input, e);
  -            }
  +            output = binding.echoStruct(input);
  +            verify("echoStruct", input, output);
           }
           
           {
  @@ -254,71 +226,43 @@
                   new SOAPStruct(1, "one", 1.1F),
                   new SOAPStruct(2, "two", 2.2F),
                   new SOAPStruct(3, "three", 3.3F)};
  -            try {
  -                output = binding.echoStructArray(input);
  -                verify("echoStructArray", input, output);
  -            } catch (Exception e) {
  -                verify("echoStructArray", input, e);
  -            }
  +            output = binding.echoStructArray(input);
  +            verify("echoStructArray", input, output);
           }
   
           {
  -            try {
  -                binding.echoVoid();
  -                verify("echoVoid", null, null);
  -            } catch (Exception e) {
  -                verify("echoVoid", null, e);
  -            }
  +            binding.echoVoid();
  +            verify("echoVoid", null, null);
           }
   
           {
               byte[] input = "Base64".getBytes();
  -            try {
  -                output = binding.echoBase64(input);
  -                verify("echoBase64", input, output);
  -            } catch (Exception e) {
  -                verify("echoBase64", input, e);
  -            }
  +            output = binding.echoBase64(input);
  +            verify("echoBase64", input, output);
           }
           
           {
               Hex input = new Hex("3344");
  -            try {
  -                output = binding.echoHexBinary(input.getBytes());
  -                verify("echoHexBinary", input, output);
  -            } catch (Exception e) {
  -                verify("echoHexBinary", input, e);
  -            }
  +            output = binding.echoHexBinary(input.getBytes());
  +            verify("echoHexBinary", input, output);
           }
           
           {
               Date input = new Date();
  -            try {
  -                output = binding.echoDate(input);
  -                verify("echoDate", input, output);
  -            } catch (Exception e) {
  -                verify("echoDate", input, e);
  -            }
  +            output = binding.echoDate(input);
  +            verify("echoDate", input, output);
           }
           
           {
               BigDecimal input = new BigDecimal("3.14159");
  -            try {
  -                output = binding.echoDecimal(input);
  -                verify("echoDecimal", input, output);
  -            } catch (Exception e) {
  -                verify("echoDecimal", input, e);
  -            }
  +            output = binding.echoDecimal(input);
  +            verify("echoDecimal", input, output);
           }
           
           {
               Boolean input = Boolean.TRUE;
  -            try {
  -                output = new Boolean( binding.echoBoolean(input.booleanValue()));
  -                verify("echoBoolean", input, output);
  -            } catch (Exception e) {
  -                verify("echoBoolean", input, e);
  -            }
  +            output = new Boolean( binding.echoBoolean(input.booleanValue()));
  +            verify("echoBoolean", input, output);
           }
           
           HashMap map = new HashMap();
  @@ -326,12 +270,8 @@
           map.put("String Key", new Date());
           {
               HashMap input = map;
  -            try {
  -                output = binding.echoMap(input);
  -                verify("echoMap", input, output);
  -            } catch (Exception e) {
  -                verify("echoMap", input, e);
  -            }
  +            output = binding.echoMap(input);
  +            verify("echoMap", input, output);
           }
   
           HashMap map2 = new HashMap();
  @@ -339,12 +279,8 @@
           map2.put("test", new Float(411));
           {
               HashMap[] input = new HashMap [] {map, map2 };
  -            try {
  -                output = binding.echoMapArray(input);
  -                verify("echoMapArray", input, output);
  -            } catch (Exception e) {
  -                verify("echoMapArray", input, e);
  -            }
  +            output = binding.echoMapArray(input);
  +            verify("echoMapArray", input, output);
           }
       }
   
  @@ -356,32 +292,24 @@
           Object output = null;
           {
               SOAPStruct input = new SOAPStruct(5, "Hello", 103F);
  -            try {
  -                StringHolder outputString = new StringHolder();
  -                IntHolder outputInteger = new IntHolder();
  -                FloatHolder outputFloat = new FloatHolder();
  -                binding.echoStructAsSimpleTypes(input, outputString, outputInteger, outputFloat);
  -                output = new SOAPStruct(outputInteger.value,
  -                                        outputString.value,
  -                                        outputFloat.value);
  -                verify("echoStructAsSimpleTypes", 
  -                       input, output);
  -            } catch (Exception e) {
  -                verify("echoStructAsSimpleTypes", input, e);
  -            }
  +            StringHolder outputString = new StringHolder();
  +            IntHolder outputInteger = new IntHolder();
  +            FloatHolder outputFloat = new FloatHolder();
  +            binding.echoStructAsSimpleTypes(input, outputString, outputInteger, outputFloat);
  +            output = new SOAPStruct(outputInteger.value,
  +                                    outputString.value,
  +                                    outputFloat.value);
  +            verify("echoStructAsSimpleTypes", 
  +                   input, output);
           }
   
           {
               SOAPStruct input = new SOAPStruct(5, "Hello", 103F);
  -            try {
  -                output = binding.echoSimpleTypesAsStruct(
  -                   input.getVarString(), input.getVarInt(), input.getVarFloat());
  -                verify("echoSimpleTypesAsStruct", 
  -                       input, 
  -                       output);
  -            } catch (Exception e) {
  -                verify("echoSimpleTypesAsStruct", input, e);
  -            }
  +            output = binding.echoSimpleTypesAsStruct(
  +                    input.getVarString(), input.getVarInt(), input.getVarFloat());
  +            verify("echoSimpleTypesAsStruct", 
  +                   input, 
  +                   output);
           }
   
           {
  @@ -390,14 +318,10 @@
               input[0][1] = "01";
               input[1][0] = "10";
               input[1][1] = "11";
  -            try {
  -                output = binding.echo2DStringArray(input);
  -                verify("echo2DStringArray", 
  -                       input, 
  -                       output);
  -            } catch (Exception e) {
  -                verify("echo2DStringArray", input, e);
  -            }
  +            output = binding.echo2DStringArray(input);
  +            verify("echo2DStringArray", 
  +                   input, 
  +                   output);
           }
   
           {
  @@ -405,24 +329,16 @@
                                                             1,
                                                             3F,
                                                             new SOAPStruct(5, "Hello", 103F));
  -            try {
  -                output = binding.echoNestedStruct(input);
  -                verify("echoNestedStruct", input, output);
  -            } catch (Exception e) {
  -                verify("echoNestedStruct", input, e);
  -            }
  +            output = binding.echoNestedStruct(input);
  +            verify("echoNestedStruct", input, output);
           }
           {
               SOAPArrayStruct input = new SOAPArrayStruct("AXIS",
                                                           1,
                                                           3F,
                                                           new String[] {"one", "two", "three"});
  -            try {
  -                output = binding.echoNestedArray(input);
  -                verify("echoNestedArray", input, output);
  -            } catch (Exception e) {
  -                verify("echoNestedArray", input, e);
  -            }
  +            output = binding.echoNestedArray(input);
  +            verify("echoNestedArray", input, output);
           }
       }
   
  
  
  
  1.17      +18 -1     xml-axis/java/samples/echo/deploy.wsdd
  
  Index: deploy.wsdd
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/samples/echo/deploy.wsdd,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- deploy.wsdd	15 Feb 2002 19:41:16 -0000	1.16
  +++ deploy.wsdd	27 Mar 2002 17:53:05 -0000	1.17
  @@ -6,8 +6,9 @@
   <!--   java org.apache.axis.client.http.AdminClient deploy.wsdd  -->
   <!--      after the axis server is running                      -->
   
  - <deployment 	name="test" xmlns="http://xml.apache.org/axis/wsdd/" 
  + <deployment 	name="test" xmlns="http://xml.apache.org/axis/wsdd/"
   			xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
  +            xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
   			xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">
     <service name="echo" provider="java:RPC" >
       <namespace>http://soapinterop.org/</namespace>
  @@ -63,6 +64,14 @@
           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
         />
         <typeMapping
  +        xmlns:ns="http://soapinterop.org/"
  +        qname="ns:ArrayOf_tns2_Map"
  +        type="java:java.util.HashMap[]"
  +        serializer="org.apache.axis.encoding.ser.ArraySerializerFactory"
  +        deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory"
  +        encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  +      />
  +      <typeMapping
           xmlns:ns="http://soapinterop.org/xsd"
           qname="ns:SOAPStructStruct"
           type="java:samples.echo.SOAPStructStruct"
  @@ -87,5 +96,13 @@
           <handler type="java:samples.echo.echoHeaderStringHandler"/>
           <handler type="java:samples.echo.echoHeaderStructHandler"/>
       </responseFlow>
  +
  +    <operation name="echoStructAsSimpleTypes">
  +      <parameter name="inputStruct" xmlns:ns="http://soapinterop.org/xsd"
  +                 type="ns:SOAPStruct"/>
  +      <parameter name="outputString" type="xsd:string" mode="OUT"/>
  +      <parameter name="outputInteger" type="xsd:int" mode="OUT"/>
  +      <parameter name="outputFloat" type="xsd:float" mode="OUT"/>
  +    </operation>
     </service>
   </deployment>
  
  
  
  1.108     +40 -21    xml-axis/java/src/org/apache/axis/client/Call.java
  
  Index: Call.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/client/Call.java,v
  retrieving revision 1.107
  retrieving revision 1.108
  diff -u -r1.107 -r1.108
  --- Call.java	27 Mar 2002 16:46:56 -0000	1.107
  +++ Call.java	27 Mar 2002 17:53:06 -0000	1.108
  @@ -698,7 +698,12 @@
        */
       public void addParameter(QName paramName, QName xmlType,
               ParameterMode parameterMode) {
  -        addParameter(paramName, xmlType, null, parameterMode);
  +        Class javaType = null;
  +        TypeMapping tm = getTypeMapping();
  +        if (tm != null) {
  +            javaType = tm.getClassForQName(xmlType);
  +        }
  +        addParameter(paramName, xmlType, javaType, parameterMode);
       }
   
       /**
  @@ -749,7 +754,12 @@
        */
       public void addParameter(String paramName, QName xmlType,
               ParameterMode parameterMode) {
  -        addParameter(new QName("", paramName), xmlType, null, parameterMode);
  +        Class javaType = null;
  +        TypeMapping tm = getTypeMapping();
  +        if (tm != null) {
  +            javaType = tm.getClassForQName(xmlType);
  +        }
  +        addParameter(new QName("", paramName), xmlType, javaType, parameterMode);
       }
   
       /**
  @@ -812,7 +822,11 @@
       public void setReturnType(QName type) {
           if (parmAndRetReq) {
               returnType = type ;
  -            if (operation != null) operation.setReturnType(type);
  +            if (operation != null) {
  +                operation.setReturnType(type);
  +                TypeMapping tm = getTypeMapping();
  +                operation.setReturnClass(tm.getClassForQName(type));
  +            }
           }
           else {
               throw new JAXRPCException();
  @@ -1517,6 +1531,22 @@
       {
           myHeaders = null;
       }
  +    
  +    public TypeMapping getTypeMapping()
  +    {
  +        // Get the TypeMappingRegistry
  +        TypeMappingRegistry tmr = msgContext.getTypeMappingRegistry();
  +
  +        // If a TypeMapping is not available, add one.
  +        TypeMapping tm = (TypeMapping) tmr.getTypeMapping(encodingStyle);
  +        TypeMapping defaultTM = (TypeMapping) tmr.getDefaultTypeMapping();
  +        if (tm == null || tm == defaultTM ) {
  +            tm = (TypeMapping) tmr.createTypeMapping();
  +            tm.setSupportedNamespaces(new String[] {encodingStyle});
  +            tmr.register(encodingStyle, tm);
  +        }
  +        return tm;
  +    }
   
       /**
        * Register type mapping information for serialization/deserialization
  @@ -1537,25 +1567,14 @@
                                       SerializerFactory sf,
                                       DeserializerFactory df,
                                       boolean force) {
  -        // Get the TypeMappingRegistry
  -        TypeMappingRegistry tmr = msgContext.getTypeMappingRegistry();
  -
  -        // If a TypeMapping is not available, add one.
  -        TypeMapping tm = (TypeMapping) tmr.getTypeMapping(encodingStyle);
  -        TypeMapping defaultTM = (TypeMapping) tmr.getDefaultTypeMapping();
  -        try {
  -            if (tm == null || tm == defaultTM ) {
  -                tm = (TypeMapping) tmr.createTypeMapping();
  -                tm.setSupportedNamespaces(new String[] {encodingStyle});
  -                tmr.register(encodingStyle, tm);
  -            }
  -            if (!force && tm.isRegistered(javaType, xmlType))
  -                return;
  -
  -            // Register the information
  -            tm.register(javaType, xmlType, sf, df);
  -        } catch (Exception e) {}
  +        TypeMapping tm = getTypeMapping();
  +        if (!force && tm.isRegistered(javaType, xmlType))
  +            return;
  +        
  +        // Register the information
  +        tm.register(javaType, xmlType, sf, df);
       }
  +
       public void registerTypeMapping(Class javaType, QName xmlType,
                                       Class sfClass, Class dfClass) {
           registerTypeMapping(javaType, xmlType, sfClass, dfClass, true);
  
  
  
  1.47      +1 -1      xml-axis/java/src/org/apache/axis/client/Service.java
  
  Index: Service.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/client/Service.java,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- Service.java	26 Mar 2002 22:34:23 -0000	1.46
  +++ Service.java	27 Mar 2002 17:53:06 -0000	1.47
  @@ -548,7 +548,7 @@
        * @return TypeMappingRegistry The registry
        */
       public TypeMappingRegistry getTypeMappingRegistry() {
  -        return( null );
  +        return( engine.getTypeMappingRegistry() );
       }
   
       /**
  
  
  
  1.15      +8 -6      xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDOperation.java
  
  Index: WSDDOperation.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDOperation.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- WSDDOperation.java	22 Mar 2002 16:08:31 -0000	1.14
  +++ WSDDOperation.java	27 Mar 2002 17:53:06 -0000	1.15
  @@ -110,12 +110,14 @@
                   throw new WSDDException(JavaUtils.getMessage("onlyOneMapping"));
               }
   
  -            // Register a mapping from an Element QName to a particular
  -            // method so we can dispatch for doc/lit services.
  -            Element el = mappingElements[0];
  -            String elString = el.getAttribute("qname");
  -            QName elQName = XMLUtils.getQNameFromString(elString, el);
  -            desc.setElementQName(elQName);
  +            if (mappingElements.length > 0) {
  +                // Register a mapping from an Element QName to a particular
  +                // method so we can dispatch for doc/lit services.
  +                Element el = mappingElements[0];
  +                String elString = el.getAttribute("qname");
  +                QName elQName = XMLUtils.getQNameFromString(elString, el);
  +                desc.setElementQName(elQName);
  +            }
           }
       }
   
  
  
  
  1.4       +41 -1     xml-axis/java/src/org/apache/axis/description/OperationDesc.java
  
  Index: OperationDesc.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/description/OperationDesc.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- OperationDesc.java	22 Mar 2002 16:08:31 -0000	1.3
  +++ OperationDesc.java	27 Mar 2002 17:53:06 -0000	1.4
  @@ -57,6 +57,7 @@
   import javax.xml.rpc.namespace.QName;
   import java.util.ArrayList;
   import java.util.Iterator;
  +import java.lang.reflect.Method;
   
   /**
    * An OperationDesc is an abstract description of an operation on a service.
  @@ -83,10 +84,18 @@
   
       /** The return type */
       private QName returnType;
  +    
  +    /** The return class */
  +    private Class returnClass;
  +    
  +    // FIXME : Just have a return ParamDesc???
   
       /** The Java method name this maps to (is this just name?) */
       private String methodName;
   
  +    /** The actual Java method associated with this operation, if known */
  +    private Method method;
  +
       /** This operation's style.  If null, we default to our parent's */
       private Integer style;
   
  @@ -129,6 +138,14 @@
           this.returnType = returnType;
       }
   
  +    public Class getReturnClass() {
  +        return returnClass;
  +    }
  +
  +    public void setReturnClass(Class returnClass) {
  +        this.returnClass = returnClass;
  +    }
  +
       public QName getElementQName() {
           return elementQName;
       }
  @@ -194,6 +211,14 @@
           return parameters.size();
       }
   
  +    public Method getMethod() {
  +        return method;
  +    }
  +
  +    public void setMethod(Method method) {
  +        this.method = method;
  +    }
  +
       public ParameterDesc getParamByQName(QName qname)
       {
           for (Iterator i = parameters.iterator(); i.hasNext();) {
  @@ -211,7 +236,7 @@
   
           param = getParamByQName(qname);
   
  -        if ((param == null) || (param.getMode() != ParameterDesc.IN)) {
  +        if ((param == null) || (param.getMode() == ParameterDesc.OUT)) {
               param = null;
           }
   
  @@ -233,10 +258,25 @@
                   param = new ParameterDesc();
                   param.setQName(qname);
                   param.setTypeQName(returnType);
  +                param.setJavaType(returnClass);
               }
           }
   
           return param;
  +    }
  +
  +    /**
  +     * Returns an ordered list of out params (NOT inouts)
  +     */
  +    public ArrayList getOutParams() {
  +        ArrayList result = new ArrayList();
  +        for (Iterator i = parameters.iterator(); i.hasNext();) {
  +            ParameterDesc desc = (ParameterDesc) i.next();
  +            if (desc.getMode() == ParameterDesc.OUT) {
  +                result.add(desc);
  +            }
  +        }
  +        return result;
       }
   }
   
  
  
  
  1.6       +221 -51   xml-axis/java/src/org/apache/axis/description/ServiceDesc.java
  
  Index: ServiceDesc.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/description/ServiceDesc.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ServiceDesc.java	25 Mar 2002 04:44:01 -0000	1.5
  +++ ServiceDesc.java	27 Mar 2002 17:53:06 -0000	1.6
  @@ -56,6 +56,7 @@
   
   import org.apache.axis.utils.JavaUtils;
   import org.apache.axis.encoding.TypeMapping;
  +import org.apache.axis.encoding.TypeMappingRegistry;
   
   import javax.xml.rpc.namespace.QName;
   import java.util.ArrayList;
  @@ -114,6 +115,10 @@
       /** Lookup caches */
       private HashMap name2OperationsMap = null;
       private HashMap qname2OperationMap = null;
  +    private HashMap method2OperationMap = new HashMap();
  +    private ArrayList completedNames = new ArrayList();
  +
  +    private TypeMapping tm = null;
   
       /**
        * Default constructor
  @@ -159,6 +164,22 @@
           this.allowedMethods = allowedMethods;
       }
   
  +    public Class getImplClass() {
  +        return implClass;
  +    }
  +
  +    public void setImplClass(Class implClass) {
  +        this.implClass = implClass;
  +    }
  +
  +    public TypeMapping getTypeMapping() {
  +        return tm;
  +    }
  +
  +    public void setTypeMapping(TypeMapping tm) {
  +        this.tm = tm;
  +    }
  +
       public void addOperationDesc(OperationDesc operation)
       {
           operations.add(operation);
  @@ -176,38 +197,42 @@
           }
   
           overloads.add(operation);
  -
  -        // If we're adding these, we won't introspect (either because we
  -        // trust the deployer/user to add everything instead, or because
  -        // we're actually in the middle of introspecting right now)
  -        hasOperationData = true;
       }
   
       public OperationDesc [] getOperationsByName(String methodName)
       {
  +        getSyncedOperationsForName(methodName);
  +
           if (name2OperationsMap == null)
               return null;
   
  -        ArrayList result = (ArrayList)name2OperationsMap.get(methodName);
  -        if (result == null)
  +        ArrayList overloads = (ArrayList)name2OperationsMap.get(methodName);
  +        if (overloads == null) {
               return null;
  +        }
   
  -        OperationDesc [] array = new OperationDesc [result.size()];
  -        return (OperationDesc[])result.toArray(array);
  +        OperationDesc [] array = new OperationDesc [overloads.size()];
  +        return (OperationDesc[])overloads.toArray(array);
       }
   
       /**
        * Return an operation matching the given method name.  Note that if we
        * have multiple overloads for this method, we will return the first one.
        */
  -    public OperationDesc getOperationDescByName(String methodName)
  +    public OperationDesc getOperationByName(String methodName)
       {
  +        // If we need to load up operations from introspection data, do it.
  +        // This returns fast if we don't need to do anything, so it's not very
  +        // expensive.
  +        getSyncedOperationsForName(methodName);
  +
           if (name2OperationsMap == null)
               return null;
   
           ArrayList overloads = (ArrayList)name2OperationsMap.get(methodName);
  -        if (overloads == null)
  +        if (overloads == null) {
               return null;
  +        }
   
           return (OperationDesc)overloads.get(0);
       }
  @@ -219,9 +244,13 @@
       {
           // If we're a wrapped service (i.e. RPC or WRAPPED style), we expect
           // this qname to match one of our operation names directly.
  -        // FIXME : Should this really ignore namespaces?
  +
  +        // FIXME : Should this really ignore namespaces?  Perhaps we should
  +        //         just check by QName... (I think that's right, actually,
  +        //         and the only time we should ignore namespaces is when
  +        //         deserializing SOAP-encoded structures?)
           if (isWrapped()) {
  -            return getOperationDescByName(qname.getLocalPart());
  +            return getOperationByName(qname.getLocalPart());
           }
   
           // If we're MESSAGE style, we should only have a single operation,
  @@ -246,55 +275,196 @@
       }
   
       /**
  -     * Fill in what we can of the service description by introspecting a
  -     * Java class.  Only do this if we haven't already been filled in.
  +     * Synchronize an existing OperationDesc to a java.lang.Method.
  +     *
  +     * This method is used when the deployer has specified operation metadata
  +     * and we want to match that up with a real java Method so that the
  +     * Operation-level dispatch carries us all the way to the implementation.
  +     * Search the declared methods on the implementation class to find one
  +     * with an argument list which matches our parameter list.
        */
  -    public void loadServiceDescByIntrospection(Class jc, TypeMapping tm)
  +    private void syncOperationToClass(OperationDesc oper)
       {
  -        if (hasOperationData)
  +        // If we're already mapped to a Java method, no need to do anything.
  +        if (oper.getMethod() != null)
               return;
   
  -        Method [] methods = jc.getDeclaredMethods();
  +        // Find the method.  We do this once for each Operation.
  +        Method [] methods = implClass.getDeclaredMethods();
  +        for (int i = 0; i < methods.length; i++) {
  +            Method method = methods[i];
  +            if (method.getName().equals(oper.getName())) {
  +                // Check params
  +                Class [] paramTypes = method.getParameterTypes();
  +                if (paramTypes.length != oper.getNumParams())
  +                    continue;
  +
  +                int j;
  +                for (j = 0; j < paramTypes.length; j++) {
  +                    Class type = paramTypes[j];
  +                    ParameterDesc param = oper.getParameter(j);
  +                    // See if they match
  +                    Class paramClass = tm.getClassForQName(
  +                            param.getTypeQName());
  +
  +                    // This is a match if the paramClass is somehow
  +                    // convertable to the "real" parameter type.
  +                    if (JavaUtils.isConvertable(paramClass, type)) {
  +                        param.setJavaType(type);
  +                        continue;
  +                    }
  +                    break;
  +                }
  +
  +                if (j != paramTypes.length) {
  +                    // failed.
  +                    continue;
  +                }
  +
  +                // At some point we might want to check here to see if this
  +                // Method is already associated with another Operation, but
  +                // this doesn't seem critital.
  +
  +                oper.setMethod(method);
  +                method2OperationMap.put(method, oper);
  +                return;
  +            }
  +        }
  +    }
  +
  +    /**
  +     * Fill in a service description by introspecting the implementation
  +     * class.
  +     */
  +    public void loadServiceDescByIntrospection()
  +    {
  +        Method [] methods = implClass.getDeclaredMethods();
   
           for (int i = 0; i < methods.length; i++) {
  -            String methodName = methods[i].getName();
  +            getSyncedOperationsForName(methods[i].getName());
  +        }
   
  -            // Skip it if it's not allowed
  -            // FIXME : This should, if allowedMethods is null, search up the
  -            //         inheritance/interface tree until we get to stop
  -            //         classes?
  -            if ((allowedMethods != null) &&
  -                !allowedMethods.contains(methodName))
  -                continue;
  +        // Setting this to null means there is nothing more to do, and it
  +        // avoids future string compares.
  +        completedNames = null;
  +    }
   
  -            // Make an OperationDesc for each method
  -            Method method = methods[i];
  -            OperationDesc operation = new OperationDesc();
  -            operation.setName(methodName);
  -            Class [] paramTypes = method.getParameterTypes();
  -            String [] paramNames =
  -                    JavaUtils.getParameterNamesFromDebugInfo(method);
  -            for (int k = 0; k < paramTypes.length; k++) {
  -                Class type = paramTypes[k];
  -                ParameterDesc paramDesc = new ParameterDesc();
  -                if (paramNames != null) {
  -                    paramDesc.setName(paramNames[k+1]);
  -                } else {
  -                    paramDesc.setName("in" + k);
  -                }
  -                Class heldClass = JavaUtils.getHolderValueType(type);
  -                if (heldClass != null) {
  -                    paramDesc.setMode(ParameterDesc.INOUT);
  -                    paramDesc.setTypeQName(tm.getTypeQName(heldClass));
  -                } else {
  -                    paramDesc.setMode(ParameterDesc.IN);
  -                    paramDesc.setTypeQName(tm.getTypeQName(type));
  +    /**
  +     * Fill in a service description by introspecting the implementation
  +     * class.  This version takes the implementation class and the in-scope
  +     * TypeMapping.
  +     */
  +    public void loadServiceDescByIntrospection(Class cls, TypeMapping tm)
  +    {
  +        // Should we complain if the implClass changes???
  +        implClass = cls;
  +        this.tm = tm;
  +        loadServiceDescByIntrospection();
  +    }
  +
  +    /**
  +     * Makes sure we have completely synchronized OperationDescs with
  +     * the implementation class.
  +     */
  +    private void getSyncedOperationsForName(String methodName)
  +    {
  +        // If we have no implementation class, don't worry about it (we're
  +        // probably on the client)
  +        if (implClass == null)
  +            return;
  +
  +        // If we're done introspecting, or have completed this method, return
  +        if (completedNames == null || completedNames.contains(methodName))
  +            return;
  +
  +        // Skip it if it's not a sanctioned method name
  +        if ((allowedMethods != null) &&
  +            !allowedMethods.contains(methodName))
  +            return;
  +
  +        // OK, go find any current OperationDescs for this method name and
  +        // make sure they're synced with the actual class.
  +        if (name2OperationsMap != null) {
  +            ArrayList currentOverloads = 
  +                    (ArrayList)name2OperationsMap.get(methodName);
  +            if (currentOverloads != null) {
  +                // For each one, sync it to the implementation class' methods
  +                for (Iterator i = currentOverloads.iterator(); i.hasNext();) {
  +                    OperationDesc oper = (OperationDesc) i.next();
  +                    if (oper.getMethod() == null) {
  +                        syncOperationToClass(oper);
  +                    }
                   }
  -                operation.addParameter(paramDesc);
               }
  -            addOperationDesc(operation);
           }
   
  -        hasOperationData = true;
  +        // Now all OperationDescs from deployment data have been completely
  +        // filled in.  So we now make new OperationDescs for any method
  +        // overloads which were not covered above.
  +        Method [] methods = implClass.getDeclaredMethods();
  +
  +        for (int i = 0; i < methods.length; i++) {
  +            Method method = methods[i];
  +            if (method.getName().equals(methodName))
  +                createOperationForMethod(method);
  +        }
  +
  +        // Note that we never have to look at this method name again.
  +        completedNames.add(methodName);
  +    }
  +
  +    /**
  +     * Make an OperationDesc from a Java method.
  +     *
  +     * In the absence of deployment metadata, this code will introspect a
  +     * Method and create an appropriate OperationDesc, using parameter names
  +     * from the bytecode debugging info if available, or "in0", "in1", etc.
  +     * if not.
  +     */
  +    private void createOperationForMethod(Method method) {
  +        // If we've already got it, never mind
  +        if (method2OperationMap.get(method) != null) {
  +            return;
  +        }
  +
  +        // Make an OperationDesc
  +        OperationDesc operation = new OperationDesc();
  +        operation.setName(method.getName());
  +        operation.setMethod(method);
  +        Class [] paramTypes = method.getParameterTypes();
  +        String [] paramNames =
  +                JavaUtils.getParameterNamesFromDebugInfo(method);
  +
  +        for (int k = 0; k < paramTypes.length; k++) {
  +            Class type = paramTypes[k];
  +            ParameterDesc paramDesc = new ParameterDesc();
  +            // If we have a name for this param, use it, otherwise call
  +            // it "in*"
  +            if (paramNames != null) {
  +                paramDesc.setName(paramNames[k+1]);
  +            } else {
  +                paramDesc.setName("in" + k);
  +            }
  +            paramDesc.setJavaType(type);
  +
  +            // If it's a Holder, mark it INOUT and set the type to the
  +            // held type.  Otherwise it's IN with its own type.
  +
  +            Class heldClass = JavaUtils.getHolderValueType(type);
  +            if (heldClass != null) {
  +                paramDesc.setMode(ParameterDesc.INOUT);
  +                paramDesc.setTypeQName(tm.getTypeQName(heldClass));
  +            } else {
  +                paramDesc.setMode(ParameterDesc.IN);
  +                paramDesc.setTypeQName(tm.getTypeQName(type));
  +            }
  +            operation.addParameter(paramDesc);
  +        }
  +
  +        operation.setReturnClass(method.getReturnType());
  +        operation.setReturnType(tm.getTypeQName(method.getReturnType()));
  +
  +        addOperationDesc(operation);
  +        method2OperationMap.put(method, operation);
       }
   }
  
  
  
  1.14      +78 -79    xml-axis/java/src/org/apache/axis/encoding/DefaultTypeMappingImpl.java
  
  Index: DefaultTypeMappingImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/DefaultTypeMappingImpl.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- DefaultTypeMappingImpl.java	21 Mar 2002 19:10:10 -0000	1.13
  +++ DefaultTypeMappingImpl.java	27 Mar 2002 17:53:06 -0000	1.14
  @@ -10,7 +10,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    notice, this list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in
  @@ -18,7 +18,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:  
  + *    if any, must include the following acknowledgment:
    *       "This product includes software developed by the
    *        Apache Software Foundation (http://www.apache.org/)."
    *    Alternately, this acknowledgment may appear in the software itself,
  @@ -26,7 +26,7 @@
    *
    * 4. The names "Axis" and "Apache Software Foundation" must
    *    not be used to endorse or promote products derived from this
  - *    software without prior written permission. For written 
  + *    software without prior written permission. For written
    *    permission, please contact apache@apache.org.
    *
    * 5. Products derived from this software may not be called "Apache",
  @@ -88,29 +88,29 @@
   
   /**
    * @author Rich Scheuerle (scheu@us.ibm.com)
  - * 
  + *
    * This is the implementation of the axis Default TypeMapping (which extends
    * the JAX-RPC TypeMapping interface) for SOAP 1.1.  If you want the JAX-RPC
    * SOAP 1.2 Type Mapping the use DefaultJAXRPCTypeMapping.
  - * 
  + *
    * A TypeMapping is obtained from the singleton TypeMappingRegistry using
    * the namespace of the webservice.  The TypeMapping contains the tuples
    * {Java type, SerializerFactory, DeserializerFactory, Type QName)
    *
  - * So if you have a Web Service with the namespace "XYZ", you call 
  + * So if you have a Web Service with the namespace "XYZ", you call
    * the TypeMappingRegistry.getTypeMapping("XYZ").
    *
    * The wsdl in your web service will use a number of types.  The tuple
    * information for each of these will be accessed via the TypeMapping.
    *
  - * Because every web service uses the soap, schema, wsdl primitives, we could 
  + * Because every web service uses the soap, schema, wsdl primitives, we could
    * pre-populate the TypeMapping with these standard tuples.  Instead, if requested
    * namespace/class matches is not found in the TypeMapping but matches one these
    * known primitives, the request is delegated to this Default TypeMapping.
  - * 
  + *
    */
  -public class DefaultTypeMappingImpl extends TypeMappingImpl { 
  -    
  +public class DefaultTypeMappingImpl extends TypeMappingImpl {
  +
       private static DefaultTypeMappingImpl tm = null;
       /**
        * Construct TypeMapping
  @@ -128,45 +128,45 @@
   
           // Notes:
           // 1) The registration statements are order dependent.  The last one
  -        //    wins.  So if two javaTypes of String are registered, the 
  +        //    wins.  So if two javaTypes of String are registered, the
           //    ser factory for the last one registered will be chosen.  Likewise
  -        //    if two javaTypes for XSD_DATE are registered, the deserializer 
  +        //    if two javaTypes for XSD_DATE are registered, the deserializer
           //    factory for the last one registered will be chosen.
           //    Corollary:  Please be very careful with the order.  The
           //                runtime, Java2WSDL and WSDL2Java emitters all
           //                use this code to get type mapping information.
  -        // 2) Even if the SOAP 1.1 format is used over the wire, an 
  +        // 2) Even if the SOAP 1.1 format is used over the wire, an
           //    attempt is made to receive SOAP 1.2 format from the wire.
  -        //    This is the reason why the soap encoded primitives are 
  +        //    This is the reason why the soap encoded primitives are
           //    registered without serializers.
   
  -        // SOAP Encoded strings are treated as primitives. 
  +        // SOAP Encoded strings are treated as primitives.
           // Everything else is not.
           // Note that only deserializing is supported since we are flowing
           // SOAP 1.1 over the wire.
  -        myRegister(Constants.SOAP_STRING,     java.lang.String.class,   
  -                   null, null, true,  true); 
  -        myRegister(Constants.SOAP_BOOLEAN,    java.lang.Boolean.class, 
  +        myRegister(Constants.SOAP_STRING,     java.lang.String.class,
  +                   null, null, true,  true);
  +        myRegister(Constants.SOAP_BOOLEAN,    java.lang.Boolean.class,
                      null, null, false, true);
  -        myRegister(Constants.SOAP_DOUBLE,     java.lang.Double.class,  
  +        myRegister(Constants.SOAP_DOUBLE,     java.lang.Double.class,
                      null, null, false, true);
  -        myRegister(Constants.SOAP_FLOAT,      java.lang.Float.class,  
  +        myRegister(Constants.SOAP_FLOAT,      java.lang.Float.class,
                      null, null, false, true);
  -        myRegister(Constants.SOAP_INT,        java.lang.Integer.class,   
  +        myRegister(Constants.SOAP_INT,        java.lang.Integer.class,
                      null, null, false, true);
           myRegister(Constants.SOAP_INTEGER,    java.math.BigInteger.class,
                      null, null, false, true);
           myRegister(Constants.SOAP_DECIMAL,    java.math.BigDecimal.class,
                      null, null, false, true);
  -        myRegister(Constants.SOAP_LONG,       java.lang.Long.class,     
  +        myRegister(Constants.SOAP_LONG,       java.lang.Long.class,
                      null, null, false, true);
  -        myRegister(Constants.SOAP_SHORT,      java.lang.Short.class,   
  +        myRegister(Constants.SOAP_SHORT,      java.lang.Short.class,
                      null, null, false, true);
  -        myRegister(Constants.SOAP_BYTE,       java.lang.Byte.class,     
  +        myRegister(Constants.SOAP_BYTE,       java.lang.Byte.class,
                      null, null, false, true);
   
           // Hex binary data needs to use the hex binary serializer/deserializer
  -        myRegister(Constants.XSD_HEXBIN,     Hex.class,   
  +        myRegister(Constants.XSD_HEXBIN,     Hex.class,
                      new HexSerializerFactory(
                           Hex.class, Constants.XSD_HEXBIN),
                      new HexDeserializerFactory(
  @@ -182,62 +182,62 @@
           // Byte[] -ser-> array of Byte
           // XSD_BASE64 -deser-> byte[]
           // SOAP_BASE64 -deser->byte[]
  -        myRegister(Constants.SOAP_BASE64,     byte[].class, 
  -                   new Base64SerializerFactory(byte[].class,
  +        myRegister(Constants.SOAP_BASE64,     Byte[].class,
  +                   new Base64SerializerFactory(Byte[].class,
                                                  Constants.SOAP_BASE64 ),
  -                   new Base64DeserializerFactory(byte[].class,
  +                   new Base64DeserializerFactory(Byte[].class,
                                                    Constants.SOAP_BASE64),
  -                   true, true);      
  -        myRegister(Constants.SOAP_ARRAY,     java.lang.Byte[].class,       
  -                   new ArraySerializerFactory(),
  -                   new ArrayDeserializerFactory(),true);
  -        myRegister(Constants.XSD_BASE64,     byte[].class,                                   
  +                   true);
  +//        myRegister(Constants.SOAP_ARRAY,     java.lang.Byte[].class,
  +//                   new ArraySerializerFactory(),
  +//                   new ArrayDeserializerFactory(),true);
  +        myRegister(Constants.XSD_BASE64,     byte[].class,
                      new Base64SerializerFactory(byte[].class,
                                                  Constants.XSD_BASE64 ),
                      new Base64DeserializerFactory(byte[].class,
                                              Constants.XSD_BASE64),true);
   
           // If SOAP 1.1 over the wire, map wrapper classes to XSD primitives.
  -        myRegister(Constants.XSD_STRING,     java.lang.String.class, 
  -                   null, null, true); 
  -        myRegister(Constants.XSD_BOOLEAN,    java.lang.Boolean.class, 
  +        myRegister(Constants.XSD_STRING,     java.lang.String.class,
                      null, null, true);
  -        myRegister(Constants.XSD_DOUBLE,     java.lang.Double.class,  
  +        myRegister(Constants.XSD_BOOLEAN,    java.lang.Boolean.class,
                      null, null, true);
  -        myRegister(Constants.XSD_FLOAT,      java.lang.Float.class,  
  +        myRegister(Constants.XSD_DOUBLE,     java.lang.Double.class,
                      null, null, true);
  -        myRegister(Constants.XSD_INT,        java.lang.Integer.class, 
  +        myRegister(Constants.XSD_FLOAT,      java.lang.Float.class,
  +                   null, null, true);
  +        myRegister(Constants.XSD_INT,        java.lang.Integer.class,
                      null, null, true);
           myRegister(Constants.XSD_INTEGER,    java.math.BigInteger.class,
                      null, null, true);
           myRegister(Constants.XSD_DECIMAL,    java.math.BigDecimal.class,
                      null, null, true);
  -        myRegister(Constants.XSD_LONG,       java.lang.Long.class,     
  +        myRegister(Constants.XSD_LONG,       java.lang.Long.class,
                      null, null, true);
  -        myRegister(Constants.XSD_SHORT,      java.lang.Short.class, 
  +        myRegister(Constants.XSD_SHORT,      java.lang.Short.class,
                      null, null, true);
  -        myRegister(Constants.XSD_BYTE,       java.lang.Byte.class,  
  +        myRegister(Constants.XSD_BYTE,       java.lang.Byte.class,
                      null, null, true);
   
           // The XSD Primitives are mapped to java primitives.
  -        myRegister(Constants.XSD_BOOLEAN,    boolean.class,        
  +        myRegister(Constants.XSD_BOOLEAN,    boolean.class,
                      null, null,true);
  -        myRegister(Constants.XSD_DOUBLE,     double.class,         
  +        myRegister(Constants.XSD_DOUBLE,     double.class,
                      null, null,true);
           myRegister(Constants.XSD_FLOAT,      float.class,
                      null, null,true);
  -        myRegister(Constants.XSD_INT,        int.class,  
  +        myRegister(Constants.XSD_INT,        int.class,
                      null, null,true);
  -        myRegister(Constants.XSD_LONG,       long.class, 
  +        myRegister(Constants.XSD_LONG,       long.class,
                      null, null,true);
  -        myRegister(Constants.XSD_SHORT,      short.class, 
  +        myRegister(Constants.XSD_SHORT,      short.class,
                      null, null,true);
  -        myRegister(Constants.XSD_BYTE,       byte.class, 
  +        myRegister(Constants.XSD_BYTE,       byte.class,
                      null, null,true);
   
   
           // Map QNAME to the jax rpc QName class
  -        myRegister(Constants.XSD_QNAME,      
  +        myRegister(Constants.XSD_QNAME,
                 javax.xml.rpc.namespace.QName.class,
                 new BeanSerializerFactory(javax.xml.rpc.namespace.QName.class,
                                           Constants.XSD_QNAME),
  @@ -246,21 +246,21 @@
                      true);
   
           // The closest match for anytype is Object
  -        myRegister(Constants.XSD_ANYTYPE,    java.lang.Object.class,  
  +        myRegister(Constants.XSD_ANYTYPE,    java.lang.Object.class,
                      null, null, false);
   
  -        // The xsd primitive for date has changed through the various 
  +        // The xsd primitive for date has changed through the various
           // namespace versions.
  -        // XSD_DATE is the current one, which is why it is 
  +        // XSD_DATE is the current one, which is why it is
           // registered after the other two
  -        myRegister(Constants.XSD_DATE2,      java.util.Date.class,                           
  -                   new DateSerializerFactory(java.util.Date.class, 
  +        myRegister(Constants.XSD_DATE2,      java.util.Date.class,
  +                   new DateSerializerFactory(java.util.Date.class,
                                                Constants.XSD_DATE2),
                      new DateDeserializerFactory(java.util.Date.class,
                                                  Constants.XSD_DATE2),
                      true);
  -        myRegister(Constants.XSD_DATE3,      java.util.Date.class,                           
  -                   new DateSerializerFactory(java.util.Date.class, 
  +        myRegister(Constants.XSD_DATE3,      java.util.Date.class,
  +                   new DateSerializerFactory(java.util.Date.class,
                                                Constants.XSD_DATE3),
                      new DateDeserializerFactory(java.util.Date.class,
                                                  Constants.XSD_DATE3),
  @@ -280,48 +280,47 @@
   
           // Serialize all extensions of Map to SOAP_MAP
           // The SOAP_MAP will be deserialized into a HashMap by default.
  -        myRegister(Constants.SOAP_MAP,       java.util.HashMap.class,    
  +        myRegister(Constants.SOAP_MAP,       java.util.HashMap.class,
                      new MapSerializerFactory(java.util.Map.class,
                                               Constants.SOAP_MAP),
                      new MapDeserializerFactory(java.util.HashMap.class,
                                                 Constants.SOAP_MAP),
                      false);
  -        myRegister(Constants.SOAP_MAP,       java.util.Map.class,    
  +        myRegister(Constants.SOAP_MAP,       java.util.Map.class,
                      new MapSerializerFactory(java.util.Map.class,
                                               Constants.SOAP_MAP),
  -                   new MapDeserializerFactory(java.util.HashMap.class,
  -                                              Constants.SOAP_MAP),
  +                   null,  // Make sure not to override the deser mapping
                      false);
   
           // Use the Element Serializeration for elements
  -        myRegister(Constants.SOAP_ELEMENT,   org.w3c.dom.Element.class,    
  +        myRegister(Constants.SOAP_ELEMENT,   org.w3c.dom.Element.class,
                      new ElementSerializerFactory(),
                      new ElementDeserializerFactory(), false);
  -        myRegister(Constants.SOAP_VECTOR,    java.util.Vector.class,                                
  +        myRegister(Constants.SOAP_VECTOR,    java.util.Vector.class,
                      new VectorSerializerFactory(java.util.Vector.class,
  -                                               Constants.SOAP_VECTOR), 
  +                                               Constants.SOAP_VECTOR),
                      new VectorDeserializerFactory(java.util.Vector.class,
  -                                                 Constants.SOAP_VECTOR), 
  +                                                 Constants.SOAP_VECTOR),
                      false);
   
           // All array objects automatically get associated with the SOAP_ARRAY.
  -        // There is no way to do this with a hash table, 
  +        // There is no way to do this with a hash table,
           // so it is done directly in getTypeQName.
           // Internally the runtime uses ArrayList objects to hold arrays...
  -        // which is the reason that ArrayList is associated with SOAP_ARRAY.  
  +        // which is the reason that ArrayList is associated with SOAP_ARRAY.
           // In addition, handle all objects that implement the List interface
           // as a SOAP_ARRAY
  -        myRegister(Constants.SOAP_ARRAY,     java.util.List.class,               
  +        myRegister(Constants.SOAP_ARRAY,     java.util.List.class,
                      new ArraySerializerFactory(),
  -                   new ArrayDeserializerFactory(), 
  +                   new ArrayDeserializerFactory(),
                      false);
  -        myRegister(Constants.SOAP_ARRAY,     java.util.ArrayList.class,               
  +        myRegister(Constants.SOAP_ARRAY,     java.util.ArrayList.class,
                      new ArraySerializerFactory(),
  -                   new ArrayDeserializerFactory(), 
  +                   new ArrayDeserializerFactory(),
                      false);
  -        myRegister(Constants.SOAP_ARRAY,     Object[].class,               
  +        myRegister(Constants.SOAP_ARRAY,     Object[].class,
                      new ArraySerializerFactory(),
  -                   new ArrayDeserializerFactory(), 
  +                   new ArrayDeserializerFactory(),
                      false);
       }
   
  @@ -334,14 +333,14 @@
        * @param df is the deser factory (if null, the simple factory is used)
        * @param primitive indicates whether serializers can be shared
        * @param onlyDeserFactory indicates if only deserialization is desired.
  -     */   
  +     */
       protected void myRegister(QName xmlType, Class javaType,
                                 SerializerFactory sf, DeserializerFactory df,
                                 boolean primitive) {
           myRegister(xmlType, javaType, sf, df, primitive, false);
       }
       protected void myRegister(QName xmlType, Class javaType,
  -                              SerializerFactory sf, DeserializerFactory df, 
  +                              SerializerFactory sf, DeserializerFactory df,
                                 boolean primitive, boolean onlyDeserFactory) {
   
           // If factories are not specified, use the Simple ser/deser factories.
  @@ -362,7 +361,7 @@
           if (onlyDeserFactory) {
               sf = null;
           }
  -        
  +
           // Register all known flavors of the namespace.
           try {
               if (xmlType.getNamespaceURI().equals(
  @@ -381,7 +380,7 @@
                       super.register(javaType, qName, sf, df);
                   }
               }
  -            // Register with the specified xmlType. 
  +            // Register with the specified xmlType.
               // This is the prefered mapping and the last registed one wins
               super.register(javaType, xmlType, sf, df);
           } catch (Exception e) {}
  @@ -407,10 +406,10 @@
   
       // Don't allow anyone to muck with the default type mapping because
       // it is a singleton used for the whole system.
  -    public void register(Class javaType, QName xmlType, 
  +    public void register(Class javaType, QName xmlType,
                            javax.xml.rpc.encoding.SerializerFactory sf,
  -                         javax.xml.rpc.encoding.DeserializerFactory dsf) 
  -        throws JAXRPCException {        
  +                         javax.xml.rpc.encoding.DeserializerFactory dsf)
  +        throws JAXRPCException {
   
           throw new JAXRPCException();
       }
  
  
  
  1.8       +6 -2      xml-axis/java/src/org/apache/axis/encoding/TypeMappingImpl.java
  
  Index: TypeMappingImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/TypeMappingImpl.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- TypeMappingImpl.java	22 Feb 2002 23:39:44 -0000	1.7
  +++ TypeMappingImpl.java	27 Mar 2002 17:53:06 -0000	1.8
  @@ -243,8 +243,12 @@
           }
           Pair pair = new Pair(javaType, xmlType);
   
  -        qName2Pair.put(xmlType, pair);
  -        class2Pair.put(javaType, pair);   
  +        // Only register the appropriate mappings.
  +        if ((dsf != null) || (qName2Pair.get(xmlType) == null))
  +            qName2Pair.put(xmlType, pair);
  +        if ((sf != null) || (class2Pair.get(javaType) == null))
  +            class2Pair.put(javaType, pair);   
  +        
           pair2SF.put(pair, sf);
           pair2DF.put(pair, dsf);
       }
  
  
  
  1.3       +1 -17     xml-axis/java/src/org/apache/axis/encoding/ser/SimpleDeserializerFactory.java
  
  Index: SimpleDeserializerFactory.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/SimpleDeserializerFactory.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SimpleDeserializerFactory.java	8 Mar 2002 22:26:46 -0000	1.2
  +++ SimpleDeserializerFactory.java	27 Mar 2002 17:53:06 -0000	1.3
  @@ -102,23 +102,7 @@
                       javaType.getDeclaredConstructor(new Class [] {String.class});
               }
               else {
  -                Class wrapper = null;
  -                if (javaType == int.class)
  -                    wrapper = java.lang.Integer.class;
  -                else if (javaType == short.class)
  -                    wrapper = java.lang.Short.class;
  -                else if (javaType == boolean.class)
  -                    wrapper = java.lang.Boolean.class;
  -                else if (javaType == byte.class)
  -                    wrapper = java.lang.Byte.class;
  -                else if (javaType == long.class)
  -                    wrapper = java.lang.Long.class;
  -                else if (javaType == double.class)
  -                    wrapper = java.lang.Double.class;
  -                else if (javaType == float.class)
  -                    wrapper = java.lang.Float.class;
  -                else if (javaType == char.class)
  -                    wrapper = java.lang.Character.class;
  +                Class wrapper = JavaUtils.getWrapperClass(javaType);
                   if (wrapper != null)
                       constructor = 
                           wrapper.getDeclaredConstructor(new Class [] {String.class});
  
  
  
  1.45      +28 -28    xml-axis/java/src/org/apache/axis/message/RPCElement.java
  
  Index: RPCElement.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCElement.java,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- RPCElement.java	23 Mar 2002 15:54:24 -0000	1.44
  +++ RPCElement.java	27 Mar 2002 17:53:07 -0000	1.45
  @@ -66,6 +66,7 @@
   import org.apache.axis.handlers.soap.SOAPService;
   import org.apache.axis.utils.cache.ClassCache;
   import org.apache.axis.utils.cache.JavaClass;
  +import org.apache.axis.utils.JavaUtils;
   import org.apache.axis.wsdl.toJava.Utils;
   import org.xml.sax.Attributes;
   import org.xml.sax.SAXException;
  @@ -158,36 +159,34 @@
           if (service != null) {
               ServiceDesc serviceDesc = service.getServiceDescription();
   
  -            // If we don't have a service description, create one
  -            // via introspection and cache it in the SOAPService.
  -            String clsName = (String)service.getOption("className");
  -
  -            if (clsName != null) {
  -                ClassLoader cl       = msgContext.getClassLoader();
  -                ClassCache cache     = msgContext.getAxisEngine().
  -                        getClassCache();
  -                JavaClass       jc   = null;
  -                try {
  -                    jc = cache.lookup(clsName, cl);
  -                } catch (ClassNotFoundException e) {
  -                    throw new SAXException(e);
  +            if (serviceDesc.getImplClass() == null) {
  +                String clsName = (String)service.getOption("className");
  +
  +                if (clsName != null) {
  +                    ClassLoader cl       = msgContext.getClassLoader();
  +                    ClassCache cache     = msgContext.getAxisEngine().
  +                            getClassCache();
  +                    JavaClass       jc   = null;
  +                    try {
  +                        jc = cache.lookup(clsName, cl);
  +                    } catch (ClassNotFoundException e) {
  +                        throw new SAXException(e);
  +                    }
  +                    TypeMapping tm = (TypeMapping)msgContext.
  +                            getTypeMappingRegistry().
  +                            getTypeMapping(msgContext.getEncodingStyle());
  +                    serviceDesc.setTypeMapping(tm);
  +                    serviceDesc.setImplClass(jc.getJavaClass());
                   }
  -                TypeMapping tm = (TypeMapping)msgContext.
  -                        getTypeMappingRegistry().
  -                        getTypeMapping(msgContext.getEncodingStyle());
  -                serviceDesc.loadServiceDescByIntrospection(jc.getJavaClass(),
  -                                                           tm);
               }
   
  -            if (serviceDesc != null) {
  -                // If we've got a service description now, we want to use
  -                // the matching operations in there.
  -                operations = serviceDesc.getOperationsByName(name);
  -
  -                if (operations == null) {
  -                    String lc = Utils.xmlNameToJava(name);
  -                    operations = serviceDesc.getOperationsByName(lc);
  -                }
  +            // If we've got a service description now, we want to use
  +            // the matching operations in there.
  +            operations = serviceDesc.getOperationsByName(name);
  +
  +            if (operations == null) {
  +                String lc = Utils.xmlNameToJava(name);
  +                operations = serviceDesc.getOperationsByName(lc);
               }
           }
   
  @@ -225,7 +224,8 @@
   
                           publishToHandler((org.xml.sax.ContentHandler) context);
   
  -                        // Success!!
  +                        // Success!!  This is the right one...
  +                        msgContext.setOperation(myOperation);
                           return;
                       } catch (SAXException e) {
                           // If there was a problem, try the next one.
  
  
  
  1.31      +10 -3     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.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- RPCHandler.java	22 Mar 2002 16:08:32 -0000	1.30
  +++ RPCHandler.java	27 Mar 2002 17:53:07 -0000	1.31
  @@ -193,11 +193,18 @@
   
                   if (type == null) {
                       type = paramDesc.getTypeQName();
  +                } else if (paramDesc.getJavaType() != null) {
  +                    // If we have an xsi:type, make sure it makes sense
  +                    // with the current paramDesc type
  +                    Class xsiClass = 
  +                            context.getTypeMapping().getClassForQName(type);
  +                    if (!JavaUtils.isConvertable(xsiClass,
  +                                                 paramDesc.getJavaType())) {
  +                        throw new SAXException("Bad types (" +
  +                            xsiClass + " -> " + paramDesc.getJavaType() + ")"); // FIXME!
  +                    }
                   }
               }
  -
  -            // FIXME : We should check here to make sure any specified
  -            // xsi:type jibes with the expected type in the ParamDesc!!
           }
   
   
  
  
  
  1.50      +96 -192   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.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- RPCProvider.java	22 Mar 2002 16:08:32 -0000	1.49
  +++ RPCProvider.java	27 Mar 2002 17:53:07 -0000	1.50
  @@ -73,6 +73,7 @@
   import org.apache.commons.logging.LogFactory;
   
   import javax.xml.rpc.namespace.QName;
  +import javax.xml.rpc.holders.Holder;
   import java.lang.reflect.Method;
   import java.lang.reflect.InvocationTargetException;
   import java.util.StringTokenizer;
  @@ -121,6 +122,11 @@
           for ( int bNum = 0 ; bNum < bodies.size() ; bNum++ ) {
               RPCElement   body;
   
  +            // If this is a regular old SOAPBodyElement, and it's a root,
  +            // we're probably a non-wrapped doc/lit service.  In this case,
  +            // we deserialize the element, and create an RPCElement "wrapper"
  +            // around it which points to the correct method.
  +            // FIXME : There should be a cleaner way to do this...
               if (!(bodies.get(bNum) instanceof RPCElement)) {
                   SOAPBodyElement bodyEl = (SOAPBodyElement)bodies.get(bNum);
                   if (bodyEl.isRoot() && operation != null) {
  @@ -136,20 +142,48 @@
                   body = (RPCElement) bodies.get( bNum );
               }
   
  -            String       mName      = body.getMethodName();
  -            Vector       args       = body.getParams();
  -            Object[]     argValues  =  null ;
  -
  -
  +            String methodName = body.getMethodName();
  +            Vector args = body.getParams();
  +            int numArgs = args.size();
  +
  +            // This may have changed, so get it again...
  +            // FIXME (there should be a cleaner way to do this)
  +            operation = msgContext.getOperation();
  +
  +            if (operation == null) {
  +                QName qname = new QName(body.getNamespaceURI(),
  +                                        body.getName());
  +                operation = serviceDesc.getOperationByElementQName(qname);
  +            }
  +
  +            // Create the array we'll use to hold the actual parameter
  +            // values.  We know how big to make it from the metadata.
  +            Object[]     argValues  =  new Object [operation.getNumParams()];
  +
  +            // A place to keep track of the out params (INOUTs and OUTs)
  +            ArrayList outs = new ArrayList();
  +
  +            // Put the values contained in the RPCParams into an array
  +            // suitable for passing to java.lang.reflect.Method.invoke()
  +            // Make sure we respect parameter ordering if we know about it
  +            // from metadata, and handle whatever conversions are necessary
  +            // (values -> Holders, etc)
               if ( args != null && args.size() > 0 ) {
  -                argValues = new Object[ args.size()];
  -                for ( int i = 0 ; i < args.size() ; i++ ) {
  +                for ( int i = 0 ; i < numArgs ; i++ ) {
                       RPCParam rpcParam = (RPCParam)args.get(i);
  +                    Object value = rpcParam.getValue();
                       ParameterDesc paramDesc = rpcParam.getParamDesc();
  +                    if (paramDesc != null && paramDesc.getJavaType() != null) {
  +                        value = JavaUtils.convert(value,
  +                                                  paramDesc.getJavaType());
  +                        rpcParam.setValue(value);
  +                        if (paramDesc.getMode() == ParameterDesc.INOUT)
  +                            outs.add(rpcParam);
  +                    }
                       if (paramDesc == null || paramDesc.getOrder() == -1) {
  -                        argValues[i]  = rpcParam.getValue() ;
  +                        argValues[i]  = value;
                       } else {
  -                        argValues[paramDesc.getOrder()] = rpcParam.getValue();
  +                        argValues[paramDesc.getOrder()] = value;
                       }
   
                       if (log.isDebugEnabled()) {
  @@ -160,185 +194,69 @@
               }
   
               // Check if we can find a Method by this name
  -            checkMethodName(msgContext, allowedMethods, mName);
  -
  -            // Get the actual method to invoke.
  -            int	numberOfBodyArgs = args.size();
  -            Method[] methods = getMethod(msgContext, 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 (methods == null) {
  -                mName = JavaUtils.xmlNameToJava(mName);
  -                methods = getMethod(msgContext, jc, mName);
  -            }
  -
  -            if ( methods == null )
  -                throw new AxisFault( "AxisServer.error",
  -                        JavaUtils.getMessage("noMethod00", mName, msgContext.getTargetService()),
  -                        null, null );
  -
  -            Object objRes = null;
  -            Class[] params = null;
  -            Exception ex = null;
  -
  -            // There might be more than one method with this name, try them all.
  -            int index = 0;
  -            for (index = 0; index < methods.length; index++) {
  -                Method method = methods[index];
  -                ex = null;
  -                params = method.getParameterTypes();
  -
  -                // Don't bother with this one if it has FEWER params
  -                if (argValues != null) {
  -                    if (params.length < argValues.length)
  -                        continue;
  -                }
  +            // FIXME : Shouldn't this type of thing have already occurred?
  +            checkMethodName(msgContext, allowedMethods, methodName);
   
  -                // The number of method parameters must match the
  -                // arguments taking into consideration 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 (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;
  +            // Now create any out holders we need to pass in
  +            if (numArgs < argValues.length) {
  +                ArrayList outParams = operation.getOutParams();
  +                for (int i = 0; i < outParams.size(); i++) {
  +                    ParameterDesc param = (ParameterDesc)outParams.get(i);
  +                    Class holderClass = param.getJavaType();
  +                    if (Holder.class.isAssignableFrom(holderClass)) {
  +                        argValues[numArgs + i] = holderClass.newInstance();
  +                        // Store an RPCParam in the outs collection so we
  +                        // have an easy and consistent way to write these
  +                        // back to the client below
  +                        outs.add(new RPCParam(param.getQName(),
  +                                              argValues[numArgs + i]));
                       } 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
  -                }
  -
  -                // 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 = invokeMethod(msgContext, method, 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++) {
  -                        Object thisArg = argValues[i];
  -                        if (!params[i].isAssignableFrom(thisArg.getClass())) {
  -                            // Attempt conversion for each non-assignable argument
  -                            Object newArg = JavaUtils.convert(thisArg, params[i]);
  -                            if (newArg != thisArg)
  -                                argValues[i] = newArg;
  -                        }
  -                    }
  -
  -                    // OK, now try again...
  -                    try {
  -                        objRes = invokeMethod(msgContext, method, obj, argValues);
  -                        break;
  -                    } catch (IllegalArgumentException exp) {
  -                        StringBuffer argbuf = new StringBuffer();
  -                        String sep= "";
  -                        for(int i = 0; argValues != null &&
  -                          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();
  -                        String msg = JavaUtils.getMessage("triedArgs00",
  -                                new String[] {
  -                                exp.getMessage(),
  -                                objName,
  -                                method.getName(),
  -                                argbuf.toString()});
  -                        ex = new IllegalArgumentException(msg);
  -                        continue;
  +                        // !!! Throw a fault here?
                       }
                   }
               }
  -            // 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 we've finished iterating through all the methods, throw an exception.
  -            if ( index == methods.length )
  -                throw new AxisFault( "AxisServer.error",
  -                        JavaUtils.getMessage("noMethod00", mName, msgContext.getTargetService()),
  -                        null, null );
   
  -            if (log.isDebugEnabled())
  -                log.debug(JavaUtils.getMessage("result00", "" + objRes));
  +            // OK!  Now we can invoke the method
  +            Object objRes = operation.getMethod().invoke(obj, argValues);
   
               /* Now put the result in the result SOAPEnvelope */
               /*************************************************/
  -            RPCElement resBody = new RPCElement(mName + "Response");
  +            RPCElement resBody = new RPCElement(methodName + "Response");
               resBody.setPrefix( body.getPrefix() );
               resBody.setNamespaceURI( body.getNamespaceURI() );
               resBody.setEncodingStyle(msgContext.getEncodingStyle());
   
  -            if ( objRes != null ) {
  -                // In the old skeleton a param list was returned, which
  -                // contained the RPC params.  Preserve this for now.
  -                if (objRes instanceof ParamList) {
  -                    ParamList list = (ParamList)objRes;
  -                    for (int i = 0; i < list.size (); ++i) {
  -                        if (list.get (i) instanceof RPCParam) {
  -                            resBody.addParam ((RPCParam) list.get (i));
  -                        }
  -                        else {
  -                            resBody.addParam (new RPCParam (getParameterName(obj, methods[index],i, mName),
  -                                                            list.get (i)));
  -                        }
  -                    }
  +            // Return first
  +            if ( operation.getMethod().getReturnType() != Void.TYPE ) {
  +                QName returnQName = operation.getReturnQName();
  +                if (returnQName == null) {
  +                    returnQName = new QName("", methodName + "Return");
                   }
  -                else {
  -                    QName returnQName = getReturnQName(serviceDesc, mName);
  -                    RPCParam param = new RPCParam(returnQName, objRes);
  -                    resBody.addParam(param);
  -                }
  -            } else if (methods[index].getReturnType() != Void.TYPE) {
  -                QName returnQName = getReturnQName(serviceDesc, mName);
                   RPCParam param = new RPCParam(returnQName, objRes);
                   resBody.addParam(param);
               }
   
  -            // The new skeleton (or no skeleton code) requires the runtime
  -            // to recognize holders and automatically pass back the outputs.
  -            for (int i=0; i < argValues.length; i++) {
  -                Class heldType = JavaUtils.getHolderValueType(params[i]);
  -                if (heldType != null) {
  -                    // Create an RPCParam by converting the Holder back into
  -                    // the held type.
  -                    resBody.addParam (new RPCParam (getParameterName(obj,
  -                                                                     methods[index],
  -                                                                     i,
  -                                                                     mName,
  -                                                                     args),
  -                                                    JavaUtils.convert(
  -                                                            argValues[i],
  -                                                            heldType)));
  +            // Then any other out params
  +            if (!outs.isEmpty()) {
  +                for (Iterator i = outs.iterator(); i.hasNext();) {
  +                    // We know this has a holder, so just unwrap the value
  +                    RPCParam param = (RPCParam) i.next();
  +                    Holder holder = (Holder)param.getValue();
  +                    param.setValue(JavaUtils.getHolderValue(holder));
  +                    resBody.addParam(param);
                   }
               }
   
  -            resEnv.addBodyElement( resBody );
  +            resEnv.addBodyElement(resBody);
           }
       }
   
  -    protected Method[] getMethod(MessageContext msgContext, JavaClass jc, String mName)
  +    protected Method[] getMethod(MessageContext msgContext,
  +                                 JavaClass jc,
  +                                 String methodName)
           throws Exception
       {
  -        return jc.getMethod(mName);
  +        return jc.getMethod(methodName);
       }
   
       protected Object invokeMethod(MessageContext msgContext,
  @@ -349,19 +267,21 @@
           return (method.invoke(obj, argValues));
       }
   
  -    protected void checkMethodName(MessageContext msgContext, String allowedMethods, String mName)
  +    protected void checkMethodName(MessageContext msgContext,
  +                                   String allowedMethods,
  +                                   String methodName)
           throws Exception
       {
           String methodNameMatch = allowedMethods;
   
           // allowedMethods may be a comma-delimited string of method names.
  -        // If so, look for the one matching mname.
  +        // If so, look for the one matching methodName.
           if (allowedMethods != null && allowedMethods.indexOf(' ') != -1) {
               StringTokenizer tok = new StringTokenizer(allowedMethods, " ");
               String nextMethodName = null;
               while (tok.hasMoreElements()) {
                   String token = tok.nextToken();
  -                if (token.equals(mName)) {
  +                if (token.equals(methodName)) {
                       nextMethodName = token;
                       break;
                   }
  @@ -369,27 +289,29 @@
               // didn't find a matching one...
               if (nextMethodName == null) {
                   throw new AxisFault( "AxisServer.error",
  -                        JavaUtils.getMessage("namesDontMatch00", mName, allowedMethods),
  +                        JavaUtils.getMessage("namesDontMatch00", methodName,
  +                                             allowedMethods),
                           null, null );  // should they??
               }
               methodNameMatch = nextMethodName;
           }
   
  -        if ( methodNameMatch != null && !methodNameMatch.equals(mName) )
  +        if ( methodNameMatch != null && !methodNameMatch.equals(methodName) )
               throw new AxisFault( "AxisServer.error",
                       JavaUtils.getMessage("namesDontMatch01",
  -                        new String[] {mName, methodNameMatch, allowedMethods}),
  +                        new String[] {methodName, methodNameMatch,
  +                                      allowedMethods}),
                       null, null );  // should they??
   
           if (log.isDebugEnabled()) {
  -            log.debug( "mName: " + mName );
  +            log.debug( "methodName: " + methodName );
               log.debug( "MethodNameMatch: " + methodNameMatch );
               log.debug( "MethodName List: " + allowedMethods );
           }
   
           ///////////////////////////////////////////////////////////////
           // If allowedMethods (i.e. methodNameMatch) is null,
  -        //  then treat it as a wildcard automatically matching mName
  +        //  then treat it as a wildcard automatically matching methodName
           ///////////////////////////////////////////////////////////////
           return;
       }
  @@ -402,8 +324,8 @@
       protected QName getParameterName(Object obj,
                                         Method method,
                                         int i,
  -                                      String mName) {
  -        return getParameterName(obj, method, i, mName, null);
  +                                      String methodName) {
  +        return getParameterName(obj, method, i, methodName, null);
       }
   
       /**
  @@ -416,7 +338,7 @@
       protected QName getParameterName(Object obj,
                                         Method method,
                                         int i,
  -                                      String mName,
  +                                      String methodName,
                                         Vector rpcParams) {
           QName parmName = null;
           // Emitter skeletons keep track of the parameter names
  @@ -427,28 +349,10 @@
                   if (rpcParams != null && rpcParams.size() > i) {
                       parmName = ((RPCParam)rpcParams.get(i)).getQName();
                   } else {
  -                    parmName = new QName("", mName + "Result" + i);
  +                    parmName = new QName("", methodName + "Result" + i);
                   }
               }
           }
           return parmName;
  -    }
  -
  -    protected QName getReturnQName(ServiceDesc service, String methodName)
  -    {
  -        QName ret = null;
  -
  -        if (service != null) {
  -            OperationDesc oper = service.getOperationDescByName(methodName);
  -            if (oper != null) {
  -                ret = oper.getReturnQName();
  -            }
  -        }
  -
  -        if (ret == null) {
  -            ret = new QName("", methodName + "Result");
  -        }
  -
  -        return ret;
       }
   }
  
  
  
  1.36      +109 -0    xml-axis/java/src/org/apache/axis/utils/JavaUtils.java
  
  Index: JavaUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/JavaUtils.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- JavaUtils.java	17 Mar 2002 16:25:08 -0000	1.35
  +++ JavaUtils.java	27 Mar 2002 17:53:07 -0000	1.36
  @@ -92,6 +92,50 @@
   {
       protected static Log log =
           LogFactory.getLog(JavaUtils.class.getName());
  +    
  +    public static Class getWrapperClass(Class primitive)
  +    {
  +        if (primitive == int.class)
  +            return java.lang.Integer.class;
  +        else if (primitive == short.class)
  +            return java.lang.Short.class;
  +        else if (primitive == boolean.class)
  +            return java.lang.Boolean.class;
  +        else if (primitive == byte.class)
  +            return java.lang.Byte.class;
  +        else if (primitive == long.class)
  +            return java.lang.Long.class;
  +        else if (primitive == double.class)
  +            return java.lang.Double.class;
  +        else if (primitive == float.class)
  +            return java.lang.Float.class;
  +        else if (primitive == char.class)
  +            return java.lang.Character.class;
  +        
  +        return null;
  +    }
  +    
  +    public static Class getPrimitiveClass(Class wrapper)
  +    {
  +        if (wrapper == java.lang.Integer.class)
  +            return int.class;
  +        else if (wrapper == java.lang.Short.class)
  +            return short.class;
  +        else if (wrapper == java.lang.Boolean.class)
  +            return boolean.class;
  +        else if (wrapper == java.lang.Byte.class)
  +            return byte.class;
  +        else if (wrapper == java.lang.Long.class)
  +            return long.class;
  +        else if (wrapper == java.lang.Double.class)
  +            return double.class;
  +        else if (wrapper == java.lang.Float.class)
  +            return float.class;
  +        else if (wrapper == java.lang.Character.class)
  +            return char.class;
  +        
  +        return null;
  +    }
   
       /**
        * Cache of tt-bytecode BCClass objects which correspond to particular
  @@ -132,6 +176,10 @@
           if (destClass == null) {
               return arg;
           }
  +        
  +        if (arg != null && destClass.isAssignableFrom(arg.getClass())) {
  +            return arg;
  +        }
   
           if (log.isDebugEnabled()) {
               String clsName = "null";
  @@ -294,7 +342,68 @@
           return destValue;
       }
   
  +    public static boolean isConvertable(Object obj, Class dest)
  +    {
  +        Class src = null;
  +        
  +        if (obj != null) {
  +            if (obj instanceof Class) {
  +                src = (Class)obj;
  +            } else {
  +                src = obj.getClass();
  +            }
  +        }
  +        
  +        if (dest == null)
  +            return false;
  +        
  +        if (src != null) {
  +            // If we're directly assignable, we're good.
  +            if (dest.isAssignableFrom(src))
  +                return true;
  +
  +            // If it's a wrapping conversion, we're good.
  +            if (getWrapperClass(src) == dest)
  +                return true;
  +            if (getWrapperClass(dest) == src)
  +                return true;
  +            
  +            // If it's List -> Array or vice versa, we're good.
  +            if ((List.class.isAssignableFrom(src) || src.isArray()) &&
  +                (List.class.isAssignableFrom(dest) || dest.isArray()))
  +                return true;
  +            
  +            if ((src == Hex.class && dest == byte[].class) ||
  +                (src == byte[].class && dest == Hex.class))
  +                return true;
  +            
  +        }
  +        
  +        Class destHeld = JavaUtils.getHolderValueType(dest);
  +        // Can always convert a null to an empty holder
  +        if (src == null)
  +            return (destHeld != null);
  +        
  +        if (destHeld != null) {
  +            if (destHeld.isAssignableFrom(src) || isConvertable(src, destHeld))
  +                return true;
  +        }
  +
  +//        // FIXME : This is a horrible hack put in here to deal with a problem
  +//        // with our default typemappings.
  +//        if (destHeld != null && (getPrimitiveClass(destHeld) == src))
  +//            return true;
  +
  +        // If it's holder -> held or held -> holder, we're good
  +        Class srcHeld = JavaUtils.getHolderValueType(src);
  +        if (srcHeld != null) {
  +            if (dest.isAssignableFrom(srcHeld) || isConvertable(srcHeld, dest))
  +                return true;
  +        }
   
  +        return false;
  +    }
  +    
       /**
        * These are java keywords as specified at the following URL (sorted alphabetically).
        * http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#229308
  
  
  
  1.29      +77 -26    xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaDeployWriter.java
  
  Index: JavaDeployWriter.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaDeployWriter.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- JavaDeployWriter.java	21 Mar 2002 14:28:53 -0000	1.28
  +++ JavaDeployWriter.java	27 Mar 2002 17:53:07 -0000	1.29
  @@ -87,7 +87,9 @@
       /**
        * Constructor.
        */
  -    protected JavaDeployWriter(Emitter emitter, Definition definition, SymbolTable symbolTable) {
  +    protected JavaDeployWriter(Emitter emitter, 
  +                               Definition definition, 
  +                               SymbolTable symbolTable) {
           super(emitter,
                   new QName(definition.getTargetNamespace(), "deploy"),
                   "",
  @@ -119,7 +121,8 @@
       protected void writeDeployServices() throws IOException {
           //deploy the ports on each service
           Map serviceMap = definition.getServices();
  -        for (Iterator mapIterator = serviceMap.values().iterator(); mapIterator.hasNext();) {
  +        for (Iterator mapIterator = serviceMap.values().iterator(); 
  +             mapIterator.hasNext();) {
               Service myService = (Service) mapIterator.next();
   
               pw.println();
  @@ -128,9 +131,12 @@
                       + " -->");
               pw.println();
   
  -            for (Iterator portIterator = myService.getPorts().values().iterator(); portIterator.hasNext();) {
  +            for (Iterator portIterator = myService.getPorts().values().iterator();
  +                 portIterator.hasNext();) {
                   Port myPort = (Port) portIterator.next();
  -                BindingEntry bEntry =  symbolTable.getBindingEntry(myPort.getBinding().getQName());
  +                BindingEntry bEntry = 
  +                        symbolTable.getBindingEntry(
  +                                myPort.getBinding().getQName());
   
                   // If this isn't an SOAP binding, skip it
                   if (bEntry.getBindingType() != BindingEntry.TYPE_SOAP) {
  @@ -177,7 +183,8 @@
               if (localPart.startsWith(SymbolTable.ANON_TOKEN)) {
                   localPart = localPart.substring(1);
               }
  -            QName qName = new QName(type.getQName().getNamespaceURI(), localPart);
  +            QName qName = new QName(type.getQName().getNamespaceURI(), 
  +                                    localPart);
   
               if (process) {
                   pw.println("      <typeMapping");
  @@ -276,30 +283,64 @@
               // interested in the return type for now.
               Parameters params =
                       symbolTable.getOperationParameters(operation, "", bEntry);
  -            if (params.returnType instanceof DefinedElement) {
  -                QName returnQName = params.returnType.getQName();
  -                pw.println("      <operation name=\"" + operation.getName() +
  -                         "\" returnQName=\"retNS:" +
  -                         returnQName.getLocalPart() +
  -                         "\" xmlns:retNS=\"" +
  -                         returnQName.getNamespaceURI() +
  -                         "\">");
  -
  -                // map doc/lit elements to this operation
  -                Map parts = operation.getInput().getMessage().getParts();
  -                if (!parts.isEmpty()) {
  -                    Iterator i = parts.values().iterator();
  -                    Part p = (Part) i.next();
  -                    QName elementQName = p.getElementName();
  -                    String ns = elementQName.getNamespaceURI();
  -                    pw.println("        <elementMapping xmlns:ns=\"" +
  -                            ns + "\" element=\"ns:" +
  -                            elementQName.getLocalPart() + "\"/>");
  +            String operName = JavaUtils.xmlNameToJava(operation.getName());
  +            if (params != null) {
  +                if (params.returnType instanceof DefinedElement) {
  +                    QName returnQName = params.returnType.getQName();
  +                    pw.println("      <operation name=\"" + operName +
  +                             "\" returnQName=\"retNS:" +
  +                             returnQName.getLocalPart() +
  +                             "\" xmlns:retNS=\"" +
  +                             returnQName.getNamespaceURI() +
  +                             "\">");
  +
  +                    // map doc/lit elements to this operation
  +                    Map parts = operation.getInput().getMessage().getParts();
  +                    if (!parts.isEmpty()) {
  +                        Iterator i = parts.values().iterator();
  +                        Part p = (Part) i.next();
  +                        QName elementQName = p.getElementName();
  +                        String ns = elementQName.getNamespaceURI();
  +                        pw.println("        <elementMapping xmlns:ns=\"" +
  +                                   ns + "\" element=\"ns:" +
  +                                   elementQName.getLocalPart() + "\"/>");
  +                    }
  +                } else {
  +                    pw.println("      <operation name=\"" + 
  +                               operName + "\">");
                   }
  -
  +                
  +                Vector paramList = params.list;
  +                for (int i = 0; i < paramList.size(); i++) {
  +                    Parameter param = (Parameter) paramList.elementAt(i);
  +                    QName paramQName = param.getQName();
  +                    TypeEntry typeEntry = param.getType();
  +                    QName paramType;
  +                    if (typeEntry instanceof DefinedElement) {
  +                        Node node = symbolTable.getTypeEntry(typeEntry.getQName(), true).getNode();
  +                        paramType = Utils.getNodeTypeRefQName(node, "type");
  +                        if (paramType == null)
  +                            paramType = typeEntry.getQName(); // FIXME
  +                    } else {
  +                        paramType = typeEntry.getQName();
  +                    }
  +                    String mode = getModeString(param.getMode());
  +                    pw.print("        <parameter ");
  +                    if (paramQName == null || "".equals(paramQName.getLocalPart())) {
  +                        pw.print("name=\"" + param.getName() + "\" " );
  +                    } else {
  +                        pw.print("qname=\"pns:" + paramQName.getLocalPart() +
  +                                 "\" xmlns:pns=\"" + paramQName.getNamespaceURI() +
  +                                 "\" ");
  +                    }
  +                    pw.print("type=\"tns:" + paramType.getLocalPart() + "\" " );
  +                    pw.print("xmlns:tns=\"" + paramType.getNamespaceURI() + "\" " );
  +                    pw.print("mode=\"" + mode + "\"" );
  +                    pw.println("/>");
  +                }
  +                
                   pw.println("      </operation>");
               }
  -
           }
   
           pw.print("      <parameter name=\"allowedMethods\" value=\"");
  @@ -321,4 +362,14 @@
           }
       } //writeDeployBinding
   
  +    public String getModeString(byte mode)
  +    {
  +        if (mode == Parameter.IN) {
  +            return "IN";
  +        } else if (mode == Parameter.INOUT) {
  +            return "INOUT";
  +        } else {
  +            return "OUT";
  +        }
  +    }
   } // class JavaDeployWriter
  
  
  
  1.34      +29 -11    xml-axis/java/test/RPCDispatch/TestRPC.java
  
  Index: TestRPC.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/RPCDispatch/TestRPC.java,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- TestRPC.java	20 Feb 2002 18:59:22 -0000	1.33
  +++ TestRPC.java	27 Mar 2002 17:53:07 -0000	1.34
  @@ -6,6 +6,8 @@
   import org.apache.axis.Handler;
   import org.apache.axis.Message;
   import org.apache.axis.MessageContext;
  +import org.apache.axis.encoding.TypeMapping;
  +import org.apache.axis.description.ServiceDesc;
   import org.apache.axis.providers.java.RPCProvider;
   import org.apache.axis.configuration.SimpleProvider;
   import org.apache.axis.handlers.soap.SOAPService;
  @@ -76,11 +78,7 @@
           envelope.addBodyElement(body);
   
           // Invoke the Axis engine
  -        try {
  -            engine.invoke(msgContext);
  -        } catch (AxisFault af) {
  -            return af;
  -        }
  +        engine.invoke(msgContext);
   
           // Extract the response Envelope
           Message message = msgContext.getResponseMessage();
  @@ -110,6 +108,9 @@
           reverse.setOption("className", "test.RPCDispatch.Service");
           reverse.setOption("allowedMethods", "reverseString");
           provider.deployService(new QName(null,SOAPAction), reverse);
  +        ServiceDesc serviceDesc = reverse.getServiceDescription();
  +        serviceDesc.loadServiceDescByIntrospection(test.RPCDispatch.Service.class,
  +                                                   (TypeMapping)reverse.getTypeMappingRegistry().getDefaultTypeMapping());
   
           // invoke the service and verify the result
           assertEquals("Did not reverse the string correctly.", "cba", rpc("reverseString", new Object[] {"abc"}));
  @@ -124,6 +125,9 @@
           reverse.setOption("className", "test.RPCDispatch.Service");
           reverse.setOption("allowedMethods", "reverseData");
           provider.deployService(new QName(null, SOAPAction), reverse);
  +        ServiceDesc serviceDesc = reverse.getServiceDescription();
  +        serviceDesc.loadServiceDescByIntrospection(test.RPCDispatch.Service.class,
  +                                                   (TypeMapping)reverse.getTypeMappingRegistry().getDefaultTypeMapping());
   
           // invoke the service and verify the result
           Data input    = new Data(5, "abc", 3);
  @@ -140,6 +144,9 @@
           tgtSvc.setOption("className", "test.RPCDispatch.Service");
           tgtSvc.setOption("allowedMethods", "targetServiceImplicit");
           provider.deployService(new QName(null, SOAPAction), tgtSvc);
  +        ServiceDesc serviceDesc = tgtSvc.getServiceDescription();
  +        serviceDesc.loadServiceDescByIntrospection(test.RPCDispatch.Service.class,
  +                                                   (TypeMapping)tgtSvc.getTypeMappingRegistry().getDefaultTypeMapping());
   
           // invoke the service and verify the result
           assertEquals("SOAP Action did not equal the targetService.", 
  @@ -155,6 +162,9 @@
           echoInt.setOption("className", "test.RPCDispatch.Service");
           echoInt.setOption("allowedMethods", "echoInt");
           provider.deployService(new QName(null, SOAPAction), echoInt);
  +        ServiceDesc serviceDesc = echoInt.getServiceDescription();
  +        serviceDesc.loadServiceDescByIntrospection(test.RPCDispatch.Service.class,
  +                                                   (TypeMapping)echoInt.getTypeMappingRegistry().getDefaultTypeMapping());
   
           // invoke the service and verify the result
           assertNull("The result was not null as expected.", rpc("echoInt", new Object[] {null}));
  @@ -169,13 +179,20 @@
           simpleFault.setOption("className", "test.RPCDispatch.Service");
           simpleFault.setOption("allowedMethods", "simpleFault");
           provider.deployService(new QName(null, SOAPAction), simpleFault);
  +        ServiceDesc serviceDesc = simpleFault.getServiceDescription();
  +        serviceDesc.loadServiceDescByIntrospection(test.RPCDispatch.Service.class,
  +                                                   (TypeMapping)simpleFault.getTypeMappingRegistry().getDefaultTypeMapping());
  +
  +        try {
  +            rpc("simpleFault", new Object[] {"foobar"});
  +        } catch (AxisFault result) {
  +            assertEquals("faultString was not set correctly.",
  +                "test.RPCDispatch.Service$TestFault: foobar",
  +                result.getFaultString());
  +            return;
  +        }
   
  -        Object result = rpc("simpleFault", new Object[] {"foobar"});
  -        assertTrue("Did not get a fault as expected.", 
  -           result instanceof AxisFault);
  -        AxisFault fault = (AxisFault) result;
  -        assertEquals("faultString was not set correctly.", 
  -            "test.RPCDispatch.Service$TestFault: foobar", fault.getFaultString());
  +        fail("Did not get an expected fault!");
       }
   
       public static void main(String args[])
  @@ -184,6 +201,7 @@
           TestRPC tester = new TestRPC("RPC test");
           tester.testReverseString();
           tester.testReverseData();
  +          tester.testSimpleFault();
         } catch (Exception e) {
           e.printStackTrace();
         }
  
  
  
  1.31      +1 -1      xml-axis/java/test/RPCDispatch/TestSerializedRPC.java
  
  Index: TestSerializedRPC.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/RPCDispatch/TestSerializedRPC.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- TestSerializedRPC.java	23 Mar 2002 15:54:25 -0000	1.30
  +++ TestSerializedRPC.java	27 Mar 2002 17:53:07 -0000	1.31
  @@ -83,7 +83,7 @@
           // be testing parameter dispatch by name, so if debug info isn't
           // compiled into the Service class, the names are going to be "in0",
           // etc.  Make sure they match.
  -        OperationDesc oper = desc.getOperationDescByName("concatenate");
  +        OperationDesc oper = desc.getOperationByName("concatenate");
           assertNotNull(oper);
           
           firstParamName = oper.getParameter(0).getName();
  
  
  
  1.22      +12 -9     xml-axis/java/test/encoding/TestSer.java
  
  Index: TestSer.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/encoding/TestSer.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- TestSer.java	21 Feb 2002 04:28:27 -0000	1.21
  +++ TestSer.java	27 Mar 2002 17:53:07 -0000	1.22
  @@ -33,8 +33,7 @@
       public static void main(String [] args) throws Exception
       {
           TestSer tester = new TestSer("TestSer");
  -        tester.testDataNoHrefs();
  -        tester.testDataWithHrefs();
  +        tester.testRPCElement();
       }
       
       public TestSer(String name) {
  @@ -105,14 +104,18 @@
       /**
        * Test RPC element serialization when we have no MessageContext
        */
  -    public void testRPCElement() throws Exception
  +    public void testRPCElement()
       {
  -        SOAPEnvelope env = new SOAPEnvelope();
  -        RPCElement method = new RPCElement("ns",
  -                                           "method",
  -                                           new Object [] { "argument" });
  -        env.addBodyElement(method);
  -        String soapStr = env.toString();
  +        try {
  +            SOAPEnvelope env = new SOAPEnvelope();
  +            RPCElement method = new RPCElement("ns",
  +                                               "method",
  +                                               new Object [] { "argument" });
  +            env.addBodyElement(method);
  +            String soapStr = env.toString();
  +        } catch (Exception e) {
  +            fail(e.getMessage());
  +        }
   
           // If there was no exception, we succeeded in serializing it.
       }
  
  
  
  1.4       +1 -1      xml-axis/java/test/wsdl/marrays/MArrayTestsSOAPBindingImpl.java
  
  Index: MArrayTestsSOAPBindingImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/wsdl/marrays/MArrayTestsSOAPBindingImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MArrayTestsSOAPBindingImpl.java	12 Feb 2002 16:50:20 -0000	1.3
  +++ MArrayTestsSOAPBindingImpl.java	27 Mar 2002 17:53:07 -0000	1.4
  @@ -42,7 +42,7 @@
           }
           return in;
       }
  -    public java.util.Map testMapFooArray(java.util.Map map)
  +    public java.util.HashMap testMapFooArray(java.util.HashMap map)
           throws java.rmi.RemoteException {
           return map;
       }
  
  
  
  1.7       +1 -1      xml-axis/java/test/wsdl/marrays/MArrayTestsServiceTestCase.java
  
  Index: MArrayTestsServiceTestCase.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/wsdl/marrays/MArrayTestsServiceTestCase.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- MArrayTestsServiceTestCase.java	12 Feb 2002 16:50:20 -0000	1.6
  +++ MArrayTestsServiceTestCase.java	27 Mar 2002 17:53:07 -0000	1.7
  @@ -131,7 +131,7 @@
   
           try {
               // Test 3F: Some of the Foo elements are multi-referenced.   
  -            Map map = new HashMap();
  +            HashMap map = new HashMap();
               Foo[] array = new Foo[1];
               array[0] = new Foo();
               array[0].setValue(123);