8004357: Implement various methods in SerialBlob/Clob/Array and specify Thread Safety
Reviewed-by: naoto
This commit is contained in:
parent
85db8f9602
commit
e57799bc0e
@ -31,6 +31,7 @@ import java.util.Map;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* A serialized version of an <code>Array</code>
|
||||
* object, which is the mapping in the Java programming language of an SQL
|
||||
@ -41,44 +42,52 @@ import java.util.Arrays;
|
||||
* 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.
|
||||
* <P>
|
||||
*
|
||||
* Note: In order for this class to function correctly, a connection to the
|
||||
* data source
|
||||
* 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)
|
||||
* if necessary. At this time, logical pointers to the data in the data source,
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* A serialized array in which each element is an <code>Object</code>
|
||||
* in the Java programming language that represents an element
|
||||
* in the SQL <code>ARRAY</code> value.
|
||||
* @serial
|
||||
*/
|
||||
/**
|
||||
* A serialized array in which each element is an <code>Object</code>
|
||||
* in the Java programming language that represents an element
|
||||
* in the SQL <code>ARRAY</code> value.
|
||||
* @serial
|
||||
*/
|
||||
private Object[] elements;
|
||||
|
||||
/**
|
||||
* The SQL type of the elements in this <code>SerialArray</code> object. The
|
||||
* type is expressed as one of the constants from the class
|
||||
* <code>java.sql.Types</code>.
|
||||
* @serial
|
||||
*/
|
||||
/**
|
||||
* The SQL type of the elements in this <code>SerialArray</code> object. The
|
||||
* type is expressed as one of the constants from the class
|
||||
* <code>java.sql.Types</code>.
|
||||
* @serial
|
||||
*/
|
||||
private int baseType;
|
||||
|
||||
/**
|
||||
* The type name used by the DBMS for the elements in the SQL <code>ARRAY</code>
|
||||
* value that this <code>SerialArray</code> object represents.
|
||||
* @serial
|
||||
*/
|
||||
/**
|
||||
* The type name used by the DBMS for the elements in the SQL <code>ARRAY</code>
|
||||
* value that this <code>SerialArray</code> object represents.
|
||||
* @serial
|
||||
*/
|
||||
private String baseTypeName;
|
||||
|
||||
/**
|
||||
* The number of elements in this <code>SerialArray</code> object, which
|
||||
* is also the number of elements in the SQL <code>ARRAY</code> value
|
||||
* that this <code>SerialArray</code> object represents.
|
||||
* @serial
|
||||
*/
|
||||
/**
|
||||
* The number of elements in this <code>SerialArray</code> object, which
|
||||
* is also the number of elements in the SQL <code>ARRAY</code> value
|
||||
* that this <code>SerialArray</code> object represents.
|
||||
* @serial
|
||||
*/
|
||||
private int len;
|
||||
|
||||
/**
|
||||
@ -192,24 +201,19 @@ public class SerialArray implements Array, Serializable, Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method frees the <code>Array</code> object and releases the resources that
|
||||
* it holds. The object is invalid once the <code>free</code>
|
||||
* method is called.
|
||||
*<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>
|
||||
* This method frees the {@code SeriableArray} 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 Array's resources
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @throws SQLException if an error occurs releasing the SerialArray's resources
|
||||
* @since 1.6
|
||||
*/
|
||||
public void free() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||
if (elements != null) {
|
||||
elements = null;
|
||||
baseTypeName= null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -292,129 +296,140 @@ public class SerialArray implements Array, Serializable, Cloneable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array that is a copy of this <code>SerialArray</code>
|
||||
* object.
|
||||
*
|
||||
* @return a copy of this <code>SerialArray</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs retrieving a copy of
|
||||
* this <code>SerialArray</code> object
|
||||
*/
|
||||
/**
|
||||
* Returns a new array that is a copy of this <code>SerialArray</code>
|
||||
* object.
|
||||
*
|
||||
* @return a copy of this <code>SerialArray</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public Object getArray() throws SerialException {
|
||||
isValid();
|
||||
Object dst = new Object[len];
|
||||
System.arraycopy((Object)elements, 0, dst, 0, len);
|
||||
return dst;
|
||||
}
|
||||
|
||||
//[if an error occurstype map used??]
|
||||
/**
|
||||
* Returns a new array that is a copy of this <code>SerialArray</code>
|
||||
* object, using the given type map for the custom
|
||||
* mapping of each element when the elements are SQL UDTs.
|
||||
* <P>
|
||||
* This method does custom mapping if the array elements are a UDT
|
||||
* and the given type map has an entry for that UDT.
|
||||
/**
|
||||
* Returns a new array that is a copy of this <code>SerialArray</code>
|
||||
* object, using the given type map for the custom
|
||||
* mapping of each element when the elements are SQL UDTs.
|
||||
* <P>
|
||||
* This method does custom mapping if the array elements are a UDT
|
||||
* and the given type map has an entry for that UDT.
|
||||
* Custom mapping is recursive,
|
||||
* meaning that if, for instance, an element of an SQL structured type
|
||||
* is an SQL structured type that itself has an element that is an SQL
|
||||
* structured type, each structured type that has a custom mapping will be
|
||||
* mapped according to the given type map.
|
||||
*
|
||||
* meaning that if, for instance, an element of an SQL structured type
|
||||
* is an SQL structured type that itself has an element that is an SQL
|
||||
* structured type, each structured type that has a custom mapping will be
|
||||
* mapped according to the given type map.
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return a copy of this <code>SerialArray</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
* @return a copy of this <code>SerialArray</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @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 {
|
||||
isValid();
|
||||
Object dst[] = new Object[len];
|
||||
System.arraycopy((Object)elements, 0, dst, 0, len);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array that is a copy of a slice
|
||||
* of this <code>SerialArray</code> object, starting with the
|
||||
* element at the given index and containing the given number
|
||||
* of consecutive elements.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied;
|
||||
* the index of the first element is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* @return a copy of the designated elements in this <code>SerialArray</code>
|
||||
* object as an <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
/**
|
||||
* Returns a new array that is a copy of a slice
|
||||
* of this <code>SerialArray</code> object, starting with the
|
||||
* element at the given index and containing the given number
|
||||
* of consecutive elements.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied;
|
||||
* the index of the first element is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* @return a copy of the designated elements in this <code>SerialArray</code>
|
||||
* object as an <code>Object</code> in the Java programming language
|
||||
* @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 {
|
||||
isValid();
|
||||
Object dst = new Object[count];
|
||||
System.arraycopy((Object)elements, (int)index, dst, 0, count);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array that is a copy of a slice
|
||||
* of this <code>SerialArray</code> object, starting with the
|
||||
* element at the given index and containing the given number
|
||||
* of consecutive elements.
|
||||
* <P>
|
||||
* This method does custom mapping if the array elements are a UDT
|
||||
* and the given type map has an entry for that UDT.
|
||||
/**
|
||||
* Returns a new array that is a copy of a slice
|
||||
* of this <code>SerialArray</code> object, starting with the
|
||||
* element at the given index and containing the given number
|
||||
* of consecutive elements.
|
||||
* <P>
|
||||
* This method does custom mapping if the array elements are a UDT
|
||||
* and the given type map has an entry for that UDT.
|
||||
* Custom mapping is recursive,
|
||||
* meaning that if, for instance, an element of an SQL structured type
|
||||
* is an SQL structured type that itself has an element that is an SQL
|
||||
* structured type, each structured type that has a custom mapping will be
|
||||
* mapped according to the given type map.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied; the index of the
|
||||
* first element in the array is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* meaning that if, for instance, an element of an SQL structured type
|
||||
* is an SQL structured type that itself has an element that is an SQL
|
||||
* structured type, each structured type that has a custom mapping will be
|
||||
* mapped according to the given type map.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied; the index of the
|
||||
* first element in the array is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return a copy of the designated elements in this <code>SerialArray</code>
|
||||
* object as an <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
* @return a copy of the designated elements in this <code>SerialArray</code>
|
||||
* object as an <code>Object</code> in the Java programming language
|
||||
* @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)
|
||||
throws SerialException
|
||||
{
|
||||
isValid();
|
||||
Object dst = new Object[count];
|
||||
System.arraycopy((Object)elements, (int)index, dst, 0, count);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the SQL type of the elements in this <code>SerialArray</code>
|
||||
* object. The <code>int</code> returned is one of the constants in the class
|
||||
* <code>java.sql.Types</code>.
|
||||
*
|
||||
* @return one of the constants in <code>java.sql.Types</code>, indicating
|
||||
* the SQL type of the elements in this <code>SerialArray</code> object
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
/**
|
||||
* Retrieves the SQL type of the elements in this <code>SerialArray</code>
|
||||
* object. The <code>int</code> returned is one of the constants in the class
|
||||
* <code>java.sql.Types</code>.
|
||||
*
|
||||
* @return one of the constants in <code>java.sql.Types</code>, indicating
|
||||
* the SQL type of the elements in this <code>SerialArray</code> object
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public int getBaseType() throws SerialException {
|
||||
isValid();
|
||||
return baseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the DBMS-specific type name for the elements in this
|
||||
* <code>SerialArray</code> object.
|
||||
*
|
||||
* @return the SQL type name used by the DBMS for the base type of this
|
||||
/**
|
||||
* Retrieves the DBMS-specific type name for the elements in this
|
||||
* <code>SerialArray</code> object.
|
||||
*
|
||||
* @return the SQL type name used by the DBMS for the base type of 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 String getBaseTypeName() throws SerialException {
|
||||
isValid();
|
||||
return baseTypeName;
|
||||
}
|
||||
|
||||
@ -434,11 +449,13 @@ public class SerialArray implements Array, Serializable, Cloneable {
|
||||
* @return a <code>ResultSet</code> object containing the designated
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException, which in turn throws an
|
||||
* <code>UnsupportedOperationException</code>, if this method is called
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
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 {
|
||||
* @return a <code>ResultSet</code> object containing all of the
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException, which in turn throws an
|
||||
* <code>UnsupportedOperationException</code>, if this method is called
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(Map<String, Class<?>> map)
|
||||
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 {
|
||||
* @return a <code>ResultSet</code> object containing all of the
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException if called, which in turn throws an
|
||||
* <code>UnsupportedOperationException</code>, if this method is called
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
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 {
|
||||
* @return a <code>ResultSet</code> object containing the designated
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException if called, which in turn throws an
|
||||
* <code>UnsupportedOperationException</code>
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(long index, int count,
|
||||
Map<String,Class<?>> map)
|
||||
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
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
@ -566,12 +590,12 @@ public class SerialArray implements Array, Serializable, Cloneable {
|
||||
* reference to a clone of the underlying objects array, not a reference
|
||||
* to the original underlying object array of this {@code SerialArray} object.
|
||||
*
|
||||
* @return a clone of this SerialArray
|
||||
* @return a clone of this SerialArray
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialArray sa = (SerialArray) super.clone();
|
||||
sa.elements = Arrays.copyOf(elements, len);
|
||||
sa.elements = (elements != null) ? Arrays.copyOf(elements, len) : null;
|
||||
return sa;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
@ -615,6 +639,19 @@ public class SerialArray implements Array, Serializable, Cloneable {
|
||||
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>
|
||||
* object.
|
||||
|
@ -51,6 +51,12 @@ import java.util.Arrays;
|
||||
* <code>Blob</code> object within a <code>SerialBlob</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
|
||||
*/
|
||||
public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
@ -76,7 +82,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
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.
|
||||
* @serial
|
||||
*/
|
||||
@ -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
|
||||
* <code>SerialBlob</code> object, starting at the given
|
||||
* 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 {
|
||||
isValid();
|
||||
if (length > len) {
|
||||
length = (int)len;
|
||||
}
|
||||
@ -189,9 +197,11 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
*
|
||||
* @return a <code>long</code> indicating the length in bytes of 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
|
||||
*/
|
||||
public long length() throws SerialException {
|
||||
isValid();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -203,12 +213,14 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
*
|
||||
* @return a <code>java.io.InputStream</code> object that contains
|
||||
* 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
|
||||
*/
|
||||
public java.io.InputStream getBinaryStream() throws SerialException {
|
||||
InputStream stream = new ByteArrayInputStream(buf);
|
||||
return stream;
|
||||
isValid();
|
||||
InputStream stream = new ByteArrayInputStream(buf);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -227,12 +239,14 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
* position; <code>-1</code> if the pattern is not found
|
||||
* or the given starting position is out of bounds; 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>
|
||||
* value from the database
|
||||
*/
|
||||
public long position(byte[] pattern, long start)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
if (start < 1 || start > len) {
|
||||
return -1;
|
||||
}
|
||||
@ -270,12 +284,14 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
* at the specified position; <code>-1</code> if the pattern is
|
||||
* not found or the given starting position is out of bounds;
|
||||
* 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>
|
||||
* value from the database
|
||||
*/
|
||||
public long position(Blob pattern, long start)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
return position(pattern.getBytes(1, (int)(pattern.length())), start);
|
||||
}
|
||||
|
||||
@ -293,7 +309,8 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
* @return the number of bytes written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <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>
|
||||
* value from the database
|
||||
* @see #getBytes
|
||||
@ -328,7 +345,8 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
* <code>BLOB</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>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>
|
||||
* value from the database.
|
||||
* @see #getBytes
|
||||
@ -336,6 +354,7 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
public int setBytes(long pos, byte[] bytes, int offset, int length)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
isValid();
|
||||
if (offset < 0 || offset > bytes.length) {
|
||||
throw new SerialException("Invalid offset in byte array set");
|
||||
}
|
||||
@ -378,11 +397,13 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
* @throws SQLException if there is an error accessing the
|
||||
* <code>BLOB</code> value
|
||||
* @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
|
||||
*/
|
||||
public java.io.OutputStream setBinaryStream(long pos)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
if (this.blob != null) {
|
||||
return this.blob.setBinaryStream(pos);
|
||||
} else {
|
||||
@ -400,54 +421,75 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
* value that this <code>Blob</code> object represents should be
|
||||
* truncated
|
||||
* @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 {
|
||||
|
||||
if (length > len) {
|
||||
throw new SerialException
|
||||
("Length more than what can be truncated");
|
||||
} else if((int)length == 0) {
|
||||
buf = new byte[0];
|
||||
len = length;
|
||||
} else {
|
||||
len = length;
|
||||
buf = this.getBytes(1, (int)len);
|
||||
}
|
||||
isValid();
|
||||
if (length > len) {
|
||||
throw new SerialException
|
||||
("Length more than what can be truncated");
|
||||
} else if((int)length == 0) {
|
||||
buf = new byte[0];
|
||||
len = length;
|
||||
} else {
|
||||
len = length;
|
||||
buf = this.getBytes(1, (int)len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
|
||||
* starting with the byte specified by pos, which is length bytes in length.
|
||||
* Returns an
|
||||
* <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.
|
||||
* The first byte in the <code>Blob</code> is at position 1
|
||||
* @param pos the offset to the first byte of the partial value to be
|
||||
* 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
|
||||
* @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read.
|
||||
* @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes
|
||||
* in the <code>Blob</code> or if pos + length is greater than the number of bytes
|
||||
* in the <code>Blob</code>
|
||||
* @return
|
||||
* <code>InputStream</code> through which the partial {@code Blob} value can
|
||||
* be read.
|
||||
* @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
|
||||
*/
|
||||
public InputStream getBinaryStream(long pos,long length) throws SQLException {
|
||||
throw new java.lang.UnsupportedOperationException("Not supported");
|
||||
public InputStream getBinaryStream(long pos, long length) throws SQLException {
|
||||
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.
|
||||
* <code>Blob</code> object. The object is invalid once the <code>free</code>
|
||||
* method is called. If <code>free</code> is called multiple times, the subsequent
|
||||
* calls to <code>free</code> are treated as a no-op.
|
||||
* This method frees the {@code SeriableBlob} 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 Blob's resources
|
||||
* @throws SQLException if an error occurs releasing the Blob's resources
|
||||
* @since 1.6
|
||||
*/
|
||||
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 {
|
||||
public Object clone() {
|
||||
try {
|
||||
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;
|
||||
return sb;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
@ -541,9 +583,21 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this <code>SerialBlob</code>
|
||||
* object.
|
||||
* 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 "
|
||||
+ "SerialBlob instance once free() has been called.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* {@code SerialBlob} object.
|
||||
*/
|
||||
static final long serialVersionUID = -8144641928112860441L;
|
||||
}
|
||||
|
@ -44,6 +44,11 @@ import java.util.Arrays;
|
||||
* from a <code>SerialClob</code> object or to locate the start of
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
* <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 {
|
||||
isValid();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -194,9 +201,11 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
*
|
||||
* @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;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public java.io.Reader getCharacterStream() throws SerialException {
|
||||
isValid();
|
||||
return (java.io.Reader) new CharArrayReader(buf);
|
||||
}
|
||||
|
||||
@ -210,13 +219,15 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
*
|
||||
* @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 SerialException if this {@code SerialClob} object was not
|
||||
* 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
|
||||
* <code>CLOB</code> value represented by the <code>Clob</code> object that was
|
||||
* used to create this <code>SerialClob</code> object
|
||||
* <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 {
|
||||
isValid();
|
||||
if (this.clob != null) {
|
||||
return this.clob.getAsciiStream();
|
||||
} else {
|
||||
@ -248,12 +259,14 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
* 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;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public String getSubString(long pos, int length) throws SerialException {
|
||||
|
||||
isValid();
|
||||
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()) {
|
||||
@ -287,13 +300,14 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
* <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
|
||||
* @throws SQLException if there is an error accessing the Blob value
|
||||
* @throws SerialException 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.
|
||||
*/
|
||||
public long position(String searchStr, long start)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
isValid();
|
||||
if (start < 1 || start > len) {
|
||||
return -1;
|
||||
}
|
||||
@ -332,13 +346,14 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
* @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
|
||||
* @throws SQLException if there is an error accessing the Blob value
|
||||
* @throws SerialException if an error occurs locating the Clob signature;
|
||||
* 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
|
||||
*/
|
||||
public long position(Clob searchStr, long start)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
isValid();
|
||||
return position(searchStr.getSubString(1,(int)searchStr.length()), start);
|
||||
}
|
||||
|
||||
@ -358,7 +373,8 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
* <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;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
*/
|
||||
public int setString(long pos, String str) throws SerialException {
|
||||
return (setString(pos, str, 0, str.length()));
|
||||
@ -383,10 +399,12 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
* <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;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
*/
|
||||
public int setString(long pos, String str, int offset, int length)
|
||||
throws SerialException {
|
||||
isValid();
|
||||
String temp = str.substring(offset);
|
||||
char cPattern[] = temp.toCharArray();
|
||||
|
||||
@ -395,7 +413,7 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -430,13 +448,15 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
* <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;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
* @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 {
|
||||
isValid();
|
||||
if (this.clob != null) {
|
||||
return this.clob.setAsciiStream(pos);
|
||||
} else {
|
||||
@ -460,13 +480,15 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
*
|
||||
* @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;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
* @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 {
|
||||
isValid();
|
||||
if (this.clob != null) {
|
||||
return this.clob.setCharacterStream(pos);
|
||||
} else {
|
||||
@ -486,33 +508,80 @@ public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
*
|
||||
* @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 SerialLException if there is an error accessing the
|
||||
* <code>CLOB</code> value;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
*/
|
||||
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
|
||||
isValid();
|
||||
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 {
|
||||
if (len == 0) {
|
||||
buf = new char[] {};
|
||||
} else {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
public Object clone() {
|
||||
try {
|
||||
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;
|
||||
return sc;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
@ -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.
|
||||
*/
|
||||
static final long serialVersionUID = -1662519690087375313L;
|
||||
|
@ -42,6 +42,12 @@ import java.net.URL;
|
||||
* <pre>
|
||||
* java.net.URL url = rowset.getURL(1);
|
||||
* </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 {
|
||||
|
||||
|
@ -44,6 +44,12 @@ import javax.sql.rowset.RowSetWarning;
|
||||
* Static or transient fields cannot be serialized; an attempt to serialize
|
||||
* 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
|
||||
*/
|
||||
public class SerialJavaObject implements Serializable, Cloneable {
|
||||
|
@ -36,6 +36,13 @@ import java.util.*;
|
||||
* The <code>SerialRef</code> class provides a constructor for
|
||||
* creating a <code>SerialRef</code> instance from a <code>Ref</code>
|
||||
* 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 {
|
||||
|
||||
|
@ -50,6 +50,13 @@ import javax.sql.rowset.*;
|
||||
* 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
|
||||
* 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 {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user