--- old/src/share/classes/javax/sql/rowset/serial/SerialClob.java 2012-09-21 10:59:38.754229654 +0800 +++ new/src/share/classes/javax/sql/rowset/serial/SerialClob.java 2012-09-21 10:59:38.610229651 +0800 @@ -60,7 +60,7 @@ * 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 SerialClob object's @@ -76,7 +76,9 @@ * * @serial */ - private final long origLen; + private long origLen; + + private boolean isFree =false; /** * Constructs a SerialClob object that is a serialized version of @@ -179,9 +181,11 @@ * * @return a long indicating the length in characters of this * SerialClob 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; } @@ -193,9 +197,11 @@ * * @return a java.io.Reader object containing this * SerialClob 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); } @@ -210,12 +216,15 @@ * @return a java.io.InputStream object containing * this SerialClob object's data * @throws SerialException if this SerialClob object was not instantiated - * with a Clob object - * @throws SQLException if there is an error accessing the + * with a Clob object or called after free() has been + * called. + * @throws SQLException + * if there is an error accessing the * CLOB value represented by the Clob object that was * used to create this SerialClob object */ public java.io.InputStream getAsciiStream() throws SerialException, SQLException { + isFreed(); if (this.clob != null) { return this.clob.getAsciiStream(); } else { @@ -247,9 +256,11 @@ * this SerialClob 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"); @@ -287,11 +298,13 @@ * not found or the starting position is out of bounds; position * numbering for the return value starts at 1 * @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; @@ -332,11 +345,13 @@ * object begins in this SerialClob 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); } @@ -357,9 +372,12 @@ * CLOB 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 SerialClob 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())); } @@ -382,10 +400,13 @@ * CLOB 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 SerialClob 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(); @@ -429,13 +450,16 @@ * CLOB 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 setAsciiStream + * Clob object that supports setAsciiStream or + * called after free() has been called. * @throws SQLException if there is an error accessing the * CLOB value * @see #getAsciiStream */ public java.io.OutputStream setAsciiStream(long pos) throws SerialException, SQLException { + isFreed(); + if (this.clob != null) { return this.clob.setAsciiStream(pos); } else { @@ -459,13 +483,16 @@ * * @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 setCharacterStream + * a Clob object that supports setCharacterStream or + * called after free() has been called. * @throws SQLException if there is an error accessing the * CLOB value * @see #getCharacterStream */ public java.io.Writer setCharacterStream(long pos) throws SerialException, SQLException { + isFreed(); + if (this.clob != null) { return this.clob.setCharacterStream(pos); } else { @@ -487,31 +514,97 @@ * value should be truncated * @throws SQLException if there is an error accessing the * CLOB value + * @throws SerialException if called after free() has been called. */ public void truncate(long length) throws SerialException { - if (length > len) { - throw new SerialException - ("Length more than what can be truncated"); - } else { - len = length; - // re-size the buffer + isFreed(); - if (len == 0) { - buf = new char[] {}; - } else { - buf = (this.getSubString(1, (int)len)).toCharArray(); - } + if (length > len) { + 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(); + } + } + } + /** + * Returns a Reader object that contains a partial + * Clob 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 + * Clob is at position 1. + * @param length + * the length in characters of the partial value to be + * retrieved. + * + * @return Reader through which the partial Clob value + * can be read. + * @throws SQLException + * if pos is less than 1 or if pos is greater than the + * number of characters in the Clob or if + * pos + length is greater than the number of characters + * in the Clob + * @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 Clob object and releases the + * resources the resources that it holds. The object is invalid once + * the free method is called. After free + * has been called, any attempt to invoke a method other than + * free will result in a SQLException being + * thrown. If free is called multiple times, the + * subsequent calls to free are treated as a no-op. + * + * @throws SQLException if an error occurs releasing the Clob'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()"); + } } /**