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/07/15 22:48:47 UTC

svn commit: r794410 - in /webservices/commons/trunk/modules/axiom/modules/axiom-api/src: main/java/org/apache/axiom/util/blob/ test/java/org/apache/axiom/util/blob/

Author: veithen
Date: Wed Jul 15 20:48:47 2009
New Revision: 794410

URL: http://svn.apache.org/viewvc?rev=794410&view=rev
Log:
Created a MemoryBlob class based on the code of BAAOutputStream/BAAInputStream. This class implements the same interface as OverflowBlob (Synapse's TemporaryData). This will make it easy to switch between in-memory storage and file based storage of binary data. It also provides a nicer API than BAA(Input|Output)Stream.

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/MemoryBlob.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Slice.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/WritableBlob.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/MemoryBlobTest.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/WritableBlobTestBase.java
      - copied, changed from r793414, webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Blob.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/OverflowBlob.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Blob.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Blob.java?rev=794410&r1=794409&r2=794410&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Blob.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Blob.java Wed Jul 15 20:48:47 2009
@@ -24,26 +24,12 @@
 import java.io.OutputStream;
 
 public interface Blob {
-    OutputStream getOutputStream();
-
     /**
-     * Fill this object with data read from a given InputStream.
-     * <p>
-     * A call <code>tmp.readFrom(in)</code> has the same effect as the
-     * following code:
-     * <pre>
-     * OutputStream out = tmp.getOutputStream();
-     * IOUtils.copy(in, out);
-     * out.close();
-     * </pre>
-     * However it does so in a more efficient way.
+     * Get an input stream to read the data in the blob.
      * 
-     * @param in An InputStream to read data from. This method will not
-     *           close the stream.
+     * @return the input stream to read the data from
      * @throws IOException
      */
-    void readFrom(InputStream in) throws IOException;
-
     InputStream getInputStream() throws IOException;
 
     /**
@@ -55,5 +41,10 @@
      */
     void writeTo(OutputStream out) throws IOException;
 
+    /**
+     * Get the length of the data in the blob, i.e. the number of bytes.
+     * 
+     * @return the length of the data in the blob
+     */
     long getLength();
 }
\ No newline at end of file

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/MemoryBlob.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/MemoryBlob.java?rev=794410&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/MemoryBlob.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/MemoryBlob.java Wed Jul 15 20:48:47 2009
@@ -0,0 +1,225 @@
+/*
+ * 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.util.blob;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.axiom.attachments.impl.BufferUtils;
+
+public class MemoryBlob implements WritableBlob {
+    final static int BUFFER_SIZE = BufferUtils.BUFFER_LEN;
+    
+    class OutputStreamImpl extends OutputStream {
+        public void write(byte[] b, int off, int len) throws IOException {
+           int total = 0;
+           while (total < len) {
+               int copy = Math.min(len-total, BUFFER_SIZE-index);
+               System.arraycopy(b, off, currBuffer, index, copy);
+               total += copy;
+               index += copy;
+               off += copy;
+               if (index >= BUFFER_SIZE) {
+                   addBuffer();
+               }
+           }
+        }
+
+        public void write(byte[] b) throws IOException {
+            this.write(b, 0, b.length);
+        }
+        
+        byte[] writeByte = new byte[1];
+        public void write(int b) throws IOException {
+            writeByte[0] = (byte) b;
+            this.write(writeByte, 0, 1);
+        }
+
+        public void close() throws IOException {
+            outputStream = null;
+            committed = true;
+        }
+    }
+
+    class InputStreamImpl extends InputStream {
+        private final int size;
+        private int i;
+        private int currIndex;
+        private int totalIndex;
+        private int mark;
+        private byte[] currBuffer;
+        private byte[] read_byte = new byte[1];
+        
+        public InputStreamImpl() {
+            size = (int)getLength();
+            currBuffer = (byte[]) data.get(0);
+        }
+
+        public int read() throws IOException {
+            int read = read(read_byte);
+
+            if (read < 0) {
+                return -1;
+            } else {
+                return read_byte[0] & 0xFF;
+            }
+        }
+
+        public int available() throws IOException {
+            return size - totalIndex;
+        }
+
+
+        public synchronized void mark(int readlimit) {
+            mark = totalIndex;
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+            int total = 0;
+            if (totalIndex >= size) {
+                return -1;
+            }
+            while (total < len && totalIndex < size) {
+                int copy = Math.min(len - total, BUFFER_SIZE - currIndex);
+                copy = Math.min(copy, size - totalIndex);
+                System.arraycopy(currBuffer, currIndex, b, off, copy);
+                total += copy;
+                currIndex += copy;
+                totalIndex += copy;
+                off += copy;
+                if (currIndex >= BUFFER_SIZE) {
+                    if (i+1 < data.size()) {
+                        currBuffer = (byte[]) data.get(i+1);
+                        i++;
+                        currIndex = 0;
+                    } else {
+                        currBuffer = null;
+                        currIndex = BUFFER_SIZE;
+                    } 
+                }
+            }
+            return total;
+        }
+
+        public int read(byte[] b) throws IOException {
+            return this.read(b, 0, b.length);
+        }
+
+        public synchronized void reset() throws IOException {
+            i = mark / BUFFER_SIZE;
+            currIndex = mark - (i * BUFFER_SIZE);
+            currBuffer = (byte[]) data.get(i);
+            totalIndex = mark;
+        }
+    }
+    
+    List data; // null here indicates the blob is in state NEW
+    int index;
+    byte[] currBuffer;
+    OutputStreamImpl outputStream;
+    boolean committed;
+    
+    private void init() {
+        data = new ArrayList();
+        addBuffer();
+    }
+    
+    void addBuffer() {
+        currBuffer = new byte[BUFFER_SIZE];
+        data.add(currBuffer);
+        index = 0;
+    }
+    
+    public long getLength() {
+        return (BUFFER_SIZE * (data.size()-1)) + index;
+    }
+
+    public OutputStream getOutputStream() {
+        if (data != null) {
+            throw new IllegalStateException();
+        } else {
+            init();
+            return outputStream = new OutputStreamImpl();
+        }
+    }
+
+    public void readFrom(InputStream in, boolean commit) throws IOException {
+        if (data == null) {
+            init();
+        }
+        
+        long bytesReceived = 0;
+        
+        // Now directly write to the buffers
+        boolean done = false;
+        while (!done) {
+            
+            // Don't get more than will fit in the current buffer
+            int len = BUFFER_SIZE - index;
+            
+            // Now get the bytes
+            int bytesRead = in.read(currBuffer, index, len);
+            if (bytesRead >= 0) {
+                bytesReceived += bytesRead;
+                index += bytesRead;
+                if (index >= BUFFER_SIZE) {
+                    addBuffer();
+                }
+            } else {
+                done = true;
+            }
+        }
+        
+        committed = commit;
+    }
+
+    public void readFrom(InputStream in) throws IOException {
+        readFrom(in, data == null);
+    }
+
+    public InputStream getInputStream() throws IOException {
+        if (!committed) {
+            throw new IllegalStateException();
+        } else {
+            return new InputStreamImpl();
+        }
+    }
+
+    public void writeTo(OutputStream os) throws IOException {
+        int size = (int)getLength();
+        if (data != null) {
+            int numBuffers = data.size();
+            for (int j = 0; j < numBuffers-1; j ++) {
+                os.write( (byte[]) data.get(j), 0, BUFFER_SIZE);
+            }
+            if (numBuffers > 0) {
+                int writeLimit = size - ((numBuffers-1) * BUFFER_SIZE);
+                os.write( (byte[]) data.get(numBuffers-1), 0, writeLimit);
+            }
+        }
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/MemoryBlob.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/OverflowBlob.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/OverflowBlob.java?rev=794410&r1=794409&r2=794410&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/OverflowBlob.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/OverflowBlob.java Wed Jul 15 20:48:47 2009
@@ -1,3 +1,22 @@
+/*
+ * 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.util.blob;
 
 import java.io.File;
@@ -23,10 +42,13 @@
  * on demand. Since a temporary file may be created it is mandatory to
  * call {@link #release()} to discard the temporary data.
  */
-public class OverflowBlob implements Blob {
-    
+public class OverflowBlob implements WritableBlob {
     private static final Log log = LogFactory.getLog(OverflowBlob.class);
     
+    static final int STATE_NEW = 0;
+    static final int STATE_UNCOMMITTED = 1;
+    static final int STATE_COMMITTED = 2;
+    
     class OutputStreamImpl extends OutputStream {
         
         private FileOutputStream fileOutputStream;
@@ -85,6 +107,7 @@
             if (fileOutputStream != null) {
                 fileOutputStream.close();
             }
+            state = STATE_COMMITTED;
         }
     }
     
@@ -145,7 +168,7 @@
 
         public int read() throws IOException {
             byte[] b = new byte[1];
-            return read(b) == -1 ? -1 : (int)b[0] & 0xFF;
+            return read(b) == -1 ? -1 : b[0] & 0xFF;
         }
 
         public boolean markSupported() {
@@ -216,6 +239,11 @@
      */
     File temporaryFile;
     
+    /**
+     * The state of the blob.
+     */
+    int state = STATE_NEW;
+    
     public OverflowBlob(int numberOfChunks, int chunkSize, String tempPrefix, String tempSuffix) {
         this.chunkSize = chunkSize;
         this.tempPrefix = tempPrefix;
@@ -270,10 +298,16 @@
     }
     
     public OutputStream getOutputStream() {
-        return new OutputStreamImpl();
+        if (state != STATE_NEW) {
+            throw new IllegalStateException();
+        } else {
+            state = STATE_UNCOMMITTED;
+            return new OutputStreamImpl();
+        }
     }
     
-    public void readFrom(InputStream in) throws IOException {
+    public void readFrom(InputStream in, boolean commit) throws IOException {
+        // TODO: this will not work if the blob is in state UNCOMMITTED and we have already switched to a temporary file
         while (true) {
             int c = in.read(getCurrentChunk(), chunkOffset, chunkSize-chunkOffset);
             if (c == -1) {
@@ -291,10 +325,17 @@
                 }
             }
         }
+        state = commit ? STATE_COMMITTED : STATE_UNCOMMITTED;
     }
     
+    public void readFrom(InputStream in) throws IOException {
+        readFrom(in, state == STATE_NEW);
+    }
+
     public InputStream getInputStream() throws IOException {
-        if (temporaryFile != null) {
+        if (state != STATE_COMMITTED) {
+            throw new IllegalStateException();
+        } else if (temporaryFile != null) {
             return new FileInputStream(temporaryFile);
         } else {
             return new InputStreamImpl();

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Slice.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Slice.java?rev=794410&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Slice.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Slice.java Wed Jul 15 20:48:47 2009
@@ -0,0 +1,24 @@
+/*
+ * 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.util.blob;
+
+public class Slice {
+
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/Slice.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/WritableBlob.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/WritableBlob.java?rev=794410&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/WritableBlob.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/WritableBlob.java Wed Jul 15 20:48:47 2009
@@ -0,0 +1,124 @@
+/*
+ * 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.util.blob;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * A writable blob.
+ * <p>
+ * The behavior of the methods defined by this interface is described in terms of three logical
+ * states the blob can be in:
+ * <dl>
+ *   <dt>NEW
+ *   <dd>The blob has just been created and no data has been written to it yet.
+ *   <dt>UNCOMMITTED
+ *   <dd>Data is being written to the blob.
+ *   <dt>COMMITTED
+ *   <dd>All data has been written to the blob and the blob will no longer accept any new data.
+ * </dl>
+ * If the blob is in state NEW or UNCOMMITTED, any call to a method defined by the {@link Blob}
+ * superinterface will result in an {@link IllegalStateException}.
+ */
+public interface WritableBlob extends Blob {
+    /**
+     * Create an output stream to write data to the blob.
+     * <p>
+     * <em>Precondition:</em> The blob is in state NEW.
+     * <p>
+     * <em>Postcondition:</em> The blob is in state UNCOMMITTED.
+     * <p>
+     * Note that the pre- and postconditions imply that this method may be called at most once for
+     * a given blob instance.
+     * <p>
+     * Calls to methods of the returned output stream will modify the state of the blob
+     * according to the following rules:
+     * <ul>
+     *   <li>A call to {@link OutputStream#close()} will change the state to COMMITTED.
+     *   <li>Calls to other methods will not modify the state of the blob. They will result in
+     *       an {@link IOException} if the state is COMMITTED, i.e. if the stream has already been
+     *       closed.
+     * </ul>
+     * 
+     * @return an output stream that can be used to write data to the blob
+     * 
+     * @throws IllegalStateException if the blob is not in state NEW
+     */
+    OutputStream getOutputStream();
+
+    /**
+     * Read data from the given input stream and write it to the blob.
+     * <p>
+     * A call to this method has the same effect as requesting an output stream using
+     * {@link #getOutputStream()} and copying the data from the input stream to that
+     * output stream, but the implementation will achieve this result in a more efficient way.
+     * <p>
+     * <em>Precondition:</em> The blob is in state NEW or UNCOMMITTED.
+     * <p>
+     * <em>Postcondition:</em> The blob is in state UNCOMMITTED if <code>commit</code> is
+     * <code>false</code>. It is in state COMMITTED if <code>commit</code> is <code>true</code>.
+     * <p>
+     * The precondition implies that this method may be used after a call to
+     * {@link #getOutputStream()}. In that case it is illegal to set <code>commit</code> to
+     * <code>true</code> (because this would invalidate the state of the output stream).
+     * 
+     * @param in An input stream to read data from. This method will not
+     *           close the stream.
+     * @throws IOException
+     * @throws IllegalStateException if the blob is in state COMMITTED or if
+     *         {@link #getOutputStream()} has been called before and <code>commit</code> is
+     *         <code>true</code>
+     */
+    void readFrom(InputStream in, boolean commit) throws IOException;
+
+    /**
+     * Read data from the given input stream and write it to the blob.
+     * <p>
+     * This method is similar to {@link #readFrom(InputStream, boolean)}, except that the state
+     * of the blob after the invocation (i.e. the <code>commit</code> argument) is determined
+     * automatically:
+     * <p>
+     * <table border="2" rules="all" cellpadding="4" cellspacing="0">
+     *   <thead>
+     *     <tr><th>Precondition (state)</th><th>Postcondition (state)</th></tr>
+     *   </thead>
+     *   <tbody>
+     *     <tr><td>NEW</td><td>COMMITTED</td></tr>
+     *     <tr><td>UNCOMMITTED</td><td>UNCOMMITTED</td></tr>
+     *     <tr><td>COMMITTED</td><td><em>illegal</em></td></tr>
+     *   </tbody>
+     * </table>
+     * <p>
+     * There are thus two usage patterns for this method:
+     * <ol>
+     *   <li>The method is used to fill the blob with the data from an input stream, but no other
+     *       data is written to the blob.
+     *   <li>The method is used in parallel with the output stream returned by
+     *       {@link #getOutputStream()}: some data is written using the output stream and some
+     *       data is written using this method (for efficiency reasons).
+     * </ol>
+     * 
+     * @throws IOException
+     * @throws IllegalStateException if the blob is in state COMMITTED
+     */
+    void readFrom(InputStream in) throws IOException;
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/blob/WritableBlob.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/MemoryBlobTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/MemoryBlobTest.java?rev=794410&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/MemoryBlobTest.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/MemoryBlobTest.java Wed Jul 15 20:48:47 2009
@@ -0,0 +1,30 @@
+/*
+ * 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.util.blob;
+
+public class MemoryBlobTest extends WritableBlobTestBase {
+    protected WritableBlob createBlob() {
+        return new MemoryBlob();
+    }
+
+    protected void releaseBlob(WritableBlob blob) {
+        // Nothing to do here
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/MemoryBlobTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java?rev=794410&r1=794409&r2=794410&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java Wed Jul 15 20:48:47 2009
@@ -1,134 +1,30 @@
 /*
- *  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
+ * 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
+ * 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.
+ * 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.util.blob;
 
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.Random;
-
-import org.apache.commons.io.IOUtils;
-
-import junit.framework.TestCase;
-
-public class OverflowBlobTest extends TestCase {
-    private final static Random random = new Random();
-    
-    private void doTestRandomReadWrite(int size) throws IOException {
-        byte[] data = new byte[size];
-        random.nextBytes(data);
-        OverflowBlob tmp = new OverflowBlob(16, 1024, "test", ".dat");
-        try {
-            OutputStream out = tmp.getOutputStream();
-            // Write the test data in chunks with random size
-            int offset = 0;
-            while (offset < data.length) {
-                int c = Math.min(512 + random.nextInt(1024), data.length - offset);
-                out.write(data, offset, c);
-                offset += c;
-            }
-            out.close();
-            assertEquals(size, tmp.getLength());
-            // Reread the test data, again in chunks with random size
-            InputStream in = tmp.getInputStream();
-            offset = 0;
-            byte[] data2 = new byte[data.length];
-            byte[] buffer = new byte[2048];
-            while (true) {
-                int bufferOffset = random.nextInt(512);
-                int c = 512 + random.nextInt(1024);
-                int read = in.read(buffer, bufferOffset, c);
-                if (read == -1) {
-                    break;
-                }
-                int newOffset = offset + read;
-                assertTrue(newOffset <= data2.length);
-                System.arraycopy(buffer, bufferOffset, data2, offset, read);
-                offset = newOffset;
-            }
-            assertEquals(data2.length, offset);
-            in.close();
-            assertTrue(Arrays.equals(data, data2));
-        }
-        finally {
-            tmp.release();
-        }
-    }
-    
-    public void testRandomReadWriteInMemory() throws IOException {
-        doTestRandomReadWrite(10000);
-    }
-    
-    public void testRandomReadWriteWithTemporaryFile() throws IOException {
-        doTestRandomReadWrite(100000);
+public class OverflowBlobTest extends WritableBlobTestBase {
+    protected WritableBlob createBlob() {
+        return new OverflowBlob(16, 1024, "test", ".dat");
     }
-    
-    public void testMarkReset() throws IOException {
-        byte[] sourceData1 = new byte[2000];
-        byte[] sourceData2 = new byte[2000];
-        random.nextBytes(sourceData1);
-        random.nextBytes(sourceData2);
-        OverflowBlob tmp = new OverflowBlob(16, 512, "test", ".dat");
-        OutputStream out = tmp.getOutputStream();
-        out.write(sourceData1);
-        out.write(sourceData2);
-        out.close();
-        DataInputStream in = new DataInputStream(tmp.getInputStream());
-        byte[] data1 = new byte[sourceData1.length];
-        byte[] data2 = new byte[sourceData2.length];
-        in.readFully(data1);
-        in.mark(sourceData2.length);
-        in.readFully(data2);
-        in.reset();
-        in.readFully(data2);
-        assertTrue(Arrays.equals(sourceData1, data1));
-        assertTrue(Arrays.equals(sourceData2, data2));
-    }
-    
-    private void testReadFrom(int size) throws IOException {
-        byte[] data = new byte[size];
-        random.nextBytes(data);
-        OverflowBlob tmp = new OverflowBlob(16, 1024, "test", ".dat");
-        try {
-            tmp.readFrom(new ByteArrayInputStream(data));
-            InputStream in = tmp.getInputStream();
-            try {
-                assertTrue(Arrays.equals(data, IOUtils.toByteArray(in)));
-            }
-            finally {
-                in.close();
-            }
-        }
-        finally {
-            tmp.release();
-        }
-    }
-    
-    public void testReadFromInMemory() throws IOException {
-        testReadFrom(10000);
-    }
-    
-    public void testReadFromWithTemporaryFile() throws IOException {
-        testReadFrom(100000);
+
+    protected void releaseBlob(WritableBlob blob) {
+        ((OverflowBlob)blob).release();
     }
 }

Copied: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/WritableBlobTestBase.java (from r793414, webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java)
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/WritableBlobTestBase.java?p2=webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/WritableBlobTestBase.java&p1=webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java&r1=793414&r2=794410&rev=794410&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/OverflowBlobTest.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/blob/WritableBlobTestBase.java Wed Jul 15 20:48:47 2009
@@ -1,20 +1,20 @@
 /*
- *  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
+ * 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
+ * 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.
+ * 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.util.blob;
@@ -31,15 +31,18 @@
 
 import junit.framework.TestCase;
 
-public class OverflowBlobTest extends TestCase {
+public abstract class WritableBlobTestBase extends TestCase {
     private final static Random random = new Random();
     
+    protected abstract WritableBlob createBlob();
+    protected abstract void releaseBlob(WritableBlob blob);
+    
     private void doTestRandomReadWrite(int size) throws IOException {
         byte[] data = new byte[size];
         random.nextBytes(data);
-        OverflowBlob tmp = new OverflowBlob(16, 1024, "test", ".dat");
+        WritableBlob blob = createBlob();
         try {
-            OutputStream out = tmp.getOutputStream();
+            OutputStream out = blob.getOutputStream();
             // Write the test data in chunks with random size
             int offset = 0;
             while (offset < data.length) {
@@ -48,9 +51,9 @@
                 offset += c;
             }
             out.close();
-            assertEquals(size, tmp.getLength());
+            assertEquals(size, blob.getLength());
             // Reread the test data, again in chunks with random size
-            InputStream in = tmp.getInputStream();
+            InputStream in = blob.getInputStream();
             offset = 0;
             byte[] data2 = new byte[data.length];
             byte[] buffer = new byte[2048];
@@ -71,15 +74,15 @@
             assertTrue(Arrays.equals(data, data2));
         }
         finally {
-            tmp.release();
+            releaseBlob(blob);
         }
     }
     
-    public void testRandomReadWriteInMemory() throws IOException {
+    public void testRandomReadWriteLength10000() throws IOException {
         doTestRandomReadWrite(10000);
     }
     
-    public void testRandomReadWriteWithTemporaryFile() throws IOException {
+    public void testRandomReadWriteLength100000() throws IOException {
         doTestRandomReadWrite(100000);
     }
     
@@ -88,30 +91,34 @@
         byte[] sourceData2 = new byte[2000];
         random.nextBytes(sourceData1);
         random.nextBytes(sourceData2);
-        OverflowBlob tmp = new OverflowBlob(16, 512, "test", ".dat");
-        OutputStream out = tmp.getOutputStream();
-        out.write(sourceData1);
-        out.write(sourceData2);
-        out.close();
-        DataInputStream in = new DataInputStream(tmp.getInputStream());
-        byte[] data1 = new byte[sourceData1.length];
-        byte[] data2 = new byte[sourceData2.length];
-        in.readFully(data1);
-        in.mark(sourceData2.length);
-        in.readFully(data2);
-        in.reset();
-        in.readFully(data2);
-        assertTrue(Arrays.equals(sourceData1, data1));
-        assertTrue(Arrays.equals(sourceData2, data2));
+        WritableBlob blob = createBlob();
+        try {
+            OutputStream out = blob.getOutputStream();
+            out.write(sourceData1);
+            out.write(sourceData2);
+            out.close();
+            DataInputStream in = new DataInputStream(blob.getInputStream());
+            byte[] data1 = new byte[sourceData1.length];
+            byte[] data2 = new byte[sourceData2.length];
+            in.readFully(data1);
+            in.mark(sourceData2.length);
+            in.readFully(data2);
+            in.reset();
+            in.readFully(data2);
+            assertTrue(Arrays.equals(sourceData1, data1));
+            assertTrue(Arrays.equals(sourceData2, data2));
+        } finally {
+            releaseBlob(blob);
+        }
     }
     
     private void testReadFrom(int size) throws IOException {
         byte[] data = new byte[size];
         random.nextBytes(data);
-        OverflowBlob tmp = new OverflowBlob(16, 1024, "test", ".dat");
+        WritableBlob blob = createBlob();
         try {
-            tmp.readFrom(new ByteArrayInputStream(data));
-            InputStream in = tmp.getInputStream();
+            blob.readFrom(new ByteArrayInputStream(data));
+            InputStream in = blob.getInputStream();
             try {
                 assertTrue(Arrays.equals(data, IOUtils.toByteArray(in)));
             }
@@ -120,15 +127,79 @@
             }
         }
         finally {
-            tmp.release();
+            releaseBlob(blob);
         }
     }
     
-    public void testReadFromInMemory() throws IOException {
+    public void testReadFromLength10000() throws IOException {
         testReadFrom(10000);
     }
     
-    public void testReadFromWithTemporaryFile() throws IOException {
+    public void testReadFromLength100000() throws IOException {
         testReadFrom(100000);
     }
+    
+    public void testGetOutputStreamUncommitted() throws Exception {
+        WritableBlob blob = createBlob();
+        try {
+            OutputStream out = blob.getOutputStream();
+            try {
+                try {
+                    blob.getOutputStream();
+                    fail("Expected IllegalStateException");
+                } catch (IllegalStateException ex) {
+                    // Expected
+                }
+            } finally {
+                out.close();
+            }
+        } finally {
+            releaseBlob(blob);
+        }
+    }
+    
+    public void testGetOutputStreamCommitted() throws Exception {
+        WritableBlob blob = createBlob();
+        try {
+            OutputStream out = blob.getOutputStream();
+            out.close();
+            try {
+                blob.getOutputStream();
+                fail("Expected IllegalStateException");
+            } catch (IllegalStateException ex) {
+                // Expected
+            }
+        } finally {
+            releaseBlob(blob);
+        }
+    }
+    
+    public void testGetInputStreamNew() throws Exception {
+        WritableBlob blob = createBlob();
+        try {
+            blob.getInputStream();
+            fail("Expected IllegalStateException");
+        } catch (IllegalStateException ex) {
+            // Expected
+        } finally {
+            releaseBlob(blob);
+        }
+    }
+    
+    public void testGetInputStreamUncommitted() throws Exception {
+        WritableBlob blob = createBlob();
+        try {
+            OutputStream out = blob.getOutputStream();
+            try {
+                blob.getInputStream();
+                fail("Expected IllegalStateException");
+            } catch (IllegalStateException ex) {
+                // Expected
+            } finally {
+                out.close();
+            }
+        } finally {
+            releaseBlob(blob);
+        }
+    }
 }