提交 159ea60b 编写于 作者: L lancea

8004357: Implement various methods in SerialBlob/Clob/Array and specify Thread Safety

Reviewed-by: naoto
上级 c597db0e
...@@ -31,6 +31,7 @@ import java.util.Map; ...@@ -31,6 +31,7 @@ import java.util.Map;
import java.net.URL; import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
/** /**
* A serialized version of an <code>Array</code> * A serialized version of an <code>Array</code>
* object, which is the mapping in the Java programming language of an SQL * object, which is the mapping in the Java programming language of an SQL
...@@ -41,12 +42,20 @@ import java.util.Arrays; ...@@ -41,12 +42,20 @@ import java.util.Arrays;
* methods for getting the base type and the SQL name for the base type, and * methods for getting the base type and the SQL name for the base type, and
* methods for copying all or part of a <code>SerialArray</code> object. * methods for copying all or part of a <code>SerialArray</code> object.
* <P> * <P>
*
* Note: In order for this class to function correctly, a connection to the * Note: In order for this class to function correctly, a connection to the
* data source * data source
* must be available in order for the SQL <code>Array</code> object to be * must be available in order for the SQL <code>Array</code> object to be
* materialized (have all of its elements brought to the client server) * materialized (have all of its elements brought to the client server)
* if necessary. At this time, logical pointers to the data in the data source, * if necessary. At this time, logical pointers to the data in the data source,
* such as locators, are not currently supported. * such as locators, are not currently supported.
*
* <h4> Thread safety </h4>
*
* A SerialArray is not safe for use by multiple concurrent threads. If a
* SerialArray is to be used by more than one thread then access to the
* SerialArray should be controlled by appropriate synchronization.
*
*/ */
public class SerialArray implements Array, Serializable, Cloneable { public class SerialArray implements Array, Serializable, Cloneable {
...@@ -192,24 +201,19 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -192,24 +201,19 @@ public class SerialArray implements Array, Serializable, Cloneable {
} }
/** /**
* This method frees the <code>Array</code> object and releases the resources that * This method frees the {@code SeriableArray} object and releases the
* it holds. The object is invalid once the <code>free</code> * resources that it holds. The object is invalid once the {@code free}
* method is called. * method is called. <p> If {@code free} is called multiple times, the
*<p> * subsequent calls to {@code free} are treated as a no-op. </P>
* 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</code> are treated as a no-op.
*<p>
* *
* @throws SQLException if an error occurs releasing * @throws SQLException if an error occurs releasing the SerialArray's resources
* the Array's resources
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since 1.6 * @since 1.6
*/ */
public void free() throws SQLException { public void free() throws SQLException {
throw new SQLFeatureNotSupportedException("Feature not supported"); if (elements != null) {
elements = null;
baseTypeName= null;
}
} }
/** /**
...@@ -298,10 +302,11 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -298,10 +302,11 @@ public class SerialArray implements Array, Serializable, Cloneable {
* *
* @return a copy of this <code>SerialArray</code> object as an * @return a copy of this <code>SerialArray</code> object as an
* <code>Object</code> in the Java programming language * <code>Object</code> in the Java programming language
* @throws SerialException if an error occurs retrieving a copy of * @throws SerialException if an error occurs;
* this <code>SerialArray</code> object * if {@code free} had previously been called on this object
*/ */
public Object getArray() throws SerialException { public Object getArray() throws SerialException {
isValid();
Object dst = new Object[len]; Object dst = new Object[len];
System.arraycopy((Object)elements, 0, dst, 0, len); System.arraycopy((Object)elements, 0, dst, 0, len);
return dst; return dst;
...@@ -328,9 +333,11 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -328,9 +333,11 @@ public class SerialArray implements Array, Serializable, Cloneable {
* that defines how the UDT is to be mapped * that defines how the UDT is to be mapped
* @return a copy of this <code>SerialArray</code> object as an * @return a copy of this <code>SerialArray</code> object as an
* <code>Object</code> in the Java programming language * <code>Object</code> in the Java programming language
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public Object getArray(Map<String, Class<?>> map) throws SerialException { public Object getArray(Map<String, Class<?>> map) throws SerialException {
isValid();
Object dst[] = new Object[len]; Object dst[] = new Object[len];
System.arraycopy((Object)elements, 0, dst, 0, len); System.arraycopy((Object)elements, 0, dst, 0, len);
return dst; return dst;
...@@ -349,9 +356,11 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -349,9 +356,11 @@ public class SerialArray implements Array, Serializable, Cloneable {
* at the given index * at the given index
* @return a copy of the designated elements in this <code>SerialArray</code> * @return a copy of the designated elements in this <code>SerialArray</code>
* object as an <code>Object</code> in the Java programming language * object as an <code>Object</code> in the Java programming language
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public Object getArray(long index, int count) throws SerialException { public Object getArray(long index, int count) throws SerialException {
isValid();
Object dst = new Object[count]; Object dst = new Object[count];
System.arraycopy((Object)elements, (int)index, dst, 0, count); System.arraycopy((Object)elements, (int)index, dst, 0, count);
return dst; return dst;
...@@ -383,11 +392,13 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -383,11 +392,13 @@ public class SerialArray implements Array, Serializable, Cloneable {
* that defines how the UDT is to be mapped * that defines how the UDT is to be mapped
* @return a copy of the designated elements in this <code>SerialArray</code> * @return a copy of the designated elements in this <code>SerialArray</code>
* object as an <code>Object</code> in the Java programming language * object as an <code>Object</code> in the Java programming language
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public Object getArray(long index, int count, Map<String,Class<?>> map) public Object getArray(long index, int count, Map<String,Class<?>> map)
throws SerialException throws SerialException
{ {
isValid();
Object dst = new Object[count]; Object dst = new Object[count];
System.arraycopy((Object)elements, (int)index, dst, 0, count); System.arraycopy((Object)elements, (int)index, dst, 0, count);
return dst; return dst;
...@@ -400,9 +411,11 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -400,9 +411,11 @@ public class SerialArray implements Array, Serializable, Cloneable {
* *
* @return one of the constants in <code>java.sql.Types</code>, indicating * @return one of the constants in <code>java.sql.Types</code>, indicating
* the SQL type of the elements in this <code>SerialArray</code> object * the SQL type of the elements in this <code>SerialArray</code> object
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public int getBaseType() throws SerialException { public int getBaseType() throws SerialException {
isValid();
return baseType; return baseType;
} }
...@@ -412,9 +425,11 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -412,9 +425,11 @@ public class SerialArray implements Array, Serializable, Cloneable {
* *
* @return the SQL type name used by the DBMS for the base type of this * @return the SQL type name used by the DBMS for the base type of this
* <code>SerialArray</code> object * <code>SerialArray</code> object
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public String getBaseTypeName() throws SerialException { public String getBaseTypeName() throws SerialException {
isValid();
return baseTypeName; return baseTypeName;
} }
...@@ -434,11 +449,13 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -434,11 +449,13 @@ public class SerialArray implements Array, Serializable, Cloneable {
* @return a <code>ResultSet</code> object containing the designated * @return a <code>ResultSet</code> object containing the designated
* elements in this <code>SerialArray</code> object, with a * elements in this <code>SerialArray</code> object, with a
* separate row for each element * separate row for each element
* @throws SerialException, which in turn throws an * @throws SerialException if called with the cause set to
* <code>UnsupportedOperationException</code>, if this method is called * {@code UnsupportedOperationException}
*/ */
public ResultSet getResultSet(long index, int count) throws SerialException { public ResultSet getResultSet(long index, int count) throws SerialException {
throw new UnsupportedOperationException(); SerialException se = new SerialException();
se.initCause(new UnsupportedOperationException());
throw se;
} }
/** /**
...@@ -461,13 +478,15 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -461,13 +478,15 @@ public class SerialArray implements Array, Serializable, Cloneable {
* @return a <code>ResultSet</code> object containing all of the * @return a <code>ResultSet</code> object containing all of the
* elements in this <code>SerialArray</code> object, with a * elements in this <code>SerialArray</code> object, with a
* separate row for each element * separate row for each element
* @throws SerialException, which in turn throws an * @throws SerialException if called with the cause set to
* <code>UnsupportedOperationException</code>, if this method is called * {@code UnsupportedOperationException}
*/ */
public ResultSet getResultSet(Map<String, Class<?>> map) public ResultSet getResultSet(Map<String, Class<?>> map)
throws SerialException throws SerialException
{ {
throw new UnsupportedOperationException(); SerialException se = new SerialException();
se.initCause(new UnsupportedOperationException());
throw se;
} }
/** /**
...@@ -480,11 +499,13 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -480,11 +499,13 @@ public class SerialArray implements Array, Serializable, Cloneable {
* @return a <code>ResultSet</code> object containing all of the * @return a <code>ResultSet</code> object containing all of the
* elements in this <code>SerialArray</code> object, with a * elements in this <code>SerialArray</code> object, with a
* separate row for each element * separate row for each element
* @throws SerialException if called, which in turn throws an * @throws SerialException if called with the cause set to
* <code>UnsupportedOperationException</code>, if this method is called * {@code UnsupportedOperationException}
*/ */
public ResultSet getResultSet() throws SerialException { public ResultSet getResultSet() throws SerialException {
throw new UnsupportedOperationException(); SerialException se = new SerialException();
se.initCause(new UnsupportedOperationException());
throw se;
} }
...@@ -514,16 +535,19 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -514,16 +535,19 @@ public class SerialArray implements Array, Serializable, Cloneable {
* @return a <code>ResultSet</code> object containing the designated * @return a <code>ResultSet</code> object containing the designated
* elements in this <code>SerialArray</code> object, with a * elements in this <code>SerialArray</code> object, with a
* separate row for each element * separate row for each element
* @throws SerialException if called, which in turn throws an * @throws SerialException if called with the cause set to
* <code>UnsupportedOperationException</code> * {@code UnsupportedOperationException}
*/ */
public ResultSet getResultSet(long index, int count, public ResultSet getResultSet(long index, int count,
Map<String,Class<?>> map) Map<String,Class<?>> map)
throws SerialException throws SerialException
{ {
throw new UnsupportedOperationException(); SerialException se = new SerialException();
se.initCause(new UnsupportedOperationException());
throw se;
} }
/** /**
* Compares this SerialArray to the specified object. The result is {@code * Compares this SerialArray to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code * true} if and only if the argument is not {@code null} and is a {@code
...@@ -571,7 +595,7 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -571,7 +595,7 @@ public class SerialArray implements Array, Serializable, Cloneable {
public Object clone() { public Object clone() {
try { try {
SerialArray sa = (SerialArray) super.clone(); SerialArray sa = (SerialArray) super.clone();
sa.elements = Arrays.copyOf(elements, len); sa.elements = (elements != null) ? Arrays.copyOf(elements, len) : null;
return sa; return sa;
} catch (CloneNotSupportedException ex) { } catch (CloneNotSupportedException ex) {
// this shouldn't happen, since we are Cloneable // this shouldn't happen, since we are Cloneable
...@@ -615,6 +639,19 @@ public class SerialArray implements Array, Serializable, Cloneable { ...@@ -615,6 +639,19 @@ public class SerialArray implements Array, Serializable, Cloneable {
s.writeFields(); s.writeFields();
} }
/**
* Check to see if this object had previously had its {@code free} method
* called
*
* @throws SerialException
*/
private void isValid() throws SerialException {
if (elements == null) {
throw new SerialException("Error: You cannot call a method on a "
+ "SerialArray instance once free() has been called.");
}
}
/** /**
* The identifier that assists in the serialization of this <code>SerialArray</code> * The identifier that assists in the serialization of this <code>SerialArray</code>
* object. * object.
......
...@@ -51,6 +51,12 @@ import java.util.Arrays; ...@@ -51,6 +51,12 @@ import java.util.Arrays;
* <code>Blob</code> object within a <code>SerialBlob</code> object * <code>Blob</code> object within a <code>SerialBlob</code> object
* and to update or truncate a <code>Blob</code> object. * and to update or truncate a <code>Blob</code> object.
* *
* <h4> Thread safety </h4>
*
* <p> A SerialBlob is not safe for use by multiple concurrent threads. If a
* SerialBlob is to be used by more than one thread then access to the SerialBlob
* should be controlled by appropriate synchronization.
*
* @author Jonathan Bruce * @author Jonathan Bruce
*/ */
public class SerialBlob implements Blob, Serializable, Cloneable { public class SerialBlob implements Blob, Serializable, Cloneable {
...@@ -76,7 +82,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -76,7 +82,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
private long len; private long len;
/** /**
* The orginal number of bytes in this <code>SerialBlob</code> object's * The original number of bytes in this <code>SerialBlob</code> object's
* array of bytes when it was first established. * array of bytes when it was first established.
* @serial * @serial
*/ */
...@@ -160,9 +166,11 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -160,9 +166,11 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* @return an array of bytes that is a copy of a region of this * @return an array of bytes that is a copy of a region of this
* <code>SerialBlob</code> object, starting at the given * <code>SerialBlob</code> object, starting at the given
* position and containing the given number of consecutive bytes * position and containing the given number of consecutive bytes
* @throws SerialException if the given starting position is out of bounds * @throws SerialException if the given starting position is out of bounds;
* if {@code free} had previously been called on this object
*/ */
public byte[] getBytes(long pos, int length) throws SerialException { public byte[] getBytes(long pos, int length) throws SerialException {
isValid();
if (length > len) { if (length > len) {
length = (int)len; length = (int)len;
} }
...@@ -189,9 +197,11 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -189,9 +197,11 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* *
* @return a <code>long</code> indicating the length in bytes of this * @return a <code>long</code> indicating the length in bytes of this
* <code>SerialBlob</code> object's array of bytes * <code>SerialBlob</code> object's array of bytes
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public long length() throws SerialException { public long length() throws SerialException {
isValid();
return len; return len;
} }
...@@ -203,10 +213,12 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -203,10 +213,12 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* *
* @return a <code>java.io.InputStream</code> object that contains * @return a <code>java.io.InputStream</code> object that contains
* this <code>SerialBlob</code> object's array of bytes * this <code>SerialBlob</code> object's array of bytes
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
* @see #setBinaryStream * @see #setBinaryStream
*/ */
public java.io.InputStream getBinaryStream() throws SerialException { public java.io.InputStream getBinaryStream() throws SerialException {
isValid();
InputStream stream = new ByteArrayInputStream(buf); InputStream stream = new ByteArrayInputStream(buf);
return stream; return stream;
} }
...@@ -227,12 +239,14 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -227,12 +239,14 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* position; <code>-1</code> if the pattern is not found * position; <code>-1</code> if the pattern is not found
* or the given starting position is out of bounds; position * or the given starting position is out of bounds; position
* numbering for the return value starts at <code>1</code> * numbering for the return value starts at <code>1</code>
* @throws SerialException if an error occurs when serializing the blob * @throws SerialException if an error occurs when serializing the blob;
* if {@code free} had previously been called on this object
* @throws SQLException if there is an error accessing the <code>BLOB</code> * @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database * value from the database
*/ */
public long position(byte[] pattern, long start) public long position(byte[] pattern, long start)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
if (start < 1 || start > len) { if (start < 1 || start > len) {
return -1; return -1;
} }
...@@ -270,12 +284,14 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -270,12 +284,14 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* at the specified position; <code>-1</code> if the pattern is * at the specified position; <code>-1</code> if the pattern is
* not found or the given starting position is out of bounds; * not found or the given starting position is out of bounds;
* position numbering for the return value starts at <code>1</code> * position numbering for the return value starts at <code>1</code>
* @throws SerialException if an error occurs when serializing the blob * @throws SerialException if an error occurs when serializing the blob;
* if {@code free} had previously been called on this object
* @throws SQLException if there is an error accessing the <code>BLOB</code> * @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database * value from the database
*/ */
public long position(Blob pattern, long start) public long position(Blob pattern, long start)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
return position(pattern.getBytes(1, (int)(pattern.length())), start); return position(pattern.getBytes(1, (int)(pattern.length())), start);
} }
...@@ -293,7 +309,8 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -293,7 +309,8 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* @return the number of bytes written * @return the number of bytes written
* @throws SerialException if there is an error accessing the * @throws SerialException if there is an error accessing the
* <code>BLOB</code> value; or if an invalid position is set; if an * <code>BLOB</code> value; or if an invalid position is set; if an
* invalid offset value is set * invalid offset value is set;
* if {@code free} had previously been called on this object
* @throws SQLException if there is an error accessing the <code>BLOB</code> * @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database * value from the database
* @see #getBytes * @see #getBytes
...@@ -328,7 +345,8 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -328,7 +345,8 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* <code>BLOB</code> value; if an invalid position is set; if an * <code>BLOB</code> value; if an invalid position is set; if an
* invalid offset value is set; if number of bytes to be written * invalid offset value is set; if number of bytes to be written
* is greater than the <code>SerialBlob</code> length; or the combined * is greater than the <code>SerialBlob</code> length; or the combined
* values of the length and offset is greater than the Blob buffer * values of the length and offset is greater than the Blob buffer;
* if {@code free} had previously been called on this object
* @throws SQLException if there is an error accessing the <code>BLOB</code> * @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database. * value from the database.
* @see #getBytes * @see #getBytes
...@@ -336,6 +354,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -336,6 +354,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
public int setBytes(long pos, byte[] bytes, int offset, int length) public int setBytes(long pos, byte[] bytes, int offset, int length)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
if (offset < 0 || offset > bytes.length) { if (offset < 0 || offset > bytes.length) {
throw new SerialException("Invalid offset in byte array set"); throw new SerialException("Invalid offset in byte array set");
} }
...@@ -378,11 +397,13 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -378,11 +397,13 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* @throws SQLException if there is an error accessing the * @throws SQLException if there is an error accessing the
* <code>BLOB</code> value * <code>BLOB</code> value
* @throws SerialException if the SerialBlob in not instantiated with a * @throws SerialException if the SerialBlob in not instantiated with a
* <code>Blob</code> object that supports <code>setBinaryStream()</code> * <code>Blob</code> object that supports <code>setBinaryStream()</code>;
* if {@code free} had previously been called on this object
* @see #getBinaryStream * @see #getBinaryStream
*/ */
public java.io.OutputStream setBinaryStream(long pos) public java.io.OutputStream setBinaryStream(long pos)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
if (this.blob != null) { if (this.blob != null) {
return this.blob.setBinaryStream(pos); return this.blob.setBinaryStream(pos);
} else { } else {
...@@ -400,10 +421,12 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -400,10 +421,12 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
* value that this <code>Blob</code> object represents should be * value that this <code>Blob</code> object represents should be
* truncated * truncated
* @throws SerialException if there is an error accessing the Blob value; * @throws SerialException if there is an error accessing the Blob value;
* or the length to truncate is greater that the SerialBlob length * or the length to truncate is greater that the SerialBlob length;
* if {@code free} had previously been called on this object
*/ */
public void truncate(long length) throws SerialException { public void truncate(long length) throws SerialException {
isValid();
if (length > len) { if (length > len) {
throw new SerialException throw new SerialException
("Length more than what can be truncated"); ("Length more than what can be truncated");
...@@ -418,36 +441,55 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -418,36 +441,55 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
/** /**
* Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value, * Returns an
* starting with the byte specified by pos, which is length bytes in length. * <code>InputStream</code> object that contains a partial
* {@code Blob} value, starting with the byte specified by pos, which is
* length bytes in length.
* *
* @param pos the offset to the first byte of the partial value to be retrieved. * @param pos the offset to the first byte of the partial value to be
* The first byte in the <code>Blob</code> is at position 1 * retrieved. The first byte in the {@code Blob} is at position 1
* @param length the length in bytes of the partial value to be retrieved * @param length the length in bytes of the partial value to be retrieved
* @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read. * @return
* @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes * <code>InputStream</code> through which the partial {@code Blob} value can
* in the <code>Blob</code> or if pos + length is greater than the number of bytes * be read.
* in the <code>Blob</code> * @throws SQLException if pos is less than 1 or if pos is greater than the
* number of bytes in the {@code Blob} or if pos + length is greater than
* the number of bytes in the {@code Blob}
* @throws SerialException if the {@code free} method had been previously
* called on this object
* *
* @since 1.6 * @since 1.6
*/ */
public InputStream getBinaryStream(long pos,long length) throws SQLException { public InputStream getBinaryStream(long pos, long length) throws SQLException {
throw new java.lang.UnsupportedOperationException("Not supported"); isValid();
if (pos < 1 || pos > this.length()) {
throw new SerialException("Invalid position in BLOB object set");
}
if (length < 1 || length > len - pos + 1) {
throw new SerialException("length is < 1 or pos + length >"
+ "total number of bytes");
}
return new ByteArrayInputStream(buf, (int) pos - 1, (int) length);
} }
/** /**
* This method frees the <code>Blob</code> object and releases the resources that it holds. * This method frees the {@code SeriableBlob} object and releases the
* <code>Blob</code> object. The object is invalid once the <code>free</code> * resources that it holds. The object is invalid once the {@code free}
* method is called. If <code>free</code> is called multiple times, the subsequent * method is called. <p> If {@code free} is called multiple times, the
* calls to <code>free</code> are treated as a no-op. * subsequent calls to {@code free} are treated as a no-op. </P>
* *
* @throws SQLException if an error occurs releasing * @throws SQLException if an error occurs releasing the Blob's resources
* the Blob's resources
* @since 1.6 * @since 1.6
*/ */
public void free() throws SQLException { public void free() throws SQLException {
throw new java.lang.UnsupportedOperationException("Not supported"); if (buf != null) {
buf = null;
if (blob != null) {
blob.free();
}
blob = null;
}
} }
/** /**
...@@ -494,7 +536,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -494,7 +536,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
public Object clone() { public Object clone() {
try { try {
SerialBlob sb = (SerialBlob) super.clone(); SerialBlob sb = (SerialBlob) super.clone();
sb.buf = Arrays.copyOf(buf, (int)len); sb.buf = (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
sb.blob = null; sb.blob = null;
return sb; return sb;
} catch (CloneNotSupportedException ex) { } catch (CloneNotSupportedException ex) {
...@@ -541,9 +583,21 @@ public class SerialBlob implements Blob, Serializable, Cloneable { ...@@ -541,9 +583,21 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
} }
/** /**
* The identifier that assists in the serialization of this <code>SerialBlob</code> * Check to see if this object had previously had its {@code free} method
* object. * called
*
* @throws SerialException
*/ */
private void isValid() throws SerialException {
if (buf == null) {
throw new SerialException("Error: You cannot call a method on a "
+ "SerialBlob instance once free() has been called.");
}
}
/**
* The identifier that assists in the serialization of this
* {@code SerialBlob} object.
*/
static final long serialVersionUID = -8144641928112860441L; static final long serialVersionUID = -8144641928112860441L;
} }
...@@ -44,6 +44,11 @@ import java.util.Arrays; ...@@ -44,6 +44,11 @@ import java.util.Arrays;
* from a <code>SerialClob</code> object or to locate the start of * from a <code>SerialClob</code> object or to locate the start of
* a pattern of characters. * a pattern of characters.
* *
* <h4> Thread safety </h4>
*
* <p> A SerialClob is not safe for use by multiple concurrent threads. If a
* SerialClob is to be used by more than one thread then access to the SerialClob
* should be controlled by appropriate synchronization.
* @author Jonathan Bruce * @author Jonathan Bruce
*/ */
public class SerialClob implements Clob, Serializable, Cloneable { public class SerialClob implements Clob, Serializable, Cloneable {
...@@ -180,9 +185,11 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -180,9 +185,11 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* *
* @return a <code>long</code> indicating the length in characters of this * @return a <code>long</code> indicating the length in characters of this
* <code>SerialClob</code> object's array of character * <code>SerialClob</code> object's array of character
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public long length() throws SerialException { public long length() throws SerialException {
isValid();
return len; return len;
} }
...@@ -194,9 +201,11 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -194,9 +201,11 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* *
* @return a <code>java.io.Reader</code> object containing this * @return a <code>java.io.Reader</code> object containing this
* <code>SerialClob</code> object's data * <code>SerialClob</code> object's data
* @throws SerialException if an error occurs * @throws SerialException if an error occurs;
* if {@code free} had previously been called on this object
*/ */
public java.io.Reader getCharacterStream() throws SerialException { public java.io.Reader getCharacterStream() throws SerialException {
isValid();
return (java.io.Reader) new CharArrayReader(buf); return (java.io.Reader) new CharArrayReader(buf);
} }
...@@ -210,13 +219,15 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -210,13 +219,15 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* *
* @return a <code>java.io.InputStream</code> object containing * @return a <code>java.io.InputStream</code> object containing
* this <code>SerialClob</code> object's data * this <code>SerialClob</code> object's data
* @throws SerialException if this <code>SerialClob</code> object was not instantiated * @throws SerialException if this {@code SerialClob} object was not
* with a <code>Clob</code> object * instantiated with a <code>Clob</code> object;
* if {@code free} had previously been called on this object
* @throws SQLException if there is an error accessing the * @throws SQLException if there is an error accessing the
* <code>CLOB</code> value represented by the <code>Clob</code> object that was * <code>CLOB</code> value represented by the <code>Clob</code> object
* used to create this <code>SerialClob</code> object * that was used to create this <code>SerialClob</code> object
*/ */
public java.io.InputStream getAsciiStream() throws SerialException, SQLException { public java.io.InputStream getAsciiStream() throws SerialException, SQLException {
isValid();
if (this.clob != null) { if (this.clob != null) {
return this.clob.getAsciiStream(); return this.clob.getAsciiStream();
} else { } else {
...@@ -248,12 +259,14 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -248,12 +259,14 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* this <code>SerialClob</code> object beginning at the * this <code>SerialClob</code> object beginning at the
* given position and containing the specified number of * given position and containing the specified number of
* consecutive characters * consecutive characters
* @throws SerialException if either of the arguments is out of bounds * @throws SerialException if either of the arguments is out of bounds;
* if {@code free} had previously been called on this object
*/ */
public String getSubString(long pos, int length) throws SerialException { public String getSubString(long pos, int length) throws SerialException {
isValid();
if (pos < 1 || pos > this.length()) { if (pos < 1 || pos > this.length()) {
throw new SerialException("Invalid position in BLOB object set"); throw new SerialException("Invalid position in SerialClob object set");
} }
if ((pos-1) + length > this.length()) { if ((pos-1) + length > this.length()) {
...@@ -287,13 +300,14 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -287,13 +300,14 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* <code>-1</code> if the given <code>String</code> object is * <code>-1</code> if the given <code>String</code> object is
* not found or the starting position is out of bounds; position * not found or the starting position is out of bounds; position
* numbering for the return value starts at <code>1</code> * numbering for the return value starts at <code>1</code>
* @throws SerialException if an error occurs locating the String signature * @throws SerialException if the {@code free} method had been
* @throws SQLException if there is an error accessing the Blob value * previously called on this object
* @throws SQLException if there is an error accessing the Clob value
* from the database. * from the database.
*/ */
public long position(String searchStr, long start) public long position(String searchStr, long start)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
if (start < 1 || start > len) { if (start < 1 || start > len) {
return -1; return -1;
} }
...@@ -332,13 +346,14 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -332,13 +346,14 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* @return the position at which the given <code>Clob</code> * @return the position at which the given <code>Clob</code>
* object begins in this <code>SerialClob</code> object, * object begins in this <code>SerialClob</code> object,
* at or after the specified starting position * at or after the specified starting position
* @throws SerialException if an error occurs locating the Clob signature * @throws SerialException if an error occurs locating the Clob signature;
* @throws SQLException if there is an error accessing the Blob value * if the {@code free} method had been previously called on this object
* @throws SQLException if there is an error accessing the Clob value
* from the database * from the database
*/ */
public long position(Clob searchStr, long start) public long position(Clob searchStr, long start)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
return position(searchStr.getSubString(1,(int)searchStr.length()), start); return position(searchStr.getSubString(1,(int)searchStr.length()), start);
} }
...@@ -358,7 +373,8 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -358,7 +373,8 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* <code>CLOB</code> value; if an invalid position is set; if an * <code>CLOB</code> value; if an invalid position is set; if an
* invalid offset value is set; if number of bytes to be written * invalid offset value is set; if number of bytes to be written
* is greater than the <code>SerialClob</code> length; or the combined * 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;
* if the {@code free} method had been previously called on this object
*/ */
public int setString(long pos, String str) throws SerialException { public int setString(long pos, String str) throws SerialException {
return (setString(pos, str, 0, str.length())); return (setString(pos, str, 0, str.length()));
...@@ -383,10 +399,12 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -383,10 +399,12 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* <code>CLOB</code> value; if an invalid position is set; if an * <code>CLOB</code> value; if an invalid position is set; if an
* invalid offset value is set; if number of bytes to be written * invalid offset value is set; if number of bytes to be written
* is greater than the <code>SerialClob</code> length; or the combined * 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;
* if the {@code free} method had been previously called on this object
*/ */
public int setString(long pos, String str, int offset, int length) public int setString(long pos, String str, int offset, int length)
throws SerialException { throws SerialException {
isValid();
String temp = str.substring(offset); String temp = str.substring(offset);
char cPattern[] = temp.toCharArray(); char cPattern[] = temp.toCharArray();
...@@ -395,7 +413,7 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -395,7 +413,7 @@ public class SerialClob implements Clob, Serializable, Cloneable {
} }
if (pos < 1 || pos > this.length()) { if (pos < 1 || pos > this.length()) {
throw new SerialException("Invalid position in BLOB object set"); throw new SerialException("Invalid position in Clob object set");
} }
if ((long)(length) > origLen) { if ((long)(length) > origLen) {
...@@ -430,13 +448,15 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -430,13 +448,15 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* <code>CLOB</code> object * <code>CLOB</code> object
* @return the stream to which ASCII encoded characters can be written * @return the stream to which ASCII encoded characters can be written
* @throws SerialException if SerialClob is not instantiated with a * @throws SerialException if SerialClob is not instantiated with a
* Clob object that supports <code>setAsciiStream</code> * Clob object;
* if the {@code free} method had been previously called on this object
* @throws SQLException if there is an error accessing the * @throws SQLException if there is an error accessing the
* <code>CLOB</code> value * <code>CLOB</code> value
* @see #getAsciiStream * @see #getAsciiStream
*/ */
public java.io.OutputStream setAsciiStream(long pos) public java.io.OutputStream setAsciiStream(long pos)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
if (this.clob != null) { if (this.clob != null) {
return this.clob.setAsciiStream(pos); return this.clob.setAsciiStream(pos);
} else { } else {
...@@ -460,13 +480,15 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -460,13 +480,15 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* *
* @return a stream to which Unicode encoded characters can be written * @return a stream to which Unicode encoded characters can be written
* @throws SerialException if the SerialClob is not instantiated with * @throws SerialException if the SerialClob is not instantiated with
* a Clob object that supports <code>setCharacterStream</code> * a Clob object;
* if the {@code free} method had been previously called on this object
* @throws SQLException if there is an error accessing the * @throws SQLException if there is an error accessing the
* <code>CLOB</code> value * <code>CLOB</code> value
* @see #getCharacterStream * @see #getCharacterStream
*/ */
public java.io.Writer setCharacterStream(long pos) public java.io.Writer setCharacterStream(long pos)
throws SerialException, SQLException { throws SerialException, SQLException {
isValid();
if (this.clob != null) { if (this.clob != null) {
return this.clob.setCharacterStream(pos); return this.clob.setCharacterStream(pos);
} else { } else {
...@@ -486,10 +508,12 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -486,10 +508,12 @@ public class SerialClob implements Clob, Serializable, Cloneable {
* *
* @param length the length, in bytes, to which the <code>CLOB</code> * @param length the length, in bytes, to which the <code>CLOB</code>
* value should be truncated * value should be truncated
* @throws SQLException if there is an error accessing the * @throws SerialLException if there is an error accessing the
* <code>CLOB</code> value * <code>CLOB</code> value;
* if the {@code free} method had been previously called on this object
*/ */
public void truncate(long length) throws SerialException { public void truncate(long length) throws SerialException {
isValid();
if (length > len) { if (length > len) {
throw new SerialException throw new SerialException
("Length more than what can be truncated"); ("Length more than what can be truncated");
...@@ -502,17 +526,62 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -502,17 +526,62 @@ public class SerialClob implements Clob, Serializable, Cloneable {
} else { } else {
buf = (this.getSubString(1, (int)len)).toCharArray(); buf = (this.getSubString(1, (int)len)).toCharArray();
} }
} }
} }
/**
* Returns a {@code Reader} object that contains a partial
* {@code SerialClob} 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 SerialClob} is at position 1.
* @param length the length in characters of the partial value to be retrieved.
* @return {@code Reader} through which the partial {@code SerialClob}
* 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 SerialClob} or if pos + length
* is greater than the number of characters in the {@code SerialClob};
* @throws SerialException if the {@code free} method had been previously
* called on this object
* @since 1.6
*/
public Reader getCharacterStream(long pos, long length) throws SQLException { public Reader getCharacterStream(long pos, long length) throws SQLException {
throw new java.lang.UnsupportedOperationException("Not supported"); isValid();
if (pos < 1 || pos > len) {
throw new SerialException("Invalid position in Clob object set");
}
if ((pos-1) + length > len) {
throw new SerialException("Invalid position and substring length");
}
if (length <= 0) {
throw new SerialException("Invalid length specified");
}
return new CharArrayReader(buf, (int)pos, (int)length);
} }
/**
* This method frees the {@code SeriableClob} object and releases the
* resources that it holds.
* The object is invalid once the {@code free} method is called.
* <p>
* If {@code free} is called multiple times, the subsequent
* calls to {@code free} are treated as a no-op.
* </P>
* @throws SQLException if an error occurs releasing
* the Clob's resources
* @since 1.6
*/
public void free() throws SQLException { public void free() throws SQLException {
throw new java.lang.UnsupportedOperationException("Not supported"); if (buf != null) {
buf = null;
if (clob != null) {
clob.free();
}
clob = null;
}
} }
/** /**
...@@ -559,7 +628,7 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -559,7 +628,7 @@ public class SerialClob implements Clob, Serializable, Cloneable {
public Object clone() { public Object clone() {
try { try {
SerialClob sc = (SerialClob) super.clone(); SerialClob sc = (SerialClob) super.clone();
sc.buf = Arrays.copyOf(buf, (int)len); sc.buf = (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
sc.clob = null; sc.clob = null;
return sc; return sc;
} catch (CloneNotSupportedException ex) { } catch (CloneNotSupportedException ex) {
...@@ -605,7 +674,20 @@ public class SerialClob implements Clob, Serializable, Cloneable { ...@@ -605,7 +674,20 @@ public class SerialClob implements Clob, Serializable, Cloneable {
} }
/** /**
* The identifier that assists in the serialization of this <code>SerialClob</code> * Check to see if this object had previously had its {@code free} method
* called
*
* @throws SerialException
*/
private void isValid() throws SerialException {
if (buf == null) {
throw new SerialException("Error: You cannot call a method on a "
+ "SerialClob instance once free() has been called.");
}
}
/**
* The identifier that assists in the serialization of this {@code SerialClob}
* object. * object.
*/ */
static final long serialVersionUID = -1662519690087375313L; static final long serialVersionUID = -1662519690087375313L;
......
...@@ -42,6 +42,12 @@ import java.net.URL; ...@@ -42,6 +42,12 @@ import java.net.URL;
* <pre> * <pre>
* java.net.URL url = rowset.getURL(1); * java.net.URL url = rowset.getURL(1);
* </pre> * </pre>
*
* <h4> Thread safety </h4>
*
* A SerialDatalink is not safe for use by multiple concurrent threads. If a
* SerialDatalink is to be used by more than one thread then access to the
* SerialDatalink should be controlled by appropriate synchronization.
*/ */
public class SerialDatalink implements Serializable, Cloneable { public class SerialDatalink implements Serializable, Cloneable {
......
...@@ -44,6 +44,12 @@ import javax.sql.rowset.RowSetWarning; ...@@ -44,6 +44,12 @@ import javax.sql.rowset.RowSetWarning;
* Static or transient fields cannot be serialized; an attempt to serialize * Static or transient fields cannot be serialized; an attempt to serialize
* them will result in a <code>SerialException</code> object being thrown. * them will result in a <code>SerialException</code> object being thrown.
* *
* <h4> Thread safety </h4>
*
* A SerialJavaObject is not safe for use by multiple concurrent threads. If a
* SerialJavaObject is to be used by more than one thread then access to the
* SerialJavaObject should be controlled by appropriate synchronization.
*
* @author Jonathan Bruce * @author Jonathan Bruce
*/ */
public class SerialJavaObject implements Serializable, Cloneable { public class SerialJavaObject implements Serializable, Cloneable {
......
...@@ -36,6 +36,13 @@ import java.util.*; ...@@ -36,6 +36,13 @@ import java.util.*;
* The <code>SerialRef</code> class provides a constructor for * The <code>SerialRef</code> class provides a constructor for
* creating a <code>SerialRef</code> instance from a <code>Ref</code> * creating a <code>SerialRef</code> instance from a <code>Ref</code>
* object and provides methods for getting and setting the <code>Ref</code> object. * object and provides methods for getting and setting the <code>Ref</code> object.
*
* <h4> Thread safety </h4>
*
* A SerialRef is not safe for use by multiple concurrent threads. If a
* SerialRef is to be used by more than one thread then access to the SerialRef
* should be controlled by appropriate synchronization.
*
*/ */
public class SerialRef implements Ref, Serializable, Cloneable { public class SerialRef implements Ref, Serializable, Cloneable {
......
...@@ -50,6 +50,13 @@ import javax.sql.rowset.*; ...@@ -50,6 +50,13 @@ import javax.sql.rowset.*;
* an instance from a <code>Struct</code> object, a method for retrieving * an instance from a <code>Struct</code> object, a method for retrieving
* the SQL type name of the SQL structured type in the database, and methods * the SQL type name of the SQL structured type in the database, and methods
* for retrieving its attribute values. * for retrieving its attribute values.
*
* <h4> Thread safety </h4>
*
* A SerialStruct is not safe for use by multiple concurrent threads. If a
* SerialStruct is to be used by more than one thread then access to the
* SerialStruct should be controlled by appropriate synchronization.
*
*/ */
public class SerialStruct implements Struct, Serializable, Cloneable { public class SerialStruct implements Struct, Serializable, Cloneable {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册