You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by di...@apache.org on 2005/08/01 05:16:45 UTC

cvs commit: ws-axis/java/src/org/apache/axis/encoding TypeMappingImpl.java

dims        2005/07/31 20:16:45

  Modified:    java/src/org/apache/axis/wsdl/symbolTable
                        CollectionType.java SymbolTable.java Utils.java
               java/src/org/apache/axis/wsdl/toJava JavaHolderWriter.java
                        JavaStubWriter.java Utils.java
               java/src/org/apache/axis/encoding TypeMappingImpl.java
  Added:       java/test/wsdl/wrapperHolder2 bug2102.wsdl build.xml
                        ExampleSoapImpl.java ExampleSoapTestCase.java
  Log:
  Fix and test case for AXIS-2102 - wsdl2java does not generate wrappers for nillable parameters
  
  from Hans (hplanting@mail.com)
  
  Revision  Changes    Path
  1.1                  ws-axis/java/test/wsdl/wrapperHolder2/bug2102.wsdl
  
  Index: bug2102.wsdl
  ===================================================================
  <?xml version="1.0" ?>
  
  <definitions name="urn:AddressFetcher"
               targetNamespace="urn:wrapperHolder2"
               xmlns:tns="urn:wrapperHolder2"
               xmlns:typens="urn:wrapperHolder2"
               xmlns:xsd="http://www.w3.org/1999/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
               xmlns="http://schemas.xmlsoap.org/wsdl/">
  
  <types>
  <schema attributeFormDefault="qualified" elementFormDefault="qualified"
    targetNamespace="urn:wrapperHolder2"
     xmlns="http://www.w3.org/1999/XMLSchema">
  
    <element name="out" type="xsd:long"/>
    <element name="DoExample">
      <complexType>
        <sequence>
          <element name="value1" nillable="true" maxOccurs="unbounded" type="xsd:base64Binary"/>
          <element name="value2" minOccurs="0" maxOccurs="1"  ref="typens:out"/>
        </sequence>
      </complexType>
    </element>
  
    <element name="DoExampleResponse">
      <complexType>
        <sequence>
          <element name="val1" nillable="true" maxOccurs="unbounded" type="xsd:base64Binary"/>
          <element name="val2" minOccurs="0" maxOccurs="unbounded" ref="typens:out"/>
          <element name="val3" nillable="true" maxOccurs="unbounded" type="xsd:int"/>
          <element name="val4" maxOccurs="unbounded" type="xsd:int"/>
          <element name="val5" maxOccurs="unbounded" type="xsd:byte"/>
        </sequence>
      </complexType>
    </element>
  
  </schema>
  </types>
  
  <message name="DoExample">
    <part name="body" element="typens:DoExample"/>
  </message>
  <message name="DoExampleResponse">
    <part name="result" element="typens:DoExampleResponse"/>
  </message>
  
  <portType name="ExampleSoap">
    <operation name="DoExample" parameterOrder="body result">
      <input message="tns:DoExample"/>
      <output message="tns:DoExampleResponse"/>
    </operation>
  </portType>
  
  <binding name="ExampleSoap" type="tns:ExampleSoap">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="DoExample">
      <soap:operation soapAction="" style="document"/>
      <input>
        <soap:body use="literal" parts="body" />
      </input>
      <output >
        <soap:body use="literal" parts="result" />
      </output>
    </operation>
  </binding>
  
  <service name="DoExample">
    <port name="WrapperHolder2" binding="tns:ExampleSoap">
      <soap:address location="http://localhost:8080/axis/services/WrapperHolder2"/>
    </port>
  </service>
  
  </definitions>
  
  
  
  1.1                  ws-axis/java/test/wsdl/wrapperHolder2/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0" ?>
  <!DOCTYPE project [
          <!ENTITY properties SYSTEM "file:../../../xmls/properties.xml">
          <!ENTITY paths  SYSTEM "file:../../../xmls/path_refs.xml">
          <!ENTITY taskdefs SYSTEM "file:../../../xmls/taskdefs.xml">
          <!ENTITY taskdefs_post_compile SYSTEM "file:../../../xmls/taskdefs_post_compile.xml">
          <!ENTITY targets SYSTEM "file:../../../xmls/targets.xml">
  ]>
  
  <!-- ===================================================================
  <description>
     This is a test case to accompany the fix for Bug 1191.
  
  Notes:
     This is a build file for use with the Jakarta Ant build tool.
  
  Prerequisites:
  
     jakarta-ant from http://jakarta.apache.org
  
  Build Instructions:
     To compile
          ant compile
     To execute
          ant run
  
  Copyright:
    Copyright (c) 2002-2004 Apache Software Foundation.
  </description>
  ==================================================================== -->
  
  <project default="compile">
  
  <property name="axis.home" location="../../.."/>
  <property name="componentName" value="test/wsdl/wrapperHolder2"/>
  <property name="packageName" value="test.wsdl.wrapperHolder2"/>
          &properties;
          &paths;
          &taskdefs;
          &taskdefs_post_compile;
          &targets;
  
  <target name="clean">
      <echo message="Removing ${build.dir}/classes/${componentName} and ${build.dir}/work/${componentName}" />
      <delete dir="${build.dir}/classes/${componentName}"/>
      <delete dir="${build.dir}/work/${componentName}"/>
      <delete dir="${build.dir}/work/holders"/>
      <delete dir="${build.dir}/classes/holders"/>
  </target>
  
  <target name="copy" depends="setenv"/>
  
  <target name="compile" depends="copy">
    <echo message="Compiling ${packageName}"/>
      <!-- Wrapped Sample Test -->
      <wsdl2java url="${axis.home}/${componentName}/bug2102.wsdl"
                 output="${axis.home}/build/work"
                 serverSide="yes"
                 skeletonDeploy="no"
                 testcase="no">
          <mapping namespace="urn:wrapperHolder2" package="${packageName}"/>
      </wsdl2java>
  
      <copy todir="${build.dir}/work/${componentName}" overwrite="yes">
        <fileset dir="${axis.home}/${componentName}">
          <include name="*TestCase.java"/>
          <include name="*Impl.java"/>
        </fileset>
      </copy>
  
      <javac srcdir="${build.dir}/work" destdir="${build.dest}" nowarn="${nowarn}" source="${source}" fork="${javac.fork}"
             debug="${debug}">
        <classpath refid="classpath" />
        <include name="${componentName}/*.java" />
      </javac>
  
  </target>
  
  <target name="run" >
    <antcall target="execute-Component" />
  </target>
  
  </project>
  
  
  
  1.1                  ws-axis/java/test/wsdl/wrapperHolder2/ExampleSoapImpl.java
  
  Index: ExampleSoapImpl.java
  ===================================================================
  /**
   * ExampleSoapImpl.java
   *
   * Verifies that wrapped operations featuring Java wrapper array types are working.
   */
  
  package test.wsdl.wrapperHolder2;
  
  public class ExampleSoapImpl implements test.wsdl.wrapperHolder2.ExampleSoap {
      public void doExample(byte[][] value1, java.lang.Long value2, holders.ByteArrayArrayHolder val1, test.wsdl.wrapperHolder2.holders.OutArrayHolder val2, holders.IntArrayWrapperHolder val3, holders.IntArrayHolder val4, holders.ByteArrayHolder val5) throws java.rmi.RemoteException {
  
          val1.value = value1;
          val2.value = new long[] { 1, 2, 3 };
          val3.value = new Integer[] { new Integer(4), new Integer(5) };
          val4.value = new int[] { 6, 7, 8 };
          val5.value = new byte[] { (byte)0x9, (byte)0x10 };
      }
  }
  
  
  
  1.1                  ws-axis/java/test/wsdl/wrapperHolder2/ExampleSoapTestCase.java
  
  Index: ExampleSoapTestCase.java
  ===================================================================
  package test.wsdl.wrapperHolder2;
  
  import javax.xml.rpc.holders.ByteArrayHolder;
  import javax.xml.rpc.holders.LongWrapperHolder;
  
  public class ExampleSoapTestCase extends junit.framework.TestCase {
      public ExampleSoapTestCase(java.lang.String name) {
          super(name);
      }
  
      public void testWrapperHolder2WSDL() throws Exception {
          javax.xml.rpc.ServiceFactory serviceFactory = javax.xml.rpc.ServiceFactory.newInstance();
          java.net.URL url = new java.net.URL(new test.wsdl.wrapperHolder2.DoExample_ServiceLocator().getWrapperHolder2Address() + "?WSDL");
          javax.xml.rpc.Service service = serviceFactory.createService(url, new test.wsdl.wrapperHolder2.DoExample_ServiceLocator().getServiceName());
          assertTrue(service != null);
      }
  
      public void test1WrapperHolder2DoExample() throws Exception {
          test.wsdl.wrapperHolder2.ExampleSoapStub binding;
          try {
              binding = (test.wsdl.wrapperHolder2.ExampleSoapStub)
                            new test.wsdl.wrapperHolder2.DoExample_ServiceLocator().getWrapperHolder2();
          }
          catch (javax.xml.rpc.ServiceException jre) {
              if(jre.getLinkedCause()!=null)
                  jre.getLinkedCause().printStackTrace();
              throw new junit.framework.AssertionFailedError("JAX-RPC ServiceException caught: " + jre);
          }
          assertNotNull("binding is null", binding);
  
          // Time out after a minute
          binding.setTimeout(60000);
  
          byte[][]           in1  = new byte[][]  {
              {   (byte) 0xbe,  (byte) 0xef,  (byte) 0xcc   },
              {   (byte) 0xee,  (byte) 0xff,  (byte) 0xaa   },
          };
          Long in2  = new Long(3);
          holders.ByteArrayArrayHolder val1 = new holders.ByteArrayArrayHolder();
          test.wsdl.wrapperHolder2.holders.OutArrayHolder val2 = new test.wsdl.wrapperHolder2.holders.OutArrayHolder();
          holders.IntArrayWrapperHolder val3 = new holders.IntArrayWrapperHolder();
          holders.IntArrayHolder val4 = new holders.IntArrayHolder();
          holders.ByteArrayHolder val5 = new holders.ByteArrayHolder();
  
          // Test operation
          binding.doExample(in1, in2, val1, val2, val3, val4, val5);
  
          assertEquals("Unexpected value for holders.ByteArrayArrayHolder",
                       byteArrayAsList(in1[0]), byteArrayAsList(val1.value[0]));
          assertEquals("Unexpected value for test.wsdl.WrapperHolder.holders.OutArrayHolder",
                       val2.value[0], 1);
          assertEquals("Unexpected value for holders.IntArrayWrapperHolder",
                       val3.value[0].intValue(), 4);
          assertEquals("Unexpected value for holders.IntArrayHolder",
                       val4.value[0], 6);
          assertEquals("Unexpected value for holders.ByteArrayHolder",
                       val5.value[0], (byte)0x9);
      }
  
      private static java.util.List  byteArrayAsList(final byte[] a) {
          return new java.util.AbstractList() {
              public Object get(int i) {
                  return new Byte(a[i]);
              }
              public int size() {
                  return a.length;
              }
              public Object set(int i, Object o) {
                  byte oldVal = a[i];
                  a[i] = ((Byte) o).byteValue();
                  return new Byte(oldVal);
              }
          };
      }
  }
  
  
  
  1.7       +9 -1      ws-axis/java/src/org/apache/axis/wsdl/symbolTable/CollectionType.java
  
  Index: CollectionType.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/wsdl/symbolTable/CollectionType.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- CollectionType.java	25 Feb 2004 14:02:50 -0000	1.6
  +++ CollectionType.java	1 Aug 2005 03:16:44 -0000	1.7
  @@ -29,6 +29,9 @@
    */
   public class CollectionType extends DefinedType implements CollectionTE {
   
  +    /** Field wrapped */
  +    private boolean wrapped;
  +
       /**
        * Constructor CollectionType
        * 
  @@ -38,7 +41,12 @@
        * @param dims    
        */
       public CollectionType(QName pqName, TypeEntry refType, Node pNode,
  -                          String dims) {
  +                          String dims, boolean wrapped) {
           super(pqName, refType, pNode, dims);
  +        this.wrapped = wrapped;
  +    }
  +
  +    public boolean isWrapped() {
  +        return wrapped;
       }
   }
  
  
  
  1.127     +2 -1      ws-axis/java/src/org/apache/axis/wsdl/symbolTable/SymbolTable.java
  
  Index: SymbolTable.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/wsdl/symbolTable/SymbolTable.java,v
  retrieving revision 1.126
  retrieving revision 1.127
  diff -u -r1.126 -r1.127
  --- SymbolTable.java	29 Jul 2005 03:28:43 -0000	1.126
  +++ SymbolTable.java	1 Aug 2005 03:16:44 -0000	1.127
  @@ -1363,8 +1363,9 @@
   
                           symbolTablePut(containedTE);
                       }
  +                    boolean wrapped = qName.getLocalPart().endsWith("wrapped");
                       symbolTablePut(new CollectionType(qName, containedTE,
  -                            node, "[]"));
  +                            node, "[]", wrapped));
                   } else {
   
                       // Case of ref and maxOccurs
  
  
  
  1.48      +5 -1      ws-axis/java/src/org/apache/axis/wsdl/symbolTable/Utils.java
  
  Index: Utils.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/wsdl/symbolTable/Utils.java,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- Utils.java	18 Jul 2005 11:35:47 -0000	1.47
  +++ Utils.java	1 Aug 2005 03:16:44 -0000	1.48
  @@ -319,6 +319,7 @@
               if (qName != null) {
                   String maxOccursValue = getAttribute(node, "maxOccurs");
                   String minOccursValue = getAttribute(node, "minOccurs");
  +                String nillableValue = getAttribute(node, "nillable");
   
                   if (maxOccursValue == null) {
                       maxOccursValue = "1";
  @@ -336,6 +337,9 @@
                   } else if (!maxOccursValue.equals("1")
                           || !minOccursValue.equals("1")) {
                       String localPart = qName.getLocalPart();
  +                    String wrapped = (nillableValue != null && nillableValue.equals("true") 
  +                        ? " wrapped" : "");
  +
                       String range = "[";
                       if (!minOccursValue.equals("1")) {
                           range += minOccursValue;
  @@ -345,7 +349,7 @@
                           range += maxOccursValue;
                       }
                       range += "]";
  -                    localPart += range;
  +                    localPart += range + wrapped;
                       qName = findQName(qName.getNamespaceURI(), localPart);
                   }
               }
  
  
  
  1.20      +12 -1     ws-axis/java/src/org/apache/axis/wsdl/toJava/JavaHolderWriter.java
  
  Index: JavaHolderWriter.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/wsdl/toJava/JavaHolderWriter.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- JavaHolderWriter.java	21 Mar 2005 12:37:20 -0000	1.19
  +++ JavaHolderWriter.java	1 Aug 2005 03:16:45 -0000	1.20
  @@ -15,7 +15,9 @@
    */
   package org.apache.axis.wsdl.toJava;
   
  +import org.apache.axis.wsdl.symbolTable.CollectionType;
   import org.apache.axis.wsdl.symbolTable.TypeEntry;
  +import org.apache.axis.wsdl.symbolTable.Parameter;
   
   import java.io.IOException;
   import java.io.PrintWriter;
  @@ -68,7 +70,16 @@
       protected void writeFileBody(PrintWriter pw) throws IOException {
   
           String holderType = type.getName();
  -
  +        if ((type instanceof CollectionType 
  +                && ((CollectionType) type).isWrapped())
  +             || type.getUnderlTypeNillable()) {
  +            /*
  +             * For soapenc arrays or elements with maxOccurs="unbounded"
  +             * having a primitive type and nillable="true" the holderType 
  +             * should be the corresponding wrapped type.
  +             */
  +            holderType = Utils.getWrapperType(type);
  +        }
           pw.println("    public " + holderType + " value;");
           pw.println();
           pw.println("    public " + className + "() {");
  
  
  
  1.154     +4 -1      ws-axis/java/src/org/apache/axis/wsdl/toJava/JavaStubWriter.java
  
  Index: JavaStubWriter.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/wsdl/toJava/JavaStubWriter.java,v
  retrieving revision 1.153
  retrieving revision 1.154
  diff -u -r1.153 -r1.154
  --- JavaStubWriter.java	30 Jun 2005 20:09:17 -0000	1.153
  +++ JavaStubWriter.java	1 Aug 2005 03:16:45 -0000	1.154
  @@ -23,6 +23,7 @@
   import org.apache.axis.utils.JavaUtils;
   import org.apache.axis.utils.StringUtils;
   import org.apache.axis.wsdl.symbolTable.BindingEntry;
  +import org.apache.axis.wsdl.symbolTable.CollectionType;
   import org.apache.axis.wsdl.symbolTable.DefinedType;
   import org.apache.axis.wsdl.symbolTable.FaultInfo;
   import org.apache.axis.wsdl.symbolTable.Parameter;
  @@ -1325,9 +1326,11 @@
           if ((type != null) && (type.getName() != null)) {
   
               String typeName = type.getName();
  -	        // If minOccurs="0" and singular or array with nillable underlying
  +            // If minOccurs="0" and singular or array with nillable underlying
               // type get the corresponding wrapper type.
               if ((param.isOmittable() && param.getType().getDimensions().equals(""))
  +                || (param.getType() instanceof CollectionType
  +                    && ((CollectionType) param.getType()).isWrapped())
                   || param.getType().getUnderlTypeNillable()) {
   
                   typeName = Utils.getWrapperType(type);
  
  
  
  1.97      +46 -23    ws-axis/java/src/org/apache/axis/wsdl/toJava/Utils.java
  
  Index: Utils.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/wsdl/toJava/Utils.java,v
  retrieving revision 1.96
  retrieving revision 1.97
  diff -u -r1.96 -r1.97
  --- Utils.java	13 Jun 2005 02:19:52 -0000	1.96
  +++ Utils.java	1 Aug 2005 03:16:45 -0000	1.97
  @@ -69,6 +69,7 @@
           arg.setType(type);
           return holder(arg, emitter);
       }
  +
       /**
        * Given a type, return the Java mapping of that type's holder.
        *
  @@ -109,19 +110,20 @@
   
           TypeEntry type = p.getType();
           String typeValue = type.getName();
  +
           // For base types that are nillable and are mapped to primitives,
           // need to switch to the corresponding wrapper types.
  -        if (p.isOmittable()
  -            &&  (type instanceof BaseType
  -                 ||  type instanceof DefinedElement
  -                     &&  type.getRefType() instanceof BaseType)) {
  -            String wrapperTypeValue = (String) TYPES.get(typeValue);
  -            typeValue = wrapperTypeValue == null  ?  typeValue
  -                                                  :  wrapperTypeValue;
  +        if ((p.isOmittable() && p.getType().getDimensions().equals(""))
  +            || (p.getType() instanceof CollectionType && ((CollectionType) p.getType()).isWrapped()) 
  +            || p.getType().getUnderlTypeNillable()) {
  +
  +            typeValue = getWrapperType(type);
           }
   
  -        // byte[] has a reserved holders
  -        if (typeValue.equals("byte[]") && type.isBaseType()) {
  +
  +        // byte[] has a reserved holders.
  +        if (typeValue.equals("byte[]") &&  type.isBaseType()) { 
  +
               return "javax.xml.rpc.holders.ByteArrayHolder";
           }
   
  @@ -136,6 +138,17 @@
                       && (type.getRefType() instanceof BaseType)) {
                   String uri = type.getRefType().getQName().getNamespaceURI();
   
  +		// Capitalize the first character for primitive type
  +		// array holder classes
  +		if (TYPES.get(JavaUtils.replace(name,"[]","")) != null) {
  +                    name = capitalizeFirstChar(name);
  +		}
  +
  +		// For wrapped primitive array holder classes append 'Wrapper' to name
  +		if (((CollectionType) type).isWrapped() && !typeValue.equals(type.getName())) {
  +                        name = name + "Wrapper";
  +	        }
  +
                   packagePrefix = emitter.getNamespaces().getCreate(uri, false);
   
                   if (packagePrefix == null) {
  @@ -144,9 +157,8 @@
                       packagePrefix += '.';
                   }
               }
  -
               name = JavaUtils.replace(name, "java.lang.", "");
  -
  +	    
               // This could be a special QName for a indexed property.
               // If so, change the [] to Array.
               name = JavaUtils.replace(name, "[]", "Array");
  @@ -715,19 +727,20 @@
               }
           }
   
  +        // If minOccurs="0" and singular or array with nillable underlying
  +        // type get the corresponding wrapper type.
  +        if ((param.isOmittable() && param.getType().getDimensions().equals(""))
  +            || (param.getType() instanceof CollectionType
  +                && ((CollectionType) param.getType()).isWrapped())
  +            || param.getType().getUnderlTypeNillable()) { 
  +            
  +            typeName = getWrapperType(param.getType());
  +        }
  +
           String objType = (String) TYPES.get(typeName);
   
           if (objType != null) {
  -            // If minOccurs="0" and singular or array with nillable underlying
  -            // type get the corresponding wrapper type.
  -            if ((param.isOmittable() && param.getType().getDimensions().equals(""))
  -                || param.getType().getUnderlTypeNillable()) {
  -
  -                typeName = getWrapperType(param.getType());
  -            } else {
  -                return "((" + objType + ") " + var + ")." + typeName +
  -                        "Value();";
  -            }
  +            return "((" + objType + ") " + var + ")." + typeName + "Value();";
           }
   
           return "(" + typeName + ") " + var + ";";
  @@ -983,6 +996,8 @@
               // If minOccurs="0" and singular or array with nillable underlying
               // type get the corresponding wrapper type.
               if ((parm.isOmittable() && parm.getType().getDimensions().equals(""))
  +                || (parm.getType() instanceof CollectionType 
  +                    && ((CollectionType) parm.getType()).isWrapped())
                   || parm.getType().getUnderlTypeNillable()) {
   
                   ret = getWrapperType(parm.getType());
  @@ -1227,9 +1242,17 @@
                                                   BooleanHolder bThrow) {
   
           String paramType = param.getType().getName();
  -        if (param.isOmittable()) {
  -            paramType = Utils.getWrapperType(paramType);
  +
  +        // For base types that are nillable and are mapped to primitives,
  +        // need to switch to the corresponding wrapper types.
  +        if ((param.isOmittable() && param.getType().getDimensions().equals(""))
  +            || (param.getType() instanceof CollectionType
  +                && ((CollectionType) param.getType()).isWrapped())
  +            || param.getType().getUnderlTypeNillable()) {
  +
  +            paramType = getWrapperType(param.getType());
           }
  +
           String mimeType = (param.getMIMEInfo() == null)
                   ? null
                   : param.getMIMEInfo().getType();
  
  
  
  1.66      +10 -7     ws-axis/java/src/org/apache/axis/encoding/TypeMappingImpl.java
  
  Index: TypeMappingImpl.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/encoding/TypeMappingImpl.java,v
  retrieving revision 1.65
  retrieving revision 1.66
  diff -u -r1.65 -r1.66
  --- TypeMappingImpl.java	13 Jun 2005 02:55:19 -0000	1.65
  +++ TypeMappingImpl.java	1 Aug 2005 03:16:45 -0000	1.66
  @@ -30,6 +30,7 @@
   import org.apache.axis.utils.Messages;
   import org.apache.axis.utils.ClassUtils;
   import org.apache.axis.utils.JavaUtils;
  +import org.apache.axis.wsdl.toJava.Utils;
   import org.apache.axis.wsdl.fromJava.Namespaces;
   import org.apache.axis.wsdl.fromJava.Types;
   import org.apache.commons.logging.Log;
  @@ -457,15 +458,17 @@
               Class componentType = javaType.getComponentType();
   
               // HACK ALERT - Don't return the ArrayDeserializer IF
  -            // the xmlType matches the component type of the array,
  -            // because that means we're using maxOccurs and we'll
  -            // want the higher layers to get the component type
  -            // deserializer... (sigh)
  +            // the xmlType matches the component type of the array
  +	    // or if the componentType is the wrappertype of the
  +	    // xmlType, because that means we're using maxOccurs 
  +	    // and/or nillable and we'll want the higher layers to 
  +	    // get the component type deserializer... (sigh)
               if (xmlType != null) {
                   Class actualClass = start.getClassForQName(xmlType);
  -                if (actualClass == componentType ||
  -                    (actualClass != null && componentType.isAssignableFrom(actualClass))) {
  -                    return null;
  +                if (actualClass == componentType
  +                    || (actualClass != null && (componentType.isAssignableFrom(actualClass)
  +                        || Utils.getWrapperType(actualClass.getName()).equals(componentType.getName())))) {
  +			return null;
                   }
               }
               Pair pair = (Pair) qName2Pair.get(Constants.SOAP_ARRAY);