src/share/classes/javax/sql/rowset/serial/SerialClob.java

Print this page

        

@@ -58,11 +58,11 @@
 
     /**
      * Internal Clob representation if SerialClob is initialized with a
      * Clob. Null if SerialClob is initialized with a char[].
      */
-    private final Clob clob;
+    private Clob clob;
 
     /**
      * The length in characters of this <code>SerialClob</code> object's
      * internal array of characters.
      *

@@ -74,11 +74,13 @@
      * The original length in characters of this <code>SerialClob</code>
      * object's internal array of characters.
      *
      * @serial
      */
-    private final long origLen;
+    private long origLen;
+
+    private boolean isFree =false;
 
     /**
      * Constructs a <code>SerialClob</code> object that is a serialized version of
      * the given <code>char</code> array.
      * <p>

@@ -177,13 +179,15 @@
      * Retrieves the number of characters in this <code>SerialClob</code>
      * object's array of characters.
      *
      * @return a <code>long</code> indicating the length in characters of this
      *         <code>SerialClob</code> object's array of character
-     * @throws SerialException if an error occurs
+     * @throws SerialException if an error occurs or
+     *     called after free() has been called.
      */
     public long length() throws SerialException {
+        isFreed();
         return len;
     }
 
     /**
      * Returns this <code>SerialClob</code> object's data as a stream

@@ -191,13 +195,15 @@
      * a stream is produced regardless of whether the <code>SerialClob</code> object
      * was created with a <code>Clob</code> object or a <code>char</code> array.
      *
      * @return a <code>java.io.Reader</code> object containing this
      *         <code>SerialClob</code> object's data
-     * @throws SerialException if an error occurs
+     * @throws SerialException if an error occurs or
+     *     called after free() has been called.
      */
     public java.io.Reader getCharacterStream() throws SerialException {
+        isFreed();
         return (java.io.Reader) new CharArrayReader(buf);
     }
 
     /**
      * Retrieves the <code>CLOB</code> value designated by this <code>SerialClob</code>

@@ -208,16 +214,19 @@
      * a <code>char</code> array, a <code>SerialException</code> object is thrown.
      *
      * @return a <code>java.io.InputStream</code> object containing
      *     this <code>SerialClob</code> object's data
      * @throws SerialException if this <code>SerialClob</code> object was not instantiated
-     *     with a <code>Clob</code> object
-     * @throws SQLException if there is an error accessing the
+     *     with a <code>Clob</code> object or called after free() has been
+     *     called.
+     * @throws SQLException
+     *             if there is an error accessing the
      *     <code>CLOB</code> value represented by the <code>Clob</code> object that was
      *     used to create this <code>SerialClob</code> object
      */
     public java.io.InputStream getAsciiStream() throws SerialException, SQLException {
+        isFreed();
         if (this.clob != null) {
             return this.clob.getAsciiStream();
         } else {
             throw new SerialException("Unsupported operation. SerialClob cannot " +
                 "return a the CLOB value as an ascii stream, unless instantiated " +

@@ -245,13 +254,15 @@
      *               <code>SerialClob</code> object
      * @return a <code>String</code> object containing a substring of
      *         this <code>SerialClob</code> object beginning at the
      *         given position and containing the specified number of
      *         consecutive characters
-     * @throws SerialException if either of the arguments is out of bounds
+     * @throws SerialException if either of the arguments is out of bounds or called
+     *                         after free() has been called.
      */
     public String getSubString(long pos, int length) throws SerialException {
+        isFreed();
 
         if (pos < 1 || pos > this.length()) {
             throw new SerialException("Invalid position in BLOB object set");
         }
 

@@ -285,15 +296,17 @@
      *         begins, starting the search at the specified position;
      *         <code>-1</code> if the given <code>String</code> object is
      *         not found or the starting position is out of bounds; position
      *         numbering for the return value starts at <code>1</code>
      * @throws SerialException if an error occurs locating the String signature
+     *         or called after free() has been called.
      * @throws SQLException if there is an error accessing the Blob value
      *         from the database.
      */
     public long position(String searchStr, long start)
         throws SerialException, SQLException {
+        isFreed();
 
         if (start < 1 || start > len) {
             return -1;
         }
 

@@ -330,15 +343,17 @@
      *         greater than the length of this <code>SerialClob</code> object
      * @return the position at which the given <code>Clob</code>
      *         object begins in this <code>SerialClob</code> object,
      *         at or after the specified starting position
      * @throws SerialException if an error occurs locating the Clob signature
+     *         or called after free() has been called.
      * @throws SQLException if there is an error accessing the Blob value
      *         from the database
      */
     public long position(Clob searchStr, long start)
         throws SerialException, SQLException {
+        isFreed();
 
         return position(searchStr.getSubString(1,(int)searchStr.length()), start);
     }
 
     /**

@@ -355,13 +370,16 @@
      * @return the number of characters written
      * @throws SerialException if there is an error accessing the
      *     <code>CLOB</code> value; if an invalid position is set; if an
      *     invalid offset value is set; if number of bytes to be written
      *     is greater than the <code>SerialClob</code> length; or the combined
-     *     values of the length and offset is greater than the Clob buffer
+     *     values of the length and offset is greater than the Clob buffer or
+     *     called after free() has been called.
      */
     public int setString(long pos, String str) throws SerialException {
+        isFreed();
+
         return (setString(pos, str, 0, str.length()));
     }
 
     /**
      * Writes <code>len</code> characters of <code>str</code>, starting

@@ -380,14 +398,17 @@
      * @return the number of characters written
      * @throws SerialException if there is an error accessing the
      *     <code>CLOB</code> value; if an invalid position is set; if an
      *     invalid offset value is set; if number of bytes to be written
      *     is greater than the <code>SerialClob</code> length; or the combined
-     *     values of the length and offset is greater than the Clob buffer
+     *     values of the length and offset is greater than the Clob buffer or
+     *     called after free() has been called.
      */
     public int setString(long pos, String str, int offset, int length)
         throws SerialException {
+        isFreed();
+
         String temp = str.substring(offset);
         char cPattern[] = temp.toCharArray();
 
         if (offset < 0 || offset > str.length()) {
             throw new SerialException("Invalid offset in byte array set");

@@ -427,17 +448,20 @@
      *
      * @param pos the position at which to start writing to the
      *        <code>CLOB</code> object
      * @return the stream to which ASCII encoded characters can be written
      * @throws SerialException if SerialClob is not instantiated with a
-     *     Clob object that supports <code>setAsciiStream</code>
+     *     Clob object that supports <code>setAsciiStream</code> or
+     *     called after free() has been called.
      * @throws SQLException if there is an error accessing the
      *     <code>CLOB</code> value
      * @see #getAsciiStream
      */
     public java.io.OutputStream setAsciiStream(long pos)
         throws SerialException, SQLException {
+        isFreed();
+
          if (this.clob != null) {
              return this.clob.setAsciiStream(pos);
          } else {
              throw new SerialException("Unsupported operation. SerialClob cannot " +
                 "return a writable ascii stream\n unless instantiated with a Clob object " +

@@ -457,17 +481,20 @@
      * @param  pos the position at which to start writing to the
      *        <code>CLOB</code> value
      *
      * @return a stream to which Unicode encoded characters can be written
      * @throws SerialException if the SerialClob is not instantiated with
-     *     a Clob object that supports <code>setCharacterStream</code>
+     *     a Clob object that supports <code>setCharacterStream</code> or
+     *     called after free() has been called.
      * @throws SQLException if there is an error accessing the
      *            <code>CLOB</code> value
      * @see #getCharacterStream
      */
     public java.io.Writer setCharacterStream(long pos)
         throws SerialException, SQLException {
+        isFreed();
+
         if (this.clob != null) {
             return this.clob.setCharacterStream(pos);
         } else {
             throw new SerialException("Unsupported operation. SerialClob cannot " +
                 "return a writable character stream\n unless instantiated with a Clob object " +

@@ -485,35 +512,101 @@
      *
      * @param length the length, in bytes, to which the <code>CLOB</code>
      *        value should be truncated
      * @throws SQLException if there is an error accessing the
      *        <code>CLOB</code> value
+     * @throws SerialException if called after free() has been called.
      */
     public void truncate(long length) throws SerialException {
+        isFreed();
+
          if (length > len) {
-            throw new SerialException
-               ("Length more than what can be truncated");
+            throw new SerialException("Length more than what can be truncated");
          } else {
               len = length;
               // re-size the buffer
 
               if (len == 0) {
                   buf = new char[] {};
               } else {
-                buf = (this.getSubString(1, (int)len)).toCharArray();
+                buf = (this.getSubString(1, (int) len)).toCharArray();
               }
 
          }
     }
 
-
+    /**
+     * Returns a <code>Reader</code> object that contains a partial
+     * <code>Clob</code> value, starting with the character specified by
+     * pos, which is length characters in length.
+     *
+     * @param pos
+     *            the offset to the first character of the partial value
+     *            to be retrieved. The first character in the
+     *            <code>Clob</code> is at position 1.
+     * @param length
+     *            the length in characters of the partial value to be
+     *            retrieved.
+     *
+     * @return Reader through which the partial <code>Clob</code> value
+     *         can be read.
+     * @throws SQLException
+     *             if pos is less than 1 or if pos is greater than the
+     *             number of characters in the <code>Clob</code> or if
+     *             pos + length is greater than the number of characters
+     *             in the <code>Clob</code>
+     * @throws SQLFeatureNotSupportedException
+     *             if the JDBC driver does not support this method
+     * @throws SerialException if called after free() has been called.
+     */
     public Reader getCharacterStream(long pos, long length) throws SQLException {
-        throw new java.lang.UnsupportedOperationException("Not supported");
+        isFreed();
+
+        if (pos < 1 || pos > len) {
+            throw new SerialException("Invalid pos in getCharacterStream");
+        }
+        if ((pos - 1) + length > len) {
+            throw new SerialException("pos + length greater than total number of bytes");
+        }
+        return (java.io.Reader) new CharArrayReader(buf, (int) pos -1, (int)length);
     }
 
+    /**
+     * This method frees the <code>Clob</code> object and releases the
+     * resources the resources that it holds. The object is invalid once
+     * the <code>free</code> method is called. After <code>free</code>
+     * has been called, any attempt to invoke a method other than
+     * <code>free</code> will result in a <code>SQLException</code> being
+     * thrown. If <code>free</code> is called multiple times, the
+     * subsequent calls to <code>free<c/ode> are treated as a no-op.
+     *
+     * @throws SQLException if an error occurs releasing the <code>Clob</code>'s
+     *          resources
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does
+     *          not support this method
+     */
     public void free() throws SQLException {
-        throw new java.lang.UnsupportedOperationException("Not supported");
+        if (isFree == false) {
+            len = -1;
+            origLen = -1;
+            buf = null;
+
+            if (clob != null) {
+                clob.free();
+                clob = null;
+            }
+
+            isFree = true;
+        }
+    }
+
+    private void isFreed() throws SerialException {
+        if (isFree == true) {
+            throw new SerialException(
+                    "Unsupported operation. SerialClob cannot "
+                            + "execute this operation when it has already been freed by free()");
+        }
     }
 
     /**
          * The identifier that assists in the serialization of this <code>SerialClob</code>
      * object.