Author: veithen
Date: Sun Dec 11 11:17:43 2011
New Revision: 1212992

URL: http://svn.apache.org/viewvc?rev=1212992&view=rev
Log:
AXIOM-403: Make sure that the content of the root part of an XOP/MTOM message 
is only buffered (read into memory) if necessary.

Added:
    
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
   (with props)
Modified:
    
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLBuilderFactory.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/OMTestSuiteBuilder.java

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java?rev=1212992&r1=1212991&r2=1212992&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
 Sun Dec 11 11:17:43 2011
@@ -22,6 +22,7 @@ package org.apache.axiom.attachments;
 import org.apache.axiom.attachments.Part;
 import org.apache.axiom.mime.Header;
 import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.util.DetachableInputStream;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.james.mime4j.MimeException;
@@ -85,6 +86,8 @@ final class PartImpl implements Part {
     
     private final DataHandler dataHandler;
     
+    private DetachableInputStream detachableInputStream;
+    
     /**
      * The actual parts are constructed with the PartFactory.
      * @see org.apache.axiom.attachments.PartContentFactory
@@ -180,6 +183,13 @@ final class PartImpl implements Part {
                 state = STATE_BUFFERED;
                 break;
             case STATE_STREAMING:
+                // If the stream is still open, buffer the remaining content
+                try {
+                    detachableInputStream.detach();
+                } catch (IOException ex) {
+                    throw new OMException(ex);
+                }
+                detachableInputStream = null;
                 moveToNextPart();
                 state = STATE_DISCARDED;
         }
@@ -208,7 +218,8 @@ final class PartImpl implements Part {
         if (!preserve && state == STATE_UNREAD) {
             checkParserState(parser.getState(), EntityState.T_BODY);
             state = STATE_STREAMING;
-            return parser.getDecodedInputStream();
+            detachableInputStream = new 
DetachableInputStream(parser.getDecodedInputStream());
+            return detachableInputStream;
         } else {
             PartContent content = getContent();
             InputStream stream = content.getInputStream();

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLBuilderFactory.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLBuilderFactory.java?rev=1212992&r1=1212991&r2=1212992&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLBuilderFactory.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLBuilderFactory.java
 Sun Dec 11 11:17:43 2011
@@ -499,12 +499,11 @@ public class OMXMLBuilderFactory {
         }
         InputStream in;
         try {
-            // TODO: AXIOM-403
-//            if (dh instanceof DataHandlerExt) {
-//                in = ((DataHandlerExt)dh).readOnce();
-//            } else {
+            if (dh instanceof DataHandlerExt) {
+                in = ((DataHandlerExt)dh).readOnce();
+            } else {
                 in = dh.getInputStream();
-//            }
+            }
         } catch (IOException ex) {
             throw new OMException("Unable to get input stream from root MIME 
part", ex);
         }

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java?rev=1212992&r1=1212991&r2=1212992&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java
 Sun Dec 11 11:17:43 2011
@@ -110,6 +110,8 @@ public class AttachmentsTest extends Abs
         
         // Now do it again but use base64 content-type-encoding for 
         // binary attachments
+        is = new ByteArrayInputStream(outBase64.getBytes());
+        attachments2 = new Attachments(is, testMessage.getContentType());
         baos = new ByteArrayOutputStream();
         
oof.setProperty(OMOutputFormat.USE_CTE_BASE64_FOR_NON_TEXTUAL_ATTACHMENTS, 
                         Boolean.TRUE);

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/OMTestSuiteBuilder.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/OMTestSuiteBuilder.java?rev=1212992&r1=1212991&r2=1212992&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/OMTestSuiteBuilder.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/OMTestSuiteBuilder.java
 Sun Dec 11 11:17:43 2011
@@ -71,6 +71,7 @@ public class OMTestSuiteBuilder extends 
         addTest(new 
org.apache.axiom.ts.om.builder.TestInvalidXML(metaFactory));
         addTest(new 
org.apache.axiom.ts.om.builder.TestIOExceptionInGetText(metaFactory));
         addTest(new 
org.apache.axiom.ts.om.builder.TestReadAttachmentBeforeRootPartComplete(metaFactory));
+        addTest(new 
org.apache.axiom.ts.om.builder.TestRootPartStreaming(metaFactory));
         addTest(new 
org.apache.axiom.ts.om.builder.TestStandaloneConfiguration(metaFactory));
         for (int i=0; i<conformanceFiles.length; i++) {
             for (int j=0; j<containerFactories.length; j++) {

Added: 
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java?rev=1212992&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
 (added)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
 Sun Dec 11 11:17:43 2011
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.ts.om.builder;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.attachments.Attachments;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMMetaFactory;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.OMXMLBuilderFactory;
+import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.om.util.StAXParserConfiguration;
+import org.apache.axiom.ts.AxiomTestCase;
+import org.apache.commons.io.input.CountingInputStream;
+
+/**
+ * Tests that the content of the root part of an XOP/MTOM message is not 
buffered (i.e. read
+ * entirely into memory) unless an attachment part is accessed. This is a 
regression test for <a
+ * href="https://issues.apache.org/jira/browse/AXIOM-403";>AXIOM-403</a>.
+ */
+public class TestRootPartStreaming extends AxiomTestCase {
+    public TestRootPartStreaming(OMMetaFactory metaFactory) {
+        super(metaFactory);
+    }
+
+    protected void runTest() throws Throwable {
+        OMFactory factory = metaFactory.getOMFactory();
+        
+        // Programmatically create the message
+        OMElement orgRoot = factory.createOMElement("root", null);
+        for (int i=0; i<1000; i++) {
+            factory.createOMElement("child", null, orgRoot).setText("Some text 
content");
+        }
+        
+        // Serialize the message as XOP even if there will be no attachment 
parts
+        OMOutputFormat format = new OMOutputFormat();
+        format.setDoOptimize(true);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        orgRoot.serialize(baos, format);
+        
+        // Parse the message and monitor the number of bytes read
+        CountingInputStream in = new CountingInputStream(new 
ByteArrayInputStream(baos.toByteArray()));
+        OMXMLParserWrapper builder = 
OMXMLBuilderFactory.createOMBuilder(factory,
+                StAXParserConfiguration.DEFAULT,
+                new Attachments(in, format.getContentType()));
+        OMElement root = builder.getDocumentElement();
+        int count1 = in.getCount();
+        XMLStreamReader reader = root.getXMLStreamReader(false);
+        while (reader.hasNext()) {
+            reader.next();
+        }
+        int count2 = in.getCount();
+        
+        // We expect that after requesting the document element, only a small 
part (corresponding to
+        // the size of the parser buffer) should have been read:
+        assertTrue(count1 < count2/2);
+    }
+}

Propchange: 
webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to