Hi, This patch adds a single call to xmlStreamReader.next() to ConverterUtil.getAnyTypeObject. This has the effect that getAnyTypeObject now leaves the stream at the end tag of the xs:anyType element when the xsi:nil attribute is set. When xsi:nil is not set, getAnyTypeObject already leaves the stream at the end tag, so this patch makes getAnyTypeObject consistent with regard to the state of the stream after getAnyTypeObject is called.
The stubs generated by wsdl2java assume that getAnyTypeObject always leaves the stream at the end tag. This mismatch between the assumptions in the stubs and the actual behavior of getAnyTypeObject was the cause of issue AXIS2-4273. I had attached an earlier version of this patch to the issue, but since there has been no response and the patch didn't apply cleanly any more, I have regenerated the patch and am sending it again. Regards, Pétur Runólfsson Betware The content of this e-mail, together with any of its attachments, is for the exclusive and confidential use of the named addressee(s) and it may contain legally privileged and confidential information and/or copyrighted material. Any other distribution, use or reproduction without the sender's prior consent is unauthorized and strictly prohibited. If you have by coincidence, mistake or without specific authorization received this e-mail in error, please notify the sender by e-mail immediately, uphold strict confidentiality and neither read, copy, transfer, disseminate, disclose nor otherwise make use of its content in any way and delete the material from your computer. The content of the e-mail and its attachments is the liability of the individual sender, if it does not relate to the affairs of Betware. Betware does not assume any civil or criminal liability should the e-mail or it´s attachments be virus infected.
Index: test/org/apache/axis2/databinding/utils/ConverterUtilTest.java =================================================================== --- test/org/apache/axis2/databinding/utils/ConverterUtilTest.java (revision 784710) +++ test/org/apache/axis2/databinding/utils/ConverterUtilTest.java (working copy) @@ -19,6 +19,8 @@ package org.apache.axis2.databinding.utils; +import org.apache.axiom.om.*; + import junit.framework.TestCase; import java.math.BigInteger; @@ -29,6 +31,9 @@ import java.util.List; import java.util.TimeZone; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + public class ConverterUtilTest extends TestCase { /** Test conversion of Big Integer */ @@ -168,5 +173,86 @@ TestCase.assertTrue(ConverterUtil.convertToString(c).endsWith("+09:00")); } + + // Verify fix for AXIS2-4273 + public void testGetAnyTypeObjectWithNull() throws Exception { + AnyTypeObjectBuilder builder = new AnyTypeObjectBuilder(); + OMAttribute nilAttribute = builder.factory.createOMAttribute("nil", + builder.xsiNamespace, "true"); + builder.anytypechild.addAttribute(nilAttribute); + + XMLStreamReader reader = builder.getReaderAtStartOfAnyTypeChild(); + + Object ob = ConverterUtil.getAnyTypeObject(reader, Object.class); + assertNull(ob); + + builder.assertAtEndOfAnyTypeChild(reader); + } + + // Test case to demonstrate that getAnyTypeObject leaves the reader at the + // end of the element for both nil and non-nil elements + public void testGetAnyTypeObjectWithString() throws Exception { + AnyTypeObjectBuilder builder = new AnyTypeObjectBuilder(); + + OMAttribute typeAttribute = builder.factory.createOMAttribute("type", + builder.xsiNamespace, "xs:string"); + builder.anytypechild.addAttribute(typeAttribute); + builder.anytypechild.setText("Hello"); + + XMLStreamReader reader = builder.getReaderAtStartOfAnyTypeChild(); + + Object ob = ConverterUtil.getAnyTypeObject(reader, Object.class); + assertEquals("Hello", ob); + + builder.assertAtEndOfAnyTypeChild(reader); + } + + // Creates the following document: + // <parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + // xmlns:xs="http://www.w3.org/2001/XMLSchema"> + // <anytypechild>...</anytypechild> + // <regularchild>World</regularchild> + // </parent> + private static class AnyTypeObjectBuilder { + public OMFactory factory = OMAbstractFactory.getOMFactory(); + public OMNamespace xsiNamespace = factory.createOMNamespace( + "http://www.w3.org/2001/XMLSchema-instance", "xsi"); + public OMNamespace xsdNamespace = factory.createOMNamespace( + "http://www.w3.org/2001/XMLSchema", "xs"); + public OMElement parent = factory.createOMElement(new QName("parent")); + public OMElement anytypechild = factory.createOMElement(new QName( + "anytypechild"), parent); + public OMElement regularchild = factory.createOMElement(new QName( + "regularchild"), parent); + + public AnyTypeObjectBuilder() { + parent.declareNamespace(xsiNamespace); + parent.declareNamespace(xsdNamespace); + + regularchild.setText("World"); + } + + public XMLStreamReader getReaderAtStartOfAnyTypeChild() + throws Exception { + XMLStreamReader reader = parent.getXMLStreamReader(); + reader.next(); + reader.next(); + // Verify that reader is at start of element + assertEquals("anytypechild", reader.getLocalName()); + assertTrue(reader.isStartElement()); + return reader; + } + + public void assertAtEndOfAnyTypeChild(XMLStreamReader reader) + throws Exception { + // Check that reader is at some end element + assertTrue(reader.isEndElement()); + // Verify that it was the correct end element by looking at the next + // element + reader.next(); + assertTrue(reader.isStartElement()); + assertEquals("regularchild", reader.getLocalName()); + } + } } Index: src/org/apache/axis2/databinding/utils/ConverterUtil.java =================================================================== --- src/org/apache/axis2/databinding/utils/ConverterUtil.java (revision 784710) +++ src/org/apache/axis2/databinding/utils/ConverterUtil.java (working copy) @@ -1512,6 +1512,7 @@ String nillableValue = xmlStreamReader.getAttributeValue(Constants.XSI_NAMESPACE, "nil"); if ("true".equals(nillableValue) || "1".equals(nillableValue)){ returnObject = null; + xmlStreamReader.next(); } else { String attributeType = xmlStreamReader.getAttributeValue(Constants.XSI_NAMESPACE, "type"); if (attributeType != null) {