db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r722443 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
Date Tue, 02 Dec 2008 12:48:28 GMT
Author: kristwaa
Date: Tue Dec  2 04:48:27 2008
New Revision: 722443

URL: http://svn.apache.org/viewvc?rev=722443&view=rev
Log:
DERBY-3936: Add CharacterStreamDescriptor.
Extended the functionality;
 o added a stream reference to the descriptor
 o added a method to return a PositionedStream reference to the InputStream
 o added a method to the builder to copy the values of another builder
 o added a few more sanity checks (sane builds only)
 o updated tests 
Patch file: derby-3936-4b-streamref_and_copy.diff

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java?rev=722443&r1=722442&r2=722443&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
Tue Dec  2 04:48:27 2008
@@ -20,7 +20,9 @@
  */
 package org.apache.derby.iapi.jdbc;
 
+import java.io.InputStream;
 import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.types.PositionedStream;
 
 /**
  * A description of a byte stream representing characters. The description is
@@ -63,8 +65,8 @@
     private final boolean bufferable;
     /** Tells if the stream is aware of its own position. */
     private final boolean positionAware;
-    /** A (mostly) unique id for the associated stream. */
-    private final int id;
+    /** Reference to the stream we are describing. */
+    private final InputStream stream;
 
     /**
      * Creates a character stream descriptor, using the supplied builder.
@@ -83,7 +85,7 @@
         byteLength = b.byteLength;
         charLength = b.charLength;
         maxCharLength = b.maxCharLength;
-        id = b.id;
+        stream = b.stream;
     }
 
     /**
@@ -157,16 +159,33 @@
     public long getMaxCharLength() {
         return maxCharLength;
     }
-    
+
     /**
-     * Returns an id that can be used to identify the associated stream.
-     * <p>
-     * Mostly used for debugging and verification purposes.
+     * Returns the associated stream.
+     *
+     * @return An {@code InputStream} reference.
+     */
+    public InputStream getStream() {
+        return stream;
+    }
+
+    /**
+     * Returns the associated positioned stream, if the stream is position
+     * aware.
      *
-     * @return An integer id.
+     * @return A {@code PositionedStream} reference.
+     * @throws ClassCastException if the stream cannot be cast to
+     *      {@code PositionedStream}
+     * @throws IllegalArgumentException if the method is called and the
+     *      assoicated stream isn't described as position aware.
+     * @see #isPositionAware
      */
-    public int getStreamId() {
-        return id;
+    public PositionedStream getPositionedStream() {
+        if (!positionAware) {
+            throw new IllegalStateException("stream is not position aware: " +
+                    stream.getClass().getName());
+        }
+        return (PositionedStream)stream;
     }
 
     public String toString() {
@@ -174,7 +193,8 @@
                 bufferable + ":positionAware=" +
                 positionAware + ":byteLength=" + byteLength + ":charLength=" +
                 charLength + ":curBytePos=" + curBytePos + ":curCharPos=" +
-                curCharPos + ":dataOffset=" + dataOffset + ":id=" + id);
+                curCharPos + ":dataOffset=" + dataOffset + ":stream=" +
+                stream.getClass());
     }
 
     /**
@@ -198,7 +218,7 @@
         private long charLength = 0;
         private long dataOffset = 0;
         private long maxCharLength = DEFAULT_MAX_CHAR_LENGTH;
-        private int id = -1;
+        private InputStream stream;
 
         /**
          * Creates a builder object.
@@ -270,6 +290,25 @@
         }
 
         /**
+         * Copies the state of the specified descriptor.
+         *
+         * @param csd the descriptor to copy
+         * @return The builder.
+         */
+        public Builder copyState(CharacterStreamDescriptor csd) {
+            this.bufferable = csd.bufferable;
+            this.byteLength = csd.byteLength;
+            this.charLength = csd.charLength;
+            this.curBytePos = csd.curBytePos;
+            this.curCharPos = csd.curCharPos;
+            this.dataOffset = csd.dataOffset;
+            this.maxCharLength = csd.maxCharLength;
+            this.positionAware = csd.positionAware;
+            this.stream = csd.stream;
+            return this;
+        }
+
+        /**
          * Sets the character length of the stream, defaults to {@code 0}.
          * <p>
          * Headers are not included in this length, only the user data.
@@ -306,8 +345,19 @@
             return this;
         }
 
-        public Builder id(int id) {
-            this.id = id;
+        /**
+         * Sets the stream described by the descriptor.
+         * <p>
+         * The stream is not allowed to be {@code null}.
+         *
+         * @param stream the stream
+         * @return The builder.
+         */
+        public Builder stream(InputStream stream) {
+            if (SanityManager.DEBUG) {
+                SanityManager.ASSERT(stream != null);
+            }
+            this.stream = stream;
             return this;
         }
 
@@ -347,6 +397,18 @@
                 if (curBytePos < dataOffset) {
                     SanityManager.ASSERT(curCharPos == BEFORE_FIRST);
                 }
+                // Byte length minus data offset must be equal to or greater
+                // then the character length.
+                if (byteLength > 0 && charLength > 0) {
+                    SanityManager.ASSERT(byteLength - dataOffset >= charLength);
+                }
+                SanityManager.ASSERT(stream != null, "Stream cannot be null");
+                if (positionAware) {
+                    SanityManager.ASSERT(stream instanceof PositionedStream);
+                }
+                // Note that the character position can be greater than the
+                // maximum character length, because the limit might be imposed
+                // as part of extracting a substring of the contents.
             }
             return new CharacterStreamDescriptor(this);
         }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java?rev=722443&r1=722442&r2=722443&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
Tue Dec  2 04:48:27 2008
@@ -20,9 +20,14 @@
  */
 package org.apache.derbyTesting.unitTests.junit;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import junit.framework.Test;
 import junit.framework.TestSuite;
+import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.jdbc.CharacterStreamDescriptor;
+import org.apache.derby.iapi.types.PositionedStream;
 import org.apache.derbyTesting.junit.BaseTestCase;
 
 /**
@@ -39,8 +44,9 @@
      * Tests the default values set by the builder.
      */
     public void testDefaultValues() {
+        InputStream emptyStream = new ByteArrayInputStream(new byte[] {});
         CharacterStreamDescriptor.Builder b =
-                new CharacterStreamDescriptor.Builder();
+                new CharacterStreamDescriptor.Builder().stream(emptyStream);
         CharacterStreamDescriptor csd = b.build();
 
         // Test the default values.
@@ -52,23 +58,23 @@
         assertEquals(0, csd.getByteLength());
         assertEquals(0, csd.getCharLength());
         assertEquals(Long.MAX_VALUE, csd.getMaxCharLength());
-        assertEquals(-1, csd.getStreamId());
     }
 
     public void testSetValues() {
-        final long byteLength = 1023;
-        final long charLength = 1023*2;
+        final long charLength = 1023;
+        final long byteLength = 1023*2;
         final long curBytePos = 4;
         final long curCharPos = 2;
         final long dataOffset = 2;
-        final long maxCharLen = 768;
-        final int streamId = this.hashCode();
+        final long maxCharLen = 2459;
+        InputStream emptyStream = new ByteArrayInputStream(new byte[] {});
 
         CharacterStreamDescriptor.Builder b =
                 new CharacterStreamDescriptor.Builder().bufferable(true).
                 byteLength(byteLength).charLength(charLength).
                 curBytePos(curBytePos).curCharPos(curCharPos).
-                dataOffset(dataOffset).maxCharLength(maxCharLen).id(streamId);
+                dataOffset(dataOffset).maxCharLength(maxCharLen).
+                stream(emptyStream);
         CharacterStreamDescriptor csd = b.build();
 
         // Test the values.
@@ -80,11 +86,12 @@
         assertEquals(byteLength, csd.getByteLength());
         assertEquals(charLength, csd.getCharLength());
         assertEquals(maxCharLen, csd.getMaxCharLength());
-        assertEquals(streamId, csd.getStreamId());
 
+        PositionedStream emptyPS = new PositionedTestStream(curBytePos);
         // Set only a few values.
         csd = new CharacterStreamDescriptor.Builder().bufferable(true).
-                positionAware(true). maxCharLength(maxCharLen).build();
+                positionAware(true). maxCharLength(maxCharLen).
+                stream(emptyPS.asInputStream()).build();
         assertEquals(true, csd.isBufferable());
         assertEquals(true, csd.isPositionAware());
         assertEquals(maxCharLen, csd.getMaxCharLength());
@@ -92,7 +99,8 @@
         // Set data offset and update the character position accordingly.
         csd = new CharacterStreamDescriptor.Builder().bufferable(true).
                 positionAware(true).dataOffset(dataOffset).
-                curCharPos(CharacterStreamDescriptor.BEFORE_FIRST).build();
+                curCharPos(CharacterStreamDescriptor.BEFORE_FIRST).
+                stream(emptyPS.asInputStream()).build();
         assertEquals(true, csd.isBufferable());
         assertEquals(true, csd.isPositionAware());
         assertEquals(dataOffset, csd.getDataOffset());
@@ -101,8 +109,89 @@
 
     }
 
+    public void testCopyState() {
+        final long charLength = 1023;
+        final long byteLength = 1023*2;
+        final long curBytePos = 4;
+        final long curCharPos = 2;
+        final long dataOffset = 2;
+        final long maxCharLen = 3021;
+        InputStream emptyStream = new ByteArrayInputStream(new byte[] {});
+
+        CharacterStreamDescriptor.Builder b1 =
+                new CharacterStreamDescriptor.Builder().bufferable(true).
+                byteLength(byteLength).charLength(charLength).
+                curBytePos(curBytePos).curCharPos(curCharPos).
+                dataOffset(dataOffset).maxCharLength(maxCharLen).
+                stream(emptyStream);
+        CharacterStreamDescriptor csd1 = b1.build();
+        CharacterStreamDescriptor.Builder b2 =
+                new CharacterStreamDescriptor.Builder().copyState(csd1);
+        CharacterStreamDescriptor csd2 = b2.build();
+
+        // Test the values.
+        assertEquals(csd2.isBufferable(), csd1.isBufferable());
+        assertEquals(csd2.isPositionAware(), csd1.isPositionAware());
+        assertEquals(csd2.getDataOffset(), csd1.getDataOffset());
+        assertEquals(csd2.getCurBytePos(), csd1.getCurBytePos());
+        assertEquals(csd2.getCurCharPos(), csd1.getCurCharPos());
+        assertEquals(csd2.getByteLength(), csd1.getByteLength());
+        assertEquals(csd2.getCharLength(), csd1.getCharLength());
+        assertEquals(csd2.getMaxCharLength(), csd1.getMaxCharLength());
+        assertTrue(csd2.getStream() == csd1.getStream());
+
+        // Override one value.
+        CharacterStreamDescriptor.Builder b3 =
+                new CharacterStreamDescriptor.Builder().copyState(csd1).
+                maxCharLength(8765);
+        CharacterStreamDescriptor csd3 = b3.build();
+        assertEquals(8765, csd3.getMaxCharLength());
+
+        // Demonstrate that copying the state after setting a value explicitly
+        // overwrites the the set value.
+        CharacterStreamDescriptor.Builder b4 =
+                new CharacterStreamDescriptor.Builder().
+                maxCharLength(8765).
+                copyState(csd1);
+        CharacterStreamDescriptor csd4 = b4.build();
+        assertEquals(csd1.getMaxCharLength(), csd4.getMaxCharLength());
+    }
+
     public static Test suite() {
         return new TestSuite(CharacterStreamDescriptorTest.class,
                 "CharacterStreamDescriptorTest suite");
     }
-}
+
+    /**
+     * A test stream that implements the {@code PositionedStream} interface.
+     * The stream is not functional, it always returns {@code -1}.
+     */
+    private static class PositionedTestStream
+            extends InputStream
+            implements PositionedStream {
+
+            private final long pos;
+
+            PositionedTestStream(long pos) {
+                this.pos = pos;
+            }
+
+            public int read() throws IOException {
+                return -1;
+            }
+
+            public InputStream asInputStream() {
+                return this;
+            }
+
+            public long getPosition() {
+                // Return the position specified in constructor.
+                return pos;
+            }
+
+            public void reposition(long requestedPos)
+                    throws IOException, StandardException {
+                // Do nothing, this is not a functional stream.
+            }
+        }
+    }



Mime
View raw message