ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From veit...@apache.org
Subject svn commit: r1796605 - in /webservices/axiom/trunk/axiom-api/src: main/java/org/apache/axiom/blob/ test/java/org/apache/axiom/blob/suite/
Date Mon, 29 May 2017 09:48:18 GMT
Author: veithen
Date: Mon May 29 09:48:17 2017
New Revision: 1796605

URL: http://svn.apache.org/viewvc?rev=1796605&view=rev
Log:
Fix bug in OverflowableBlob.

Modified:
    webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/blob/OverflowableBlobImpl.java
    webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/TestReadFromSupport.java
    webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/WritableBlobTestSuiteBuilder.java

Modified: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/blob/OverflowableBlobImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/blob/OverflowableBlobImpl.java?rev=1796605&r1=1796604&r2=1796605&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/blob/OverflowableBlobImpl.java
(original)
+++ webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/blob/OverflowableBlobImpl.java
Mon May 29 09:48:17 2017
@@ -29,9 +29,6 @@ import org.apache.axiom.util.io.IOUtils;
 
 final class OverflowableBlobImpl implements OverflowableBlob {
     class OutputStreamImpl extends OutputStream implements ReadFromSupport {
-        
-        private OutputStream overflowOutputStream;
-        
         @Override
         public void write(byte[] b, int off, int len) throws IOException {
             if (state != State.UNCOMMITTED) {
@@ -42,7 +39,7 @@ final class OverflowableBlobImpl impleme
             } else if (len > (chunks.length-chunkIndex)*chunkSize - chunkOffset) {
 
                 // The buffer will overflow. Switch to a temporary file.
-                overflowOutputStream = switchToOverflowBlob();
+                switchToOverflowBlob();
                 
                 // Write the new data to the temporary file.
                 overflowOutputStream.write(b, off, len);
@@ -229,6 +226,8 @@ final class OverflowableBlobImpl impleme
      */
     State state = State.NEW;
     
+    OutputStream overflowOutputStream;
+    
     OverflowableBlobImpl(int numberOfChunks, int chunkSize, WritableBlobFactory<?>
overflowBlobFactory) {
         this.chunkSize = chunkSize;
         this.overflowBlobFactory = overflowBlobFactory;
@@ -258,23 +257,21 @@ final class OverflowableBlobImpl impleme
      * @return an open FileOutputStream to the temporary file
      * @throws IOException
      */
-    OutputStream switchToOverflowBlob() throws IOException {
+    void switchToOverflowBlob() throws IOException {
         overflowBlob = overflowBlobFactory.createBlob();
 
-        OutputStream outputStream = overflowBlob.getOutputStream();
+        overflowOutputStream = overflowBlob.getOutputStream();
         // Write the buffer to the temporary file.
         for (int i=0; i<chunkIndex; i++) {
-            outputStream.write(chunks[i]);
+            overflowOutputStream.write(chunks[i]);
         }
 
         if (chunkOffset > 0) {
-            outputStream.write(chunks[chunkIndex], 0, chunkOffset);
+            overflowOutputStream.write(chunks[chunkIndex], 0, chunkOffset);
         }
 
         // Release references to the buffer so that it can be garbage collected.
         chunks = null;
-        
-        return outputStream;
     }
     
     @Override
@@ -291,44 +288,46 @@ final class OverflowableBlobImpl impleme
         if (state == State.COMMITTED) {
             throw new IllegalStateException();
         }
-        // TODO: this will not work if the blob is in state UNCOMMITTED and we have already
switched to a temporary file
         long read = 0;
         long toRead = length == -1 ? Long.MAX_VALUE : length;
         while (toRead > 0) {
-            int c;
-            try {
-                int len = chunkSize-chunkOffset;
-                if (len > toRead) {
-                    len = (int)toRead;
-                }
-                c = in.read(getCurrentChunk(), chunkOffset, len);
-            } catch (IOException ex) {
-                throw new StreamCopyException(StreamCopyException.READ, ex);
-            }
-            if (c == -1) {
+            if (overflowOutputStream != null) {
+                read += IOUtils.copy(in, overflowOutputStream, toRead);
                 break;
-            }
-            read += c;
-            toRead -= c;
-            chunkOffset += c;
-            if (chunkOffset == chunkSize) {
-                chunkIndex++;
-                chunkOffset = 0;
-                if (chunkIndex == chunks.length) {
-                    OutputStream out;
-                    try {
-                        out = switchToOverflowBlob();
-                    } catch (IOException ex) {
-                        throw new StreamCopyException(StreamCopyException.WRITE, ex);
-                    }
-                    read += IOUtils.copy(in, out, toRead);
-                    try {
-                        out.close();
-                    } catch (IOException ex) {
-                        throw new StreamCopyException(StreamCopyException.WRITE, ex);
+            } else if (chunkIndex == chunks.length) {
+                try {
+                    switchToOverflowBlob();
+                } catch (IOException ex) {
+                    throw new StreamCopyException(StreamCopyException.WRITE, ex);
+                }
+            } else {
+                int c;
+                try {
+                    int len = chunkSize-chunkOffset;
+                    if (len > toRead) {
+                        len = (int)toRead;
                     }
+                    c = in.read(getCurrentChunk(), chunkOffset, len);
+                } catch (IOException ex) {
+                    throw new StreamCopyException(StreamCopyException.READ, ex);
+                }
+                if (c == -1) {
                     break;
                 }
+                read += c;
+                toRead -= c;
+                chunkOffset += c;
+                if (chunkOffset == chunkSize) {
+                    chunkIndex++;
+                    chunkOffset = 0;
+                }
+            }
+        }
+        if (commit && overflowOutputStream != null) {
+            try {
+                overflowOutputStream.close();
+            } catch (IOException ex) {
+                throw new StreamCopyException(StreamCopyException.WRITE, ex);
             }
         }
         state = commit ? State.COMMITTED : State.UNCOMMITTED;

Modified: webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/TestReadFromSupport.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/TestReadFromSupport.java?rev=1796605&r1=1796604&r2=1796605&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/TestReadFromSupport.java
(original)
+++ webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/TestReadFromSupport.java
Mon May 29 09:48:17 2017
@@ -23,32 +23,36 @@ import static com.google.common.truth.Tr
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Random;
 
 import org.apache.axiom.blob.WritableBlob;
 import org.apache.axiom.blob.WritableBlobFactory;
 import org.apache.axiom.ext.io.ReadFromSupport;
 import org.apache.commons.io.IOUtils;
 
-public class TestReadFromSupport extends WritableBlobTestCase {
-    public TestReadFromSupport(WritableBlobFactory<?> factory) {
-        super(factory, State.NEW);
+public class TestReadFromSupport extends SizeSensitiveWritableBlobTestCase {
+    public TestReadFromSupport(WritableBlobFactory<?> factory, int size) {
+        super(factory, State.NEW, size);
     }
 
     @Override
     protected void runTest(WritableBlob blob) throws Throwable {
+        int chunkSize = size/4;
+        byte[] content = new byte[chunkSize*4];
+        new Random().nextBytes(content);
         OutputStream out = blob.getOutputStream();
         try {
-            out.write(new byte[] { 50, 60 });
-            ((ReadFromSupport)out).readFrom(new ByteArrayInputStream(new byte[] { 1, 2, 3,
4 }), -1);
-            ((ReadFromSupport)out).readFrom(new ByteArrayInputStream(new byte[] { 5, 6, 7,
8 }), 2);
-            out.write(new byte[] { 70, 80 });
+            out.write(Arrays.copyOfRange(content, 0, chunkSize));
+            ((ReadFromSupport)out).readFrom(new ByteArrayInputStream(Arrays.copyOfRange(content,
chunkSize, chunkSize*2)), -1);
+            ((ReadFromSupport)out).readFrom(new ByteArrayInputStream(Arrays.copyOfRange(content,
chunkSize*2, chunkSize*4)), chunkSize);
+            out.write(content, chunkSize*3, chunkSize);
         } finally {
             out.close();
         }
         InputStream in = blob.getInputStream();
         try {
-            assertThat(IOUtils.toByteArray(in)).isEqualTo(
-                    new byte[] { 50, 60, 1, 2, 3, 4, 5, 6, 70, 80 });
+            assertThat(IOUtils.toByteArray(in)).isEqualTo(content);
         } finally {
             in.close();
         }

Modified: webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/WritableBlobTestSuiteBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/WritableBlobTestSuiteBuilder.java?rev=1796605&r1=1796604&r2=1796605&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/WritableBlobTestSuiteBuilder.java
(original)
+++ webservices/axiom/trunk/axiom-api/src/test/java/org/apache/axiom/blob/suite/WritableBlobTestSuiteBuilder.java
Mon May 29 09:48:17 2017
@@ -51,9 +51,6 @@ public class WritableBlobTestSuiteBuilde
         addTest(new TestReadFromIllegalState(factory, State.UNCOMMITTED));
         addTest(new TestReadFromIllegalState(factory, State.COMMITTED));
         addTest(new TestReadFromIllegalState(factory, State.RELEASED));
-        if (outputStreamHasReadFromSupport) {
-            addTest(new TestReadFromSupport(factory));
-        }
         addTest(new TestReadFromWithError(factory));
         addTest(new TestReadZeroLength(factory));
         addTest(new TestReleaseTwice(factory));
@@ -70,6 +67,9 @@ public class WritableBlobTestSuiteBuilde
     private void addTests(int size) {
         addTest(new TestMarkReset(factory, size));
         addTest(new TestReadFrom(factory, size));
+        if (outputStreamHasReadFromSupport) {
+            addTest(new TestReadFromSupport(factory, size));
+        }
         addTest(new TestRandomReadWrite(factory, size));
         addTest(new TestWriteTo(factory, size));
         if (writeToUsesReadFromSupport) {



Mime
View raw message