You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by ve...@apache.org on 2009/10/10 14:35:46 UTC

svn commit: r823847 - in /webservices/commons/trunk/modules/axiom/modules/axiom-api/src: main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java test/java/org/apache/axiom/util/stax/XMLStreamReaderUtilsTest.java

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();
+        }
+    }
 }