Author: veithen Date: Sat Oct 10 12:35:45 2009 New Revision: 823847 URL: http://svn.apache.org/viewvc?rev=823847&view=rev Log: * Applied a proper fix for the problem in ADB revealed by r823134, but that avoids the regression caused by the change in XMLStreamReaderUtils in r822747. * Increased unit test coverage for XMLStreamReaderUtils to avoid regression.
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/XMLStreamReaderUtilsTest.java Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java?rev=823847&r1=823846&r2=823847&view=diff ============================================================================== --- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java (original) +++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java Sat Oct 10 12:35:45 2009 @@ -64,26 +64,21 @@ */ public static DataHandler getDataHandlerFromElement(XMLStreamReader reader) throws XMLStreamException { - - // according to the pre and post conditions it is possible to have an - // empty element eg. <ns3:inByteArray xmlns:ns3="http://tempuri.org/"></ns3:inByteArray> for empty data handlers - // in that case we return a new data handler. - // This method is used by adb parser we can not return null since this element is not null. - reader.next(); - if (!reader.hasText()){ - DataHandler dataHandler = new DataHandler(new ByteArrayDataSource(new byte[0])); - // return from here since reader at the end element - return dataHandler; - } DataHandlerReader dhr = getDataHandlerReader(reader); String base64; if (dhr == null) { - // since we have advance the reader to next have to use the - // reader.getText - base64 = reader.getText(); - reader.next(); + // In this case the best way to get the content of the element is using + // the getElementText method + base64 = reader.getElementText(); } else { + int event = reader.next(); + if (event == XMLStreamConstants.END_ELEMENT) { + // This means that the element is actaullay empty -> return empty DataHandler + return new DataHandler(new ByteArrayDataSource(new byte[0])); + } else if (event != XMLStreamConstants.CHARACTERS) { + throw new XMLStreamException("Expected a CHARACTER event"); + } if (dhr.isBinary()) { DataHandler dh = dhr.getDataHandler(); reader.next(); Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/XMLStreamReaderUtilsTest.java URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/XMLStreamReaderUtilsTest.java?rev=823847&r1=823846&r2=823847&view=diff ============================================================================== --- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/XMLStreamReaderUtilsTest.java (original) +++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/XMLStreamReaderUtilsTest.java Sat Oct 10 12:35:45 2009 @@ -19,17 +19,54 @@ package org.apache.axiom.util.stax; import java.io.StringReader; +import java.util.Arrays; +import java.util.Random; import javax.activation.DataHandler; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import org.apache.axiom.om.util.StAXUtils; - import junit.framework.TestCase; +import org.apache.axiom.om.util.StAXUtils; +import org.apache.axiom.util.base64.Base64StringBufferOutputStream; +import org.apache.axiom.util.stax.xop.XOPDecodingStreamReader; +import org.apache.commons.io.IOUtils; + public class XMLStreamReaderUtilsTest extends TestCase { - public void testGetDataHandlerFromElementWithZeroLength() throws Exception { + /** + * Test that {...@link XMLStreamReaderUtils#getDataHandlerFromElement(XMLStreamReader)} + * returns an empty {...@link DataHandler} when the element is empty. The test uses + * an {...@link XMLStreamReader} instance that doesn't implement the + * {...@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader} extension. + * + * @throws Exception + */ + public void testGetDataHandlerFromElementWithZeroLengthNonDHR() throws Exception { + testGetDataHandlerFromElementWithZeroLength(false); + } + + /** + * Test that {...@link XMLStreamReaderUtils#getDataHandlerFromElement(XMLStreamReader)} + * returns an empty {...@link DataHandler} when the element is empty. The test uses + * an {...@link XMLStreamReader} instance that implements the + * {...@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader} extension. + * + * @throws Exception + */ + public void testGetDataHandlerFromElementWithZeroLengthDHR() throws Exception { + testGetDataHandlerFromElementWithZeroLength(true); + } + + private void testGetDataHandlerFromElementWithZeroLength(boolean useDHR) throws Exception { XMLStreamReader reader = StAXUtils.createXMLStreamReader(new StringReader("<test/>")); + if (useDHR) { + // To have an XMLStreamReader that uses the DataHandlerReader extension, we wrap + // the parser using an XOPDecodingStreamReader (even if the document doesn't contain + // any xop:Include). + reader = new XOPDecodingStreamReader(reader, null); + } try { reader.next(); @@ -45,4 +82,109 @@ reader.close(); } } + + /** + * Test that {...@link XMLStreamReaderUtils#getDataHandlerFromElement(XMLStreamReader)} + * throws an exception if the element has unexpected content. The test uses + * an {...@link XMLStreamReader} instance that doesn't implement the + * {...@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader} extension. + * + * @throws Exception + */ + public void testGetDataHandlerFromElementWithUnexpectedContentNonDHR() throws Exception { + testGetDataHandlerFromElementWithUnexpectedContent(false); + } + + /** + * Test that {...@link XMLStreamReaderUtils#getDataHandlerFromElement(XMLStreamReader)} + * throws an exception if the element has unexpected content. The test uses + * an {...@link XMLStreamReader} instance that implements the + * {...@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader} extension. + * + * @throws Exception + */ + public void testGetDataHandlerFromElementWithUnexpectedContentDHR() throws Exception { + testGetDataHandlerFromElementWithUnexpectedContent(true); + } + + private void testGetDataHandlerFromElementWithUnexpectedContent(boolean useDHR) throws Exception { + XMLStreamReader reader = StAXUtils.createXMLStreamReader(new StringReader("<test>\n<child/>\n</test>")); + if (useDHR) { + reader = new XOPDecodingStreamReader(reader, null); + } + try { + reader.next(); + + // Check precondition + assertTrue(reader.isStartElement()); + + try { + XMLStreamReaderUtils.getDataHandlerFromElement(reader); + fail("Expected XMLStreamException"); + } catch (XMLStreamException ex) { + // Expected + } + } finally { + reader.close(); + } + } + + /** + * Test that {...@link XMLStreamReaderUtils#getDataHandlerFromElement(XMLStreamReader)} + * correctly decodes base64 data if the parser is non coalescing and produces the data + * as multiple <tt>CHARACTER</tt> events. The test uses an {...@link XMLStreamReader} instance + * that doesn't implement the {...@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader} + * extension. + * + * @throws Exception + */ + public void testGetDataHandlerFromElementNonCoalescingNonDHR() throws Exception { + testGetDataHandlerFromElementNonCoalescing(false); + } + + /** + * Test that {...@link XMLStreamReaderUtils#getDataHandlerFromElement(XMLStreamReader)} + * correctly decodes base64 data if the parser is non coalescing and produces the data + * as multiple <tt>CHARACTER</tt> events. The test uses an {...@link XMLStreamReader} instance + * that implements the {...@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader} + * extension. + * + * @throws Exception + */ + public void testGetDataHandlerFromElementNonCoalescingDHR() throws Exception { + testGetDataHandlerFromElementNonCoalescing(true); + } + + private void testGetDataHandlerFromElementNonCoalescing(boolean useDHR) throws Exception { + // We generate base64 that is sufficiently large to force the parser to generate + // multiple CHARACTER events + StringBuffer buffer = new StringBuffer("<test>"); + Base64StringBufferOutputStream out = new Base64StringBufferOutputStream(buffer); + byte[] data = new byte[65536]; + new Random().nextBytes(data); + out.write(data); + out.complete(); + buffer.append("</test>"); + // StAXUtils return coalescing parsers, so we need to use XMLInputFactory here + XMLInputFactory factory = XMLInputFactory.newInstance(); + factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.FALSE); + XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(buffer.toString())); + if (useDHR) { + reader = new XOPDecodingStreamReader(reader, null); + } + try { + reader.next(); + + // Check precondition + assertTrue(reader.isStartElement()); + + DataHandler dh = XMLStreamReaderUtils.getDataHandlerFromElement(reader); + + // Check postcondition + assertTrue(reader.isEndElement()); + assertTrue(Arrays.equals(data, IOUtils.toByteArray(dh.getInputStream()))); + } finally { + reader.close(); + } + } }