feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
668
jdkSrc/jdk8/javax/sql/rowset/serial/SQLInputImpl.java
Normal file
668
jdkSrc/jdk8/javax/sql/rowset/serial/SQLInputImpl.java
Normal file
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* An input stream used for custom mapping user-defined types (UDTs).
|
||||
* An <code>SQLInputImpl</code> object is an input stream that contains a
|
||||
* stream of values that are the attributes of a UDT.
|
||||
* <p>
|
||||
* This class is used by the driver behind the scenes when the method
|
||||
* <code>getObject</code> is called on an SQL structured or distinct type
|
||||
* that has a custom mapping; a programmer never invokes
|
||||
* <code>SQLInputImpl</code> methods directly. They are provided here as a
|
||||
* convenience for those who write <code>RowSet</code> implementations.
|
||||
* <P>
|
||||
* The <code>SQLInputImpl</code> class provides a set of
|
||||
* reader methods analogous to the <code>ResultSet</code> getter
|
||||
* methods. These methods make it possible to read the values in an
|
||||
* <code>SQLInputImpl</code> object.
|
||||
* <P>
|
||||
* The method <code>wasNull</code> is used to determine whether the
|
||||
* the last value read was SQL <code>NULL</code>.
|
||||
* <P>When the method <code>getObject</code> is called with an
|
||||
* object of a class implementing the interface <code>SQLData</code>,
|
||||
* the JDBC driver calls the method <code>SQLData.getSQLType</code>
|
||||
* to determine the SQL type of the UDT being custom mapped. The driver
|
||||
* creates an instance of <code>SQLInputImpl</code>, populating it with the
|
||||
* attributes of the UDT. The driver then passes the input
|
||||
* stream to the method <code>SQLData.readSQL</code>, which in turn
|
||||
* calls the <code>SQLInputImpl</code> reader methods
|
||||
* to read the attributes from the input stream.
|
||||
* @since 1.5
|
||||
* @see java.sql.SQLData
|
||||
*/
|
||||
public class SQLInputImpl implements SQLInput {
|
||||
|
||||
/**
|
||||
* <code>true</code> if the last value returned was <code>SQL NULL</code>;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
private boolean lastValueWasNull;
|
||||
|
||||
/**
|
||||
* The current index into the array of SQL structured type attributes
|
||||
* that will be read from this <code>SQLInputImpl</code> object and
|
||||
* mapped to the fields of a class in the Java programming language.
|
||||
*/
|
||||
private int idx;
|
||||
|
||||
/**
|
||||
* The array of attributes to be read from this stream. The order
|
||||
* of the attributes is the same as the order in which they were
|
||||
* listed in the SQL definition of the UDT.
|
||||
*/
|
||||
private Object attrib[];
|
||||
|
||||
/**
|
||||
* The type map to use when the method <code>readObject</code>
|
||||
* is invoked. This is a <code>java.util.Map</code> object in which
|
||||
* there may be zero or more entries. Each entry consists of the
|
||||
* fully qualified name of a UDT (the value to be mapped) and the
|
||||
* <code>Class</code> object for a class that implements
|
||||
* <code>SQLData</code> (the Java class that defines how the UDT
|
||||
* will be mapped).
|
||||
*/
|
||||
private Map<String,Class<?>> map;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an <code>SQLInputImpl</code> object initialized with the
|
||||
* given array of attributes and the given type map. If any of the
|
||||
* attributes is a UDT whose name is in an entry in the type map,
|
||||
* the attribute will be mapped according to the corresponding
|
||||
* <code>SQLData</code> implementation.
|
||||
*
|
||||
* @param attributes an array of <code>Object</code> instances in which
|
||||
* each element is an attribute of a UDT. The order of the
|
||||
* attributes in the array is the same order in which
|
||||
* the attributes were defined in the UDT definition.
|
||||
* @param map a <code>java.util.Map</code> object containing zero or more
|
||||
* entries, with each entry consisting of 1) a <code>String</code>
|
||||
* giving the fully
|
||||
* qualified name of the UDT and 2) the <code>Class</code> object
|
||||
* for the <code>SQLData</code> implementation that defines how
|
||||
* the UDT is to be mapped
|
||||
* @throws SQLException if the <code>attributes</code> or the <code>map</code>
|
||||
* is a <code>null</code> value
|
||||
*/
|
||||
|
||||
public SQLInputImpl(Object[] attributes, Map<String,Class<?>> map)
|
||||
throws SQLException
|
||||
{
|
||||
if ((attributes == null) || (map == null)) {
|
||||
throw new SQLException("Cannot instantiate a SQLInputImpl " +
|
||||
"object with null parameters");
|
||||
}
|
||||
// assign our local reference to the attribute stream
|
||||
attrib = Arrays.copyOf(attributes, attributes.length);
|
||||
// init the index point before the head of the stream
|
||||
idx = -1;
|
||||
// set the map
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as an <code>Object</code> in the Java programming language.
|
||||
*
|
||||
* @return the next value in the input stream
|
||||
* as an <code>Object</code> in the Java programming language
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream
|
||||
*/
|
||||
private Object getNextAttribute() throws SQLException {
|
||||
if (++idx >= attrib.length) {
|
||||
throw new SQLException("SQLInputImpl exception: Invalid read " +
|
||||
"position");
|
||||
} else {
|
||||
lastValueWasNull = attrib[idx] == null;
|
||||
return attrib[idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// Methods for reading attributes from the stream of SQL data.
|
||||
// These methods correspond to the column-accessor methods of
|
||||
// java.sql.ResultSet.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>String</code> in the Java programming language.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code>
|
||||
* implementation.
|
||||
* <p>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream.
|
||||
*/
|
||||
public String readString() throws SQLException {
|
||||
return (String)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>boolean</code> in the Java programming language.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code>
|
||||
* implementation.
|
||||
* <p>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream.
|
||||
*/
|
||||
public boolean readBoolean() throws SQLException {
|
||||
Boolean attrib = (Boolean)getNextAttribute();
|
||||
return (attrib == null) ? false : attrib.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>byte</code> in the Java programming language.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code>
|
||||
* implementation.
|
||||
* <p>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream
|
||||
*/
|
||||
public byte readByte() throws SQLException {
|
||||
Byte attrib = (Byte)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.byteValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>short</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public short readShort() throws SQLException {
|
||||
Short attrib = (Short)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.shortValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as an <code>int</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public int readInt() throws SQLException {
|
||||
Integer attrib = (Integer)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>long</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public long readLong() throws SQLException {
|
||||
Long attrib = (Long)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>float</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public float readFloat() throws SQLException {
|
||||
Float attrib = (Float)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.floatValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>double</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public double readDouble() throws SQLException {
|
||||
Double attrib = (Double)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>java.math.BigDecimal</code>.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public java.math.BigDecimal readBigDecimal() throws SQLException {
|
||||
return (java.math.BigDecimal)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as an array of bytes.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public byte[] readBytes() throws SQLException {
|
||||
return (byte[])getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> as
|
||||
* a <code>java.sql.Date</code> object.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public java.sql.Date readDate() throws SQLException {
|
||||
return (java.sql.Date)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>java.sql.Time</code> object.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.sql.Time readTime() throws SQLException {
|
||||
return (java.sql.Time)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>java.sql.Timestamp</code> object.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.sql.Timestamp readTimestamp() throws SQLException {
|
||||
return (java.sql.Timestamp)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a stream of Unicode characters.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.io.Reader readCharacterStream() throws SQLException {
|
||||
return (java.io.Reader)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a stream of ASCII characters.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>,
|
||||
* return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.io.InputStream readAsciiStream() throws SQLException {
|
||||
return (java.io.InputStream)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a stream of uninterpreted bytes.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.io.InputStream readBinaryStream() throws SQLException {
|
||||
return (java.io.InputStream)getNextAttribute();
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// Methods for reading items of SQL user-defined types from the stream.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Retrieves the value at the head of this <code>SQLInputImpl</code>
|
||||
* object as an <code>Object</code> in the Java programming language. The
|
||||
* actual type of the object returned is determined by the default
|
||||
* mapping of SQL types to types in the Java programming language unless
|
||||
* there is a custom mapping, in which case the type of the object
|
||||
* returned is determined by this stream's type map.
|
||||
* <P>
|
||||
* The JDBC technology-enabled driver registers a type map with the stream
|
||||
* before passing the stream to the application.
|
||||
* <P>
|
||||
* When the datum at the head of the stream is an SQL <code>NULL</code>,
|
||||
* this method returns <code>null</code>. If the datum is an SQL
|
||||
* structured or distinct type with a custom mapping, this method
|
||||
* determines the SQL type of the datum at the head of the stream,
|
||||
* constructs an object of the appropriate class, and calls the method
|
||||
* <code>SQLData.readSQL</code> on that object. The <code>readSQL</code>
|
||||
* method then calls the appropriate <code>SQLInputImpl.readXXX</code>
|
||||
* methods to retrieve the attribute values from the stream.
|
||||
*
|
||||
* @return the value at the head of the stream as an <code>Object</code>
|
||||
* in the Java programming language; <code>null</code> if
|
||||
* the value is SQL <code>NULL</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Object readObject() throws SQLException {
|
||||
Object attrib = getNextAttribute();
|
||||
if (attrib instanceof Struct) {
|
||||
Struct s = (Struct)attrib;
|
||||
// look up the class in the map
|
||||
Class<?> c = map.get(s.getSQLTypeName());
|
||||
if (c != null) {
|
||||
// create new instance of the class
|
||||
SQLData obj = null;
|
||||
try {
|
||||
obj = (SQLData)ReflectUtil.newInstance(c);
|
||||
} catch (Exception ex) {
|
||||
throw new SQLException("Unable to Instantiate: ", ex);
|
||||
}
|
||||
// get the attributes from the struct
|
||||
Object attribs[] = s.getAttributes(map);
|
||||
// create the SQLInput "stream"
|
||||
SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);
|
||||
// read the values...
|
||||
obj.readSQL(sqlInput, s.getSQLTypeName());
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return attrib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value at the head of this <code>SQLInputImpl</code> object
|
||||
* as a <code>Ref</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>Ref</code> object representing the SQL
|
||||
* <code>REF</code> value at the head of the stream; if the value
|
||||
* is <code>SQL NULL</code> return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Ref readRef() throws SQLException {
|
||||
return (Ref)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>BLOB</code> value at the head of this
|
||||
* <code>SQLInputImpl</code> object as a <code>Blob</code> object
|
||||
* in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return a <code>Blob</code> object representing the SQL
|
||||
* <code>BLOB</code> value at the head of this stream;
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Blob readBlob() throws SQLException {
|
||||
return (Blob)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>CLOB</code> value at the head of this
|
||||
* <code>SQLInputImpl</code> object as a <code>Clob</code> object
|
||||
* in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return a <code>Clob</code> object representing the SQL
|
||||
* <code>CLOB</code> value at the head of the stream;
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Clob readClob() throws SQLException {
|
||||
return (Clob)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>ARRAY</code> value from the stream and
|
||||
* returns it as an <code>Array</code> object in the Java programming
|
||||
* language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return an <code>Array</code> object representing the SQL
|
||||
* <code>ARRAY</code> value at the head of the stream; *
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
|
||||
*/
|
||||
public Array readArray() throws SQLException {
|
||||
return (Array)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether the last value read from this
|
||||
* <code>SQLInputImpl</code> object was <code>null</code>.
|
||||
*
|
||||
* @return <code>true</code> if the SQL value read most recently was
|
||||
* <code>null</code>; otherwise, <code>false</code>; by default it
|
||||
* will return false
|
||||
* @throws SQLException if an error occurs determining the last value
|
||||
* read was a <code>null</code> value or not;
|
||||
*/
|
||||
public boolean wasNull() throws SQLException {
|
||||
return lastValueWasNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>DATALINK</code> value from the stream and
|
||||
* returns it as an <code>URL</code> object in the Java programming
|
||||
* language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return an <code>URL</code> object representing the SQL
|
||||
* <code>DATALINK</code> value at the head of the stream; *
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.net.URL readURL() throws SQLException {
|
||||
return (java.net.URL)getNextAttribute();
|
||||
}
|
||||
|
||||
//---------------------------- JDBC 4.0 -------------------------
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>NCLOB</code> value from the stream and returns it as a
|
||||
* <code>Clob</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>NClob</code> object representing data of the SQL <code>NCLOB</code> value
|
||||
* at the head of the stream; <code>null</code> if the value read is
|
||||
* SQL <code>NULL</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public NClob readNClob() throws SQLException {
|
||||
return (NClob)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next attribute in the stream and returns it as a <code>String</code>
|
||||
* in the Java programming language. It is intended for use when
|
||||
* accessing <code>NCHAR</code>,<code>NVARCHAR</code>
|
||||
* and <code>LONGNVARCHAR</code> columns.
|
||||
*
|
||||
* @return the attribute; if the value is SQL <code>NULL</code>, returns <code>null</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public String readNString() throws SQLException {
|
||||
return (String)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>XML</code> value from the stream and returns it as a
|
||||
* <code>SQLXML</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>SQLXML</code> object representing data of the SQL <code>XML</code> value
|
||||
* at the head of the stream; <code>null</code> if the value read is
|
||||
* SQL <code>NULL</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public SQLXML readSQLXML() throws SQLException {
|
||||
return (SQLXML)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>ROWID</code> value from the stream and returns it as a
|
||||
* <code>RowId</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>RowId</code> object representing data of the SQL <code>ROWID</code> value
|
||||
* at the head of the stream; <code>null</code> if the value read is
|
||||
* SQL <code>NULL</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public RowId readRowId() throws SQLException {
|
||||
return (RowId)getNextAttribute();
|
||||
}
|
||||
|
||||
|
||||
}
|
644
jdkSrc/jdk8/javax/sql/rowset/serial/SQLOutputImpl.java
Normal file
644
jdkSrc/jdk8/javax/sql/rowset/serial/SQLOutputImpl.java
Normal file
@@ -0,0 +1,644 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.sql.*;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* The output stream for writing the attributes of a
|
||||
* custom-mapped user-defined type (UDT) back to the database.
|
||||
* The driver uses this interface internally, and its
|
||||
* methods are never directly invoked by an application programmer.
|
||||
* <p>
|
||||
* When an application calls the
|
||||
* method <code>PreparedStatement.setObject</code>, the driver
|
||||
* checks to see whether the value to be written is a UDT with
|
||||
* a custom mapping. If it is, there will be an entry in a
|
||||
* type map containing the <code>Class</code> object for the
|
||||
* class that implements <code>SQLData</code> for this UDT.
|
||||
* If the value to be written is an instance of <code>SQLData</code>,
|
||||
* the driver will create an instance of <code>SQLOutputImpl</code>
|
||||
* and pass it to the method <code>SQLData.writeSQL</code>.
|
||||
* The method <code>writeSQL</code> in turn calls the
|
||||
* appropriate <code>SQLOutputImpl.writeXXX</code> methods
|
||||
* to write data from the <code>SQLData</code> object to
|
||||
* the <code>SQLOutputImpl</code> output stream as the
|
||||
* representation of an SQL user-defined type.
|
||||
*/
|
||||
public class SQLOutputImpl implements SQLOutput {
|
||||
|
||||
/**
|
||||
* A reference to an existing vector that
|
||||
* contains the attributes of a <code>Struct</code> object.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Vector attribs;
|
||||
|
||||
/**
|
||||
* The type map the driver supplies to a newly created
|
||||
* <code>SQLOutputImpl</code> object. This type map
|
||||
* indicates the <code>SQLData</code> class whose
|
||||
* <code>writeSQL</code> method will be called. This
|
||||
* method will in turn call the appropriate
|
||||
* <code>SQLOutputImpl</code> writer methods.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Map map;
|
||||
|
||||
/**
|
||||
* Creates a new <code>SQLOutputImpl</code> object
|
||||
* initialized with the given vector of attributes and
|
||||
* type map. The driver will use the type map to determine
|
||||
* which <code>SQLData.writeSQL</code> method to invoke.
|
||||
* This method will then call the appropriate
|
||||
* <code>SQLOutputImpl</code> writer methods in order and
|
||||
* thereby write the attributes to the new output stream.
|
||||
*
|
||||
* @param attributes a <code>Vector</code> object containing the attributes of
|
||||
* the UDT to be mapped to one or more objects in the Java
|
||||
* programming language
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object containing zero or
|
||||
* more entries, with each entry consisting of 1) a <code>String</code>
|
||||
* 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
|
||||
* @throws SQLException if the <code>attributes</code> or the <code>map</code>
|
||||
* is a <code>null</code> value
|
||||
*/
|
||||
public SQLOutputImpl(Vector<?> attributes, Map<String,?> map)
|
||||
throws SQLException
|
||||
{
|
||||
if ((attributes == null) || (map == null)) {
|
||||
throw new SQLException("Cannot instantiate a SQLOutputImpl " +
|
||||
"instance with null parameters");
|
||||
}
|
||||
this.attribs = attributes;
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// Methods for writing attributes to the stream of SQL data.
|
||||
// These methods correspond to the column-accessor methods of
|
||||
// java.sql.ResultSet.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Writes a <code>String</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>CHAR</code>, <code>VARCHAR</code>, or
|
||||
* <code>LONGVARCHAR</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeString(String x) throws SQLException {
|
||||
//System.out.println("Adding :"+x);
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>boolean</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>BIT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBoolean(boolean x) throws SQLException {
|
||||
attribs.add(Boolean.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>byte</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>BIT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeByte(byte x) throws SQLException {
|
||||
attribs.add(Byte.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>short</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>SMALLINT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeShort(short x) throws SQLException {
|
||||
attribs.add(Short.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an <code>int</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>INTEGER</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeInt(int x) throws SQLException {
|
||||
attribs.add(Integer.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>long</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>BIGINT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeLong(long x) throws SQLException {
|
||||
attribs.add(Long.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>float</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>REAL</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeFloat(float x) throws SQLException {
|
||||
attribs.add(Float.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>double</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>DOUBLE</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeDouble(double x) throws SQLException{
|
||||
attribs.add(Double.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.math.BigDecimal</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>NUMERIC</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBigDecimal(java.math.BigDecimal x) throws SQLException{
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an array of <code>bytes</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBytes(byte[] x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.sql.Date</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>DATE</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeDate(java.sql.Date x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.sql.Time</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>TIME</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTime(java.sql.Time x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.sql.Timestamp</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>TIMESTAMP</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTimestamp(java.sql.Timestamp x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a stream of Unicode characters to this
|
||||
* <code>SQLOutputImpl</code> object. The driver will do any necessary
|
||||
* conversion from Unicode to the database <code>CHAR</code> format.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeCharacterStream(java.io.Reader x) throws SQLException {
|
||||
BufferedReader bufReader = new BufferedReader(x);
|
||||
try {
|
||||
int i;
|
||||
while( (i = bufReader.read()) != -1 ) {
|
||||
char ch = (char)i;
|
||||
StringBuffer strBuf = new StringBuffer();
|
||||
strBuf.append(ch);
|
||||
|
||||
String str = new String(strBuf);
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(str.concat(strLine));
|
||||
}
|
||||
} catch(IOException ioe) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a stream of ASCII characters to this
|
||||
* <code>SQLOutputImpl</code> object. The driver will do any necessary
|
||||
* conversion from ASCII to the database <code>CHAR</code> format.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeAsciiStream(java.io.InputStream x) throws SQLException {
|
||||
BufferedReader bufReader = new BufferedReader(new InputStreamReader(x));
|
||||
try {
|
||||
int i;
|
||||
while( (i=bufReader.read()) != -1 ) {
|
||||
char ch = (char)i;
|
||||
|
||||
StringBuffer strBuf = new StringBuffer();
|
||||
strBuf.append(ch);
|
||||
|
||||
String str = new String(strBuf);
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(str.concat(strLine));
|
||||
}
|
||||
}catch(IOException ioe) {
|
||||
throw new SQLException(ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a stream of uninterpreted bytes to this <code>SQLOutputImpl</code>
|
||||
* object.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBinaryStream(java.io.InputStream x) throws SQLException {
|
||||
BufferedReader bufReader = new BufferedReader(new InputStreamReader(x));
|
||||
try {
|
||||
int i;
|
||||
while( (i=bufReader.read()) != -1 ) {
|
||||
char ch = (char)i;
|
||||
|
||||
StringBuffer strBuf = new StringBuffer();
|
||||
strBuf.append(ch);
|
||||
|
||||
String str = new String(strBuf);
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(str.concat(strLine));
|
||||
}
|
||||
} catch(IOException ioe) {
|
||||
throw new SQLException(ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// Methods for writing items of SQL user-defined types to the stream.
|
||||
// These methods pass objects to the database as values of SQL
|
||||
// Structured Types, Distinct Types, Constructed Types, and Locator
|
||||
// Types. They decompose the Java object(s) and write leaf data
|
||||
// items using the methods above.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Writes to the stream the data contained in the given
|
||||
* <code>SQLData</code> object.
|
||||
* When the <code>SQLData</code> object is <code>null</code>, this
|
||||
* method writes an SQL <code>NULL</code> to the stream.
|
||||
* Otherwise, it calls the <code>SQLData.writeSQL</code>
|
||||
* method of the given object, which
|
||||
* writes the object's attributes to the stream.
|
||||
* <P>
|
||||
* The implementation of the method <code>SQLData.writeSQ</code>
|
||||
* calls the appropriate <code>SQLOutputImpl.writeXXX</code> method(s)
|
||||
* for writing each of the object's attributes in order.
|
||||
* The attributes must be read from an <code>SQLInput</code>
|
||||
* input stream and written to an <code>SQLOutputImpl</code>
|
||||
* output stream in the same order in which they were
|
||||
* listed in the SQL definition of the user-defined type.
|
||||
*
|
||||
* @param x the object representing data of an SQL structured or
|
||||
* distinct type
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeObject(SQLData x) throws SQLException {
|
||||
|
||||
/*
|
||||
* Except for the types that are passed as objects
|
||||
* this seems to be the only way for an object to
|
||||
* get a null value for a field in a structure.
|
||||
*
|
||||
* Note: this means that the class defining SQLData
|
||||
* will need to track if a field is SQL null for itself
|
||||
*/
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
/*
|
||||
* We have to write out a SerialStruct that contains
|
||||
* the name of this class otherwise we don't know
|
||||
* what to re-instantiate during readSQL()
|
||||
*/
|
||||
attribs.add(new SerialStruct(x, map));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Ref</code> object in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to a serializable <code>SerialRef</code> SQL <code>REF</code> value
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>REF</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeRef(Ref x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialRef(x));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Blob</code> object in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to a serializable <code>SerialBlob</code> SQL <code>BLOB</code> value
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>BLOB</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBlob(Blob x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialBlob(x));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Clob</code> object in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to a serializable <code>SerialClob</code> SQL <code>CLOB</code> value
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>CLOB</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeClob(Clob x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialClob(x));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Struct</code> object in the Java
|
||||
* programming language to this <code>SQLOutputImpl</code>
|
||||
* object. The driver converts this value to an SQL structured type
|
||||
* before returning it to the database.
|
||||
* <P>
|
||||
* This method should be used when an SQL structured type has been
|
||||
* mapped to a <code>Struct</code> object in the Java programming
|
||||
* language (the standard mapping). The method
|
||||
* <code>writeObject</code> should be used if an SQL structured type
|
||||
* has been custom mapped to a class in the Java programming language.
|
||||
*
|
||||
* @param x an object representing the attributes of an SQL structured type
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeStruct(Struct x) throws SQLException {
|
||||
SerialStruct s = new SerialStruct(x,map);;
|
||||
attribs.add(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an <code>Array</code> object in the Java
|
||||
* programming language to this <code>SQLOutputImpl</code>
|
||||
* object. The driver converts this value to a serializable
|
||||
* <code>SerialArray</code> SQL <code>ARRAY</code>
|
||||
* value before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>ARRAY</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeArray(Array x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialArray(x, map));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an <code>java.sql.Type.DATALINK</code> object in the Java
|
||||
* programming language to this <code>SQLOutputImpl</code> object. The
|
||||
* driver converts this value to a serializable <code>SerialDatalink</code>
|
||||
* SQL <code>DATALINK</code> value before return it to the database.
|
||||
*
|
||||
* @param url an object representing a SQL <code>DATALINK</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeURL(java.net.URL url) throws SQLException {
|
||||
if (url == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialDatalink(url));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes the next attribute to the stream as a <code>String</code>
|
||||
* in the Java programming language. The driver converts this to a
|
||||
* SQL <code>NCHAR</code> or
|
||||
* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
|
||||
* (depending on the argument's
|
||||
* size relative to the driver's limits on <code>NVARCHAR</code> values)
|
||||
* when it sends it to the stream.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeNString(String x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an SQL <code>NCLOB</code> value to the stream.
|
||||
*
|
||||
* @param x a <code>NClob</code> object representing data of an SQL
|
||||
* <code>NCLOB</code> value
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeNClob(NClob x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes an SQL <code>ROWID</code> value to the stream.
|
||||
*
|
||||
* @param x a <code>RowId</code> object representing data of an SQL
|
||||
* <code>ROWID</code> value
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeRowId(RowId x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes an SQL <code>XML</code> value to the stream.
|
||||
*
|
||||
* @param x a <code>SQLXML</code> object representing data of an SQL
|
||||
* <code>XML</code> value
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeSQLXML(SQLXML x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
}
|
660
jdkSrc/jdk8/javax/sql/rowset/serial/SerialArray.java
Normal file
660
jdkSrc/jdk8/javax/sql/rowset/serial/SerialArray.java
Normal file
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
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
|
||||
* <code>ARRAY</code> value.
|
||||
* <P>
|
||||
* The <code>SerialArray</code> class provides a constructor for creating
|
||||
* a <code>SerialArray</code> instance from an <code>Array</code> object,
|
||||
* 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.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
private int len;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SerialArray</code> object from the given
|
||||
* <code>Array</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.
|
||||
* <P>
|
||||
* The new <code>SerialArray</code>
|
||||
* object contains the same elements as the <code>Array</code> object
|
||||
* from which it is built, except when the base type is the SQL type
|
||||
* <code>STRUCT</code>, <code>ARRAY</code>, <code>BLOB</code>,
|
||||
* <code>CLOB</code>, <code>DATALINK</code> or <code>JAVA_OBJECT</code>.
|
||||
* In this case, each element in the new
|
||||
* <code>SerialArray</code> object is the appropriate serialized form,
|
||||
* that is, a <code>SerialStruct</code>, <code>SerialArray</code>,
|
||||
* <code>SerialBlob</code>, <code>SerialClob</code>,
|
||||
* <code>SerialDatalink</code>, or <code>SerialJavaObject</code> object.
|
||||
* <P>
|
||||
* Note: (1) The <code>Array</code> object from which a <code>SerialArray</code>
|
||||
* object is created must have materialized the SQL <code>ARRAY</code> value's
|
||||
* data on the client before it is passed to the constructor. Otherwise,
|
||||
* the new <code>SerialArray</code> object will contain no data.
|
||||
* <p>
|
||||
* Note: (2) If the <code>Array</code> contains <code>java.sql.Types.JAVA_OBJECT</code>
|
||||
* types, the <code>SerialJavaObject</code> constructor is called where checks
|
||||
* are made to ensure this object is serializable.
|
||||
* <p>
|
||||
* Note: (3) The <code>Array</code> object supplied to this constructor cannot
|
||||
* return <code>null</code> for any <code>Array.getArray()</code> methods.
|
||||
* <code>SerialArray</code> cannot serialize null array values.
|
||||
*
|
||||
*
|
||||
* @param array the <code>Array</code> object to be serialized
|
||||
* @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 (an SQL structured type or
|
||||
* distinct type) and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped. The <i>map</i>
|
||||
* parameter does not have any effect for <code>Blob</code>,
|
||||
* <code>Clob</code>, <code>DATALINK</code>, or
|
||||
* <code>JAVA_OBJECT</code> types.
|
||||
* @throws SerialException if an error occurs serializing the
|
||||
* <code>Array</code> object
|
||||
* @throws SQLException if a database access error occurs or if the
|
||||
* <i>array</i> or the <i>map</i> values are <code>null</code>
|
||||
*/
|
||||
public SerialArray(Array array, Map<String,Class<?>> map)
|
||||
throws SerialException, SQLException
|
||||
{
|
||||
|
||||
if ((array == null) || (map == null)) {
|
||||
throw new SQLException("Cannot instantiate a SerialArray " +
|
||||
"object with null parameters");
|
||||
}
|
||||
|
||||
if ((elements = (Object[])array.getArray()) == null) {
|
||||
throw new SQLException("Invalid Array object. Calls to Array.getArray() " +
|
||||
"return null value which cannot be serialized");
|
||||
}
|
||||
|
||||
elements = (Object[])array.getArray(map);
|
||||
baseType = array.getBaseType();
|
||||
baseTypeName = array.getBaseTypeName();
|
||||
len = elements.length;
|
||||
|
||||
switch (baseType) {
|
||||
case java.sql.Types.STRUCT:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialStruct((Struct)elements[i], map);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.ARRAY:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialArray((Array)elements[i], map);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.BLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialBlob((Blob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.CLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialClob((Clob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.DATALINK:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialDatalink((URL)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.JAVA_OBJECT:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialJavaObject(elements[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 SerialArray's resources
|
||||
* @since 1.6
|
||||
*/
|
||||
public void free() throws SQLException {
|
||||
if (elements != null) {
|
||||
elements = null;
|
||||
baseTypeName= null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SerialArray</code> object from the given
|
||||
* <code>Array</code> object.
|
||||
* <P>
|
||||
* This constructor does not do custom mapping. If the base type of the array
|
||||
* is an SQL structured type and custom mapping is desired, the constructor
|
||||
* <code>SerialArray(Array array, Map map)</code> should be used.
|
||||
* <P>
|
||||
* The new <code>SerialArray</code>
|
||||
* object contains the same elements as the <code>Array</code> object
|
||||
* from which it is built, except when the base type is the SQL type
|
||||
* <code>BLOB</code>,
|
||||
* <code>CLOB</code>, <code>DATALINK</code> or <code>JAVA_OBJECT</code>.
|
||||
* In this case, each element in the new
|
||||
* <code>SerialArray</code> object is the appropriate serialized form,
|
||||
* that is, a <code>SerialBlob</code>, <code>SerialClob</code>,
|
||||
* <code>SerialDatalink</code>, or <code>SerialJavaObject</code> object.
|
||||
* <P>
|
||||
* Note: (1) The <code>Array</code> object from which a <code>SerialArray</code>
|
||||
* object is created must have materialized the SQL <code>ARRAY</code> value's
|
||||
* data on the client before it is passed to the constructor. Otherwise,
|
||||
* the new <code>SerialArray</code> object will contain no data.
|
||||
* <p>
|
||||
* Note: (2) The <code>Array</code> object supplied to this constructor cannot
|
||||
* return <code>null</code> for any <code>Array.getArray()</code> methods.
|
||||
* <code>SerialArray</code> cannot serialize <code>null</code> array values.
|
||||
*
|
||||
* @param array the <code>Array</code> object to be serialized
|
||||
* @throws SerialException if an error occurs serializing the
|
||||
* <code>Array</code> object
|
||||
* @throws SQLException if a database access error occurs or the
|
||||
* <i>array</i> parameter is <code>null</code>.
|
||||
*/
|
||||
public SerialArray(Array array) throws SerialException, SQLException {
|
||||
if (array == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialArray " +
|
||||
"object with a null Array object");
|
||||
}
|
||||
|
||||
if ((elements = (Object[])array.getArray()) == null) {
|
||||
throw new SQLException("Invalid Array object. Calls to Array.getArray() " +
|
||||
"return null value which cannot be serialized");
|
||||
}
|
||||
|
||||
//elements = (Object[])array.getArray();
|
||||
baseType = array.getBaseType();
|
||||
baseTypeName = array.getBaseTypeName();
|
||||
len = elements.length;
|
||||
|
||||
switch (baseType) {
|
||||
|
||||
case java.sql.Types.BLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialBlob((Blob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.CLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialClob((Clob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.DATALINK:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialDatalink((URL)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.JAVA_OBJECT:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialJavaObject(elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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 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;
|
||||
* 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;
|
||||
* 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.
|
||||
* 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
|
||||
* @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;
|
||||
* 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;
|
||||
* 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
|
||||
* <code>SerialArray</code> object
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public String getBaseTypeName() throws SerialException {
|
||||
isValid();
|
||||
return baseTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a <code>ResultSet</code> object holding the elements of
|
||||
* the subarray that starts at
|
||||
* index <i>index</i> and contains up to <i>count</i> successive elements.
|
||||
* This method uses the connection's type map to map the elements of
|
||||
* the array if the map contains
|
||||
* an entry for the base type. Otherwise, the standard mapping is used.
|
||||
*
|
||||
* @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
|
||||
* @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 with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(long index, int count) throws SerialException {
|
||||
SerialException se = new SerialException();
|
||||
se.initCause(new UnsupportedOperationException());
|
||||
throw se;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Retrieves a <code>ResultSet</code> object that contains all of
|
||||
* the elements of the SQL <code>ARRAY</code>
|
||||
* value represented by this <code>SerialArray</code> object. This method uses
|
||||
* the specified map for type map customizations unless the base type of the
|
||||
* array does not match a user-defined type (UDT) in <i>map</i>, in
|
||||
* which case it uses the
|
||||
* standard mapping. This version of the method <code>getResultSet</code>
|
||||
* uses either the given type map or the standard mapping; it never uses the
|
||||
* type map associated with the connection.
|
||||
*
|
||||
* @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 <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 with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(Map<String, Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
SerialException se = new SerialException();
|
||||
se.initCause(new UnsupportedOperationException());
|
||||
throw se;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a <code>ResultSet</code> object that contains all of
|
||||
* the elements in the <code>ARRAY</code> value that this
|
||||
* <code>SerialArray</code> object represents.
|
||||
* If appropriate, the elements of the array are mapped using the connection's
|
||||
* type map; otherwise, the standard mapping is used.
|
||||
*
|
||||
* @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 with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet() throws SerialException {
|
||||
SerialException se = new SerialException();
|
||||
se.initCause(new UnsupportedOperationException());
|
||||
throw se;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a result set holding the elements of the subarray that starts at
|
||||
* Retrieves a <code>ResultSet</code> object that contains a subarray of the
|
||||
* elements in this <code>SerialArray</code> object, starting at
|
||||
* index <i>index</i> and containing up to <i>count</i> successive
|
||||
* elements. This method uses
|
||||
* the specified map for type map customizations unless the base type of the
|
||||
* array does not match a user-defined type (UDT) in <i>map</i>, in
|
||||
* which case it uses the
|
||||
* standard mapping. This version of the method <code>getResultSet</code> uses
|
||||
* either the given type map or the standard mapping; it never uses the type
|
||||
* map associated with the connection.
|
||||
*
|
||||
* @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 <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 with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(long index, int count,
|
||||
Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
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
|
||||
* SerialArray} object whose elements are identical to this object's elements
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialArray} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialArray}
|
||||
* equivalent to this SerialArray, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj instanceof SerialArray) {
|
||||
SerialArray sa = (SerialArray)obj;
|
||||
return baseType == sa.baseType &&
|
||||
baseTypeName.equals(sa.baseTypeName) &&
|
||||
Arrays.equals(elements, sa.elements);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this SerialArray. The hash code for a
|
||||
* {@code SerialArray} object is computed using the hash codes
|
||||
* of the elements of the {@code SerialArray} object
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (((31 + Arrays.hashCode(elements)) * 31 + len) * 31 +
|
||||
baseType) * 31 + baseTypeName.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialArray}. The copy will contain a
|
||||
* 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
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialArray sa = (SerialArray) super.clone();
|
||||
sa.elements = (elements != null) ? Arrays.copyOf(elements, len) : null;
|
||||
return sa;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the {@code SerialArray} from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
Object[] tmp = (Object[])fields.get("elements", null);
|
||||
if (tmp == null)
|
||||
throw new InvalidObjectException("elements is null and should not be!");
|
||||
elements = tmp.clone();
|
||||
len = fields.get("len", 0);
|
||||
if(elements.length != len)
|
||||
throw new InvalidObjectException("elements is not the expected size");
|
||||
|
||||
baseType = fields.get("baseType", 0);
|
||||
baseTypeName = (String)fields.get("baseTypeName", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the {@code SerialArray}
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("elements", elements);
|
||||
fields.put("len", len);
|
||||
fields.put("baseType", baseType);
|
||||
fields.put("baseTypeName", baseTypeName);
|
||||
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.
|
||||
*/
|
||||
static final long serialVersionUID = -8466174297270688520L;
|
||||
}
|
602
jdkSrc/jdk8/javax/sql/rowset/serial/SerialBlob.java
Normal file
602
jdkSrc/jdk8/javax/sql/rowset/serial/SerialBlob.java
Normal file
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* <code>BLOB</code> value.
|
||||
* <P>
|
||||
* The <code>SerialBlob</code> class provides a constructor for creating
|
||||
* an instance from a <code>Blob</code> object. Note that the
|
||||
* <code>Blob</code>
|
||||
* object should have brought the SQL <code>BLOB</code> value's data over
|
||||
* to the client before a <code>SerialBlob</code> object
|
||||
* is constructed from it. The data of an SQL <code>BLOB</code> value can
|
||||
* be materialized on the client as an array of bytes (using the method
|
||||
* <code>Blob.getBytes</code>) or as a stream of uninterpreted bytes
|
||||
* (using the method <code>Blob.getBinaryStream</code>).
|
||||
* <P>
|
||||
* <code>SerialBlob</code> methods make it possible to make a copy of a
|
||||
* <code>SerialBlob</code> object as an array of bytes or as a stream.
|
||||
* They also make it possible to locate a given pattern of bytes or a
|
||||
* <code>Blob</code> object within a <code>SerialBlob</code> object
|
||||
* and to update or truncate a <code>Blob</code> object.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* <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 {
|
||||
|
||||
/**
|
||||
* A serialized array of uninterpreted bytes representing the
|
||||
* value of this <code>SerialBlob</code> object.
|
||||
* @serial
|
||||
*/
|
||||
private byte[] buf;
|
||||
|
||||
/**
|
||||
* The internal representation of the <code>Blob</code> object on which this
|
||||
* <code>SerialBlob</code> object is based.
|
||||
*/
|
||||
private Blob blob;
|
||||
|
||||
/**
|
||||
* The number of bytes in this <code>SerialBlob</code> object's
|
||||
* array of bytes.
|
||||
* @serial
|
||||
*/
|
||||
private long len;
|
||||
|
||||
/**
|
||||
* The original number of bytes in this <code>SerialBlob</code> object's
|
||||
* array of bytes when it was first established.
|
||||
* @serial
|
||||
*/
|
||||
private long origLen;
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialBlob</code> object that is a serialized version of
|
||||
* the given <code>byte</code> array.
|
||||
* <p>
|
||||
* The new <code>SerialBlob</code> object is initialized with the data from the
|
||||
* <code>byte</code> array, thus allowing disconnected <code>RowSet</code>
|
||||
* objects to establish serialized <code>Blob</code> objects without
|
||||
* touching the data source.
|
||||
*
|
||||
* @param b the <code>byte</code> array containing the data for the
|
||||
* <code>Blob</code> object to be serialized
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if a SQL errors occurs
|
||||
*/
|
||||
public SerialBlob(byte[] b)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
len = b.length;
|
||||
buf = new byte[(int)len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
buf[i] = b[i];
|
||||
}
|
||||
origLen = len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialBlob</code> object that is a serialized
|
||||
* version of the given <code>Blob</code> object.
|
||||
* <P>
|
||||
* The new <code>SerialBlob</code> object is initialized with the
|
||||
* data from the <code>Blob</code> object; therefore, the
|
||||
* <code>Blob</code> object should have previously brought the
|
||||
* SQL <code>BLOB</code> value's data over to the client from
|
||||
* the database. Otherwise, the new <code>SerialBlob</code> object
|
||||
* will contain no data.
|
||||
*
|
||||
* @param blob the <code>Blob</code> object from which this
|
||||
* <code>SerialBlob</code> object is to be constructed;
|
||||
* cannot be null.
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if the <code>Blob</code> passed to this
|
||||
* to this constructor is a <code>null</code>.
|
||||
* @see java.sql.Blob
|
||||
*/
|
||||
public SerialBlob (Blob blob)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
if (blob == null) {
|
||||
throw new SQLException(
|
||||
"Cannot instantiate a SerialBlob object with a null Blob object");
|
||||
}
|
||||
|
||||
len = blob.length();
|
||||
buf = blob.getBytes(1, (int)len );
|
||||
this.blob = blob;
|
||||
origLen = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the specified number of bytes, starting at the given
|
||||
* position, from this <code>SerialBlob</code> object to
|
||||
* another array of bytes.
|
||||
* <P>
|
||||
* Note that if the given number of bytes to be copied is larger than
|
||||
* the length of this <code>SerialBlob</code> object's array of
|
||||
* bytes, the given number will be shortened to the array's length.
|
||||
*
|
||||
* @param pos the ordinal position of the first byte in this
|
||||
* <code>SerialBlob</code> object to be copied;
|
||||
* numbering starts at <code>1</code>; must not be less
|
||||
* than <code>1</code> and must be less than or equal
|
||||
* to the length of this <code>SerialBlob</code> object
|
||||
* @param length the number of bytes to be copied
|
||||
* @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;
|
||||
* 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;
|
||||
}
|
||||
|
||||
if (pos < 1 || len - pos < 0 ) {
|
||||
throw new SerialException("Invalid arguments: position cannot be "
|
||||
+ "less than 1 or greater than the length of the SerialBlob");
|
||||
}
|
||||
|
||||
pos--; // correct pos to array index
|
||||
|
||||
byte[] b = new byte[length];
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
b[i] = this.buf[(int)pos];
|
||||
pos++;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the number of bytes in this <code>SerialBlob</code>
|
||||
* object's array of bytes.
|
||||
*
|
||||
* @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;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public long length() throws SerialException {
|
||||
isValid();
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this <code>SerialBlob</code> object as an input stream.
|
||||
* Unlike the related method, <code>setBinaryStream</code>,
|
||||
* a stream is produced regardless of whether the <code>SerialBlob</code>
|
||||
* was created with a <code>Blob</code> object or a <code>byte</code> array.
|
||||
*
|
||||
* @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;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @see #setBinaryStream
|
||||
*/
|
||||
public java.io.InputStream getBinaryStream() throws SerialException {
|
||||
isValid();
|
||||
InputStream stream = new ByteArrayInputStream(buf);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialBlob</code> object where
|
||||
* the given pattern of bytes begins, starting the search at the
|
||||
* specified position.
|
||||
*
|
||||
* @param pattern the pattern of bytes for which to search
|
||||
* @param start the position of the byte in this
|
||||
* <code>SerialBlob</code> object from which to begin
|
||||
* the search; the first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object
|
||||
* @return the position in this <code>SerialBlob</code> object
|
||||
* where the given pattern begins, starting 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;
|
||||
* 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;
|
||||
}
|
||||
|
||||
int pos = (int)start-1; // internally Blobs are stored as arrays.
|
||||
int i = 0;
|
||||
long patlen = pattern.length;
|
||||
|
||||
while (pos < len) {
|
||||
if (pattern[i] == buf[pos]) {
|
||||
if (i + 1 == patlen) {
|
||||
return (pos + 1) - (patlen - 1);
|
||||
}
|
||||
i++; pos++; // increment pos, and i
|
||||
} else if (pattern[i] != buf[pos]) {
|
||||
pos++; // increment pos only
|
||||
}
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialBlob</code> object where
|
||||
* the given <code>Blob</code> object begins, starting the search at the
|
||||
* specified position.
|
||||
*
|
||||
* @param pattern the <code>Blob</code> object for which to search;
|
||||
* @param start the position of the byte in this
|
||||
* <code>SerialBlob</code> object from which to begin
|
||||
* the search; the first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object
|
||||
* @return the position in this <code>SerialBlob</code> object
|
||||
* where the given <code>Blob</code> object begins, starting
|
||||
* 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;
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given array of bytes to the <code>BLOB</code> value that
|
||||
* this <code>Blob</code> object represents, starting at position
|
||||
* <code>pos</code>, and returns the number of bytes written.
|
||||
*
|
||||
* @param pos the position in the SQL <code>BLOB</code> value at which
|
||||
* to start writing. The first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object.
|
||||
* @param bytes the array of bytes to be written to the <code>BLOB</code>
|
||||
* value that this <code>Blob</code> object represents
|
||||
* @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;
|
||||
* 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
|
||||
*/
|
||||
public int setBytes(long pos, byte[] bytes)
|
||||
throws SerialException, SQLException {
|
||||
return setBytes(pos, bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes all or part of the given <code>byte</code> array to the
|
||||
* <code>BLOB</code> value that this <code>Blob</code> object represents
|
||||
* and returns the number of bytes written.
|
||||
* Writing starts at position <code>pos</code> in the <code>BLOB</code>
|
||||
* value; <i>len</i> bytes from the given byte array are written.
|
||||
*
|
||||
* @param pos the position in the <code>BLOB</code> object at which
|
||||
* to start writing. The first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object.
|
||||
* @param bytes the array of bytes to be written to the <code>BLOB</code>
|
||||
* value
|
||||
* @param offset the offset in the <code>byte</code> array at which
|
||||
* to start reading the bytes. The first offset position is
|
||||
* <code>0</code>; must not be less than <code>0</code> nor greater
|
||||
* than the length of the <code>byte</code> array
|
||||
* @param length the number of bytes to be written to the
|
||||
* <code>BLOB</code> value from the array of bytes <i>bytes</i>.
|
||||
*
|
||||
* @return the number of bytes written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <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;
|
||||
* 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
|
||||
*/
|
||||
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");
|
||||
}
|
||||
|
||||
if (pos < 1 || pos > this.length()) {
|
||||
throw new SerialException("Invalid position in BLOB object set");
|
||||
}
|
||||
|
||||
if ((long)(length) > origLen) {
|
||||
throw new SerialException("Buffer is not sufficient to hold the value");
|
||||
}
|
||||
|
||||
if ((length + offset) > bytes.length) {
|
||||
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
|
||||
"and length that is greater that the Blob buffer");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
pos--; // correct to array indexing
|
||||
while ( i < length || (offset + i +1) < (bytes.length-offset) ) {
|
||||
this.buf[(int)pos + i] = bytes[offset + i ];
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stream that can be used to write to the <code>BLOB</code>
|
||||
* value that this <code>Blob</code> object represents. The stream begins
|
||||
* at position <code>pos</code>. This method forwards the
|
||||
* <code>setBinaryStream()</code> call to the underlying <code>Blob</code> in
|
||||
* the event that this <code>SerialBlob</code> object is instantiated with a
|
||||
* <code>Blob</code>. If this <code>SerialBlob</code> is instantiated with
|
||||
* a <code>byte</code> array, a <code>SerialException</code> is thrown.
|
||||
*
|
||||
* @param pos the position in the <code>BLOB</code> value at which
|
||||
* to start writing
|
||||
* @return a <code>java.io.OutputStream</code> object to which data can
|
||||
* be written
|
||||
* @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>;
|
||||
* 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 {
|
||||
throw new SerialException("Unsupported operation. SerialBlob cannot " +
|
||||
"return a writable binary stream, unless instantiated with a Blob object " +
|
||||
"that provides a setBinaryStream() implementation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the <code>BLOB</code> value that this <code>Blob</code>
|
||||
* object represents to be <code>len</code> bytes in length.
|
||||
*
|
||||
* @param length the length, in bytes, to which the <code>BLOB</code>
|
||||
* 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;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public void truncate(long length) throws SerialException {
|
||||
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} 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} 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} 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 {
|
||||
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 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
|
||||
* @since 1.6
|
||||
*/
|
||||
public void free() throws SQLException {
|
||||
if (buf != null) {
|
||||
buf = null;
|
||||
if (blob != null) {
|
||||
blob.free();
|
||||
}
|
||||
blob = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialBlob to the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
* SerialBlob} object that represents the same sequence of bytes as this
|
||||
* object.
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialBlob} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialBlob}
|
||||
* equivalent to this SerialBlob, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialBlob) {
|
||||
SerialBlob sb = (SerialBlob)obj;
|
||||
if (this.len == sb.len) {
|
||||
return Arrays.equals(buf, sb.buf);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialBlob}.
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((31 + Arrays.hashCode(buf)) * 31 + (int)len) * 31 + (int)origLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialBlob}. The copy will contain a
|
||||
* reference to a clone of the internal byte array, not a reference
|
||||
* to the original internal byte array of this {@code SerialBlob} object.
|
||||
* The underlying {@code Blob} object will be set to null.
|
||||
*
|
||||
* @return a clone of this SerialBlob
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialBlob sb = (SerialBlob) super.clone();
|
||||
sb.buf = (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
|
||||
sb.blob = null;
|
||||
return sb;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the SerialBlob from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
byte[] tmp = (byte[])fields.get("buf", null);
|
||||
if (tmp == null)
|
||||
throw new InvalidObjectException("buf is null and should not be!");
|
||||
buf = tmp.clone();
|
||||
len = fields.get("len", 0L);
|
||||
if (buf.length != len)
|
||||
throw new InvalidObjectException("buf is not the expected size");
|
||||
origLen = fields.get("origLen", 0L);
|
||||
blob = (Blob) fields.get("blob", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the SerialBlob
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("buf", buf);
|
||||
fields.put("len", len);
|
||||
fields.put("origLen", origLen);
|
||||
// Note: this check to see if it is an instance of Serializable
|
||||
// is for backwards compatibiity
|
||||
fields.put("blob", blob instanceof Serializable ? blob : null);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
694
jdkSrc/jdk8/javax/sql/rowset/serial/SerialClob.java
Normal file
694
jdkSrc/jdk8/javax/sql/rowset/serial/SerialClob.java
Normal file
@@ -0,0 +1,694 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* <code>CLOB</code> value.
|
||||
* <P>
|
||||
* The <code>SerialClob</code> class provides a constructor for creating
|
||||
* an instance from a <code>Clob</code> object. Note that the <code>Clob</code>
|
||||
* object should have brought the SQL <code>CLOB</code> value's data over
|
||||
* to the client before a <code>SerialClob</code> object
|
||||
* is constructed from it. The data of an SQL <code>CLOB</code> value can
|
||||
* be materialized on the client as a stream of Unicode characters.
|
||||
* <P>
|
||||
* <code>SerialClob</code> methods make it possible to get a substring
|
||||
* from a <code>SerialClob</code> object or to locate the start of
|
||||
* a pattern of characters.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* <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 {
|
||||
|
||||
/**
|
||||
* A serialized array of characters containing the data of the SQL
|
||||
* <code>CLOB</code> value that this <code>SerialClob</code> object
|
||||
* represents.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private char buf[];
|
||||
|
||||
/**
|
||||
* Internal Clob representation if SerialClob is initialized with a
|
||||
* Clob. Null if SerialClob is initialized with a char[].
|
||||
*/
|
||||
private Clob clob;
|
||||
|
||||
/**
|
||||
* The length in characters of this <code>SerialClob</code> object's
|
||||
* internal array of characters.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private long len;
|
||||
|
||||
/**
|
||||
* The original length in characters of this <code>SerialClob</code>
|
||||
* object's internal array of characters.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private long origLen;
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialClob</code> object that is a serialized version of
|
||||
* the given <code>char</code> array.
|
||||
* <p>
|
||||
* The new <code>SerialClob</code> object is initialized with the data from the
|
||||
* <code>char</code> array, thus allowing disconnected <code>RowSet</code>
|
||||
* objects to establish a serialized <code>Clob</code> object without touching
|
||||
* the data source.
|
||||
*
|
||||
* @param ch the char array representing the <code>Clob</code> object to be
|
||||
* serialized
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if a SQL error occurs
|
||||
*/
|
||||
public SerialClob(char ch[]) throws SerialException, SQLException {
|
||||
|
||||
// %%% JMB. Agreed. Add code here to throw a SQLException if no
|
||||
// support is available for locatorsUpdateCopy=false
|
||||
// Serializing locators is not supported.
|
||||
|
||||
len = ch.length;
|
||||
buf = new char[(int)len];
|
||||
for (int i = 0; i < len ; i++){
|
||||
buf[i] = ch[i];
|
||||
}
|
||||
origLen = len;
|
||||
clob = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialClob</code> object that is a serialized
|
||||
* version of the given <code>Clob</code> object.
|
||||
* <P>
|
||||
* The new <code>SerialClob</code> object is initialized with the
|
||||
* data from the <code>Clob</code> object; therefore, the
|
||||
* <code>Clob</code> object should have previously brought the
|
||||
* SQL <code>CLOB</code> value's data over to the client from
|
||||
* the database. Otherwise, the new <code>SerialClob</code> object
|
||||
* object will contain no data.
|
||||
* <p>
|
||||
* Note: The <code>Clob</code> object supplied to this constructor must
|
||||
* return non-null for both the <code>Clob.getCharacterStream()</code>
|
||||
* and <code>Clob.getAsciiStream</code> methods. This <code>SerialClob</code>
|
||||
* constructor cannot serialize a <code>Clob</code> object in this instance
|
||||
* and will throw an <code>SQLException</code> object.
|
||||
*
|
||||
* @param clob the <code>Clob</code> object from which this
|
||||
* <code>SerialClob</code> object is to be constructed; cannot be null
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if a SQL error occurs in capturing the CLOB;
|
||||
* if the <code>Clob</code> object is a null; or if either of the
|
||||
* <code>Clob.getCharacterStream()</code> and <code>Clob.getAsciiStream()</code>
|
||||
* methods on the <code>Clob</code> returns a null
|
||||
* @see java.sql.Clob
|
||||
*/
|
||||
public SerialClob(Clob clob) throws SerialException, SQLException {
|
||||
|
||||
if (clob == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialClob " +
|
||||
"object with a null Clob object");
|
||||
}
|
||||
len = clob.length();
|
||||
this.clob = clob;
|
||||
buf = new char[(int)len];
|
||||
int read = 0;
|
||||
int offset = 0;
|
||||
|
||||
try (Reader charStream = clob.getCharacterStream()) {
|
||||
if (charStream == null) {
|
||||
throw new SQLException("Invalid Clob object. The call to getCharacterStream " +
|
||||
"returned null which cannot be serialized.");
|
||||
}
|
||||
|
||||
// Note: get an ASCII stream in order to null-check it,
|
||||
// even though we don't do anything with it.
|
||||
try (InputStream asciiStream = clob.getAsciiStream()) {
|
||||
if (asciiStream == null) {
|
||||
throw new SQLException("Invalid Clob object. The call to getAsciiStream " +
|
||||
"returned null which cannot be serialized.");
|
||||
}
|
||||
}
|
||||
|
||||
try (Reader reader = new BufferedReader(charStream)) {
|
||||
do {
|
||||
read = reader.read(buf, offset, (int)(len - offset));
|
||||
offset += read;
|
||||
} while (read > 0);
|
||||
}
|
||||
} catch (java.io.IOException ex) {
|
||||
throw new SerialException("SerialClob: " + ex.getMessage());
|
||||
}
|
||||
|
||||
origLen = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the number of characters in this <code>SerialClob</code>
|
||||
* object's array of characters.
|
||||
*
|
||||
* @return a <code>long</code> indicating the length in characters of this
|
||||
* <code>SerialClob</code> object's array of character
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public long length() throws SerialException {
|
||||
isValid();
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this <code>SerialClob</code> object's data as a stream
|
||||
* of Unicode characters. Unlike the related method, <code>getAsciiStream</code>,
|
||||
* a stream is produced regardless of whether the <code>SerialClob</code> object
|
||||
* was created with a <code>Clob</code> object or a <code>char</code> array.
|
||||
*
|
||||
* @return a <code>java.io.Reader</code> object containing this
|
||||
* <code>SerialClob</code> object's data
|
||||
* @throws SerialException if an error occurs;
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>CLOB</code> value designated by this <code>SerialClob</code>
|
||||
* object as an ascii stream. This method forwards the <code>getAsciiStream</code>
|
||||
* call to the underlying <code>Clob</code> object in the event that this
|
||||
* <code>SerialClob</code> object is instantiated with a <code>Clob</code>
|
||||
* object. If this <code>SerialClob</code> object is instantiated with
|
||||
* a <code>char</code> array, a <code>SerialException</code> object is thrown.
|
||||
*
|
||||
* @return a <code>java.io.InputStream</code> object containing
|
||||
* this <code>SerialClob</code> object's data
|
||||
* @throws SerialException if this {@code SerialClob} 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
|
||||
*/
|
||||
public java.io.InputStream getAsciiStream() throws SerialException, SQLException {
|
||||
isValid();
|
||||
if (this.clob != null) {
|
||||
return this.clob.getAsciiStream();
|
||||
} else {
|
||||
throw new SerialException("Unsupported operation. SerialClob cannot " +
|
||||
"return a the CLOB value as an ascii stream, unless instantiated " +
|
||||
"with a fully implemented Clob object.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the substring contained in this
|
||||
* <code>SerialClob</code> object, starting at the given position
|
||||
* and continuing for the specified number or characters.
|
||||
*
|
||||
* @param pos the position of the first character in the substring
|
||||
* to be copied; the first character of the
|
||||
* <code>SerialClob</code> object is at position
|
||||
* <code>1</code>; must not be less than <code>1</code>,
|
||||
* and the sum of the starting position and the length
|
||||
* of the substring must be less than the length of this
|
||||
* <code>SerialClob</code> object
|
||||
* @param length the number of characters in the substring to be
|
||||
* returned; must not be greater than the length of
|
||||
* this <code>SerialClob</code> object, and the
|
||||
* sum of the starting position and the length
|
||||
* of the substring must be less than the length of this
|
||||
* <code>SerialClob</code> object
|
||||
* @return a <code>String</code> object containing a substring of
|
||||
* this <code>SerialClob</code> object beginning at the
|
||||
* given position and containing the specified number of
|
||||
* consecutive characters
|
||||
* @throws SerialException if either of the arguments is out of bounds;
|
||||
* 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 SerialClob object set");
|
||||
}
|
||||
|
||||
if ((pos-1) + length > this.length()) {
|
||||
throw new SerialException("Invalid position and substring length");
|
||||
}
|
||||
|
||||
try {
|
||||
return new String(buf, (int)pos - 1, length);
|
||||
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
throw new SerialException("StringIndexOutOfBoundsException: " +
|
||||
e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialClob</code> object
|
||||
* where the given <code>String</code> object begins, starting
|
||||
* the search at the specified position. This method returns
|
||||
* <code>-1</code> if the pattern is not found.
|
||||
*
|
||||
* @param searchStr the <code>String</code> object for which to
|
||||
* search
|
||||
* @param start the position in this <code>SerialClob</code> object
|
||||
* at which to start the search; the first position is
|
||||
* <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @return the position at which the given <code>String</code> object
|
||||
* begins, starting the search at the specified position;
|
||||
* <code>-1</code> if the given <code>String</code> object is
|
||||
* not found or the starting position is out of bounds; position
|
||||
* numbering for the return value starts at <code>1</code>
|
||||
* @throws SerialException if 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;
|
||||
}
|
||||
|
||||
char pattern[] = searchStr.toCharArray();
|
||||
|
||||
int pos = (int)start-1;
|
||||
int i = 0;
|
||||
long patlen = pattern.length;
|
||||
|
||||
while (pos < len) {
|
||||
if (pattern[i] == buf[pos]) {
|
||||
if (i + 1 == patlen) {
|
||||
return (pos + 1) - (patlen - 1);
|
||||
}
|
||||
i++; pos++; // increment pos, and i
|
||||
|
||||
} else if (pattern[i] != buf[pos]) {
|
||||
pos++; // increment pos only
|
||||
}
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialClob</code> object
|
||||
* where the given <code>Clob</code> signature begins, starting
|
||||
* the search at the specified position. This method returns
|
||||
* <code>-1</code> if the pattern is not found.
|
||||
*
|
||||
* @param searchStr the <code>Clob</code> object for which to search
|
||||
* @param start the position in this <code>SerialClob</code> object
|
||||
* at which to begin the search; the first position is
|
||||
* <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @return the position at which the given <code>Clob</code>
|
||||
* object begins in this <code>SerialClob</code> object,
|
||||
* at or after the specified starting position
|
||||
* @throws SerialException if an error occurs locating the Clob signature;
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given Java <code>String</code> to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents, at the position
|
||||
* <code>pos</code>.
|
||||
*
|
||||
* @param pos the position at which to start writing to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents; the first
|
||||
* position is <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @param str the string to be written to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents
|
||||
* @return the number of characters written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <code>CLOB</code> value; if an invalid position is set; if an
|
||||
* invalid offset value is set; if number of bytes to be written
|
||||
* is greater than the <code>SerialClob</code> length; or the combined
|
||||
* values of the length and offset is greater than the Clob buffer;
|
||||
* 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()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <code>len</code> characters of <code>str</code>, starting
|
||||
* at character <code>offset</code>, to the <code>CLOB</code> value
|
||||
* that this <code>Clob</code> represents.
|
||||
*
|
||||
* @param pos the position at which to start writing to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents; the first
|
||||
* position is <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @param str the string to be written to the <code>CLOB</code>
|
||||
* value that this <code>Clob</code> object represents
|
||||
* @param offset the offset into <code>str</code> to start reading
|
||||
* the characters to be written
|
||||
* @param length the number of characters to be written
|
||||
* @return the number of characters written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <code>CLOB</code> value; if an invalid position is set; if an
|
||||
* invalid offset value is set; if number of bytes to be written
|
||||
* is greater than the <code>SerialClob</code> length; or the combined
|
||||
* values of the length and offset is greater than the Clob buffer;
|
||||
* 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();
|
||||
|
||||
if (offset < 0 || offset > str.length()) {
|
||||
throw new SerialException("Invalid offset in byte array set");
|
||||
}
|
||||
|
||||
if (pos < 1 || pos > this.length()) {
|
||||
throw new SerialException("Invalid position in Clob object set");
|
||||
}
|
||||
|
||||
if ((long)(length) > origLen) {
|
||||
throw new SerialException("Buffer is not sufficient to hold the value");
|
||||
}
|
||||
|
||||
if ((length + offset) > str.length()) {
|
||||
// need check to ensure length + offset !> bytes.length
|
||||
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
|
||||
" and length that is greater that the Blob buffer");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
pos--; //values in the array are at position one less
|
||||
while ( i < length || (offset + i +1) < (str.length() - offset ) ) {
|
||||
this.buf[(int)pos + i ] = cPattern[offset + i ];
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stream to be used to write Ascii characters to the
|
||||
* <code>CLOB</code> value that this <code>SerialClob</code> object represents,
|
||||
* starting at position <code>pos</code>. This method forwards the
|
||||
* <code>setAsciiStream()</code> call to the underlying <code>Clob</code> object in
|
||||
* the event that this <code>SerialClob</code> object is instantiated with a
|
||||
* <code>Clob</code> object. If this <code>SerialClob</code> object is instantiated
|
||||
* with a <code>char</code> array, a <code>SerialException</code> object is thrown.
|
||||
*
|
||||
* @param pos the position at which to start writing to the
|
||||
* <code>CLOB</code> object
|
||||
* @return the stream to which ASCII encoded characters can be written
|
||||
* @throws SerialException if SerialClob is not instantiated with a
|
||||
* Clob object;
|
||||
* 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 {
|
||||
throw new SerialException("Unsupported operation. SerialClob cannot " +
|
||||
"return a writable ascii stream\n unless instantiated with a Clob object " +
|
||||
"that has a setAsciiStream() implementation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stream to be used to write a stream of Unicode characters
|
||||
* to the <code>CLOB</code> value that this <code>SerialClob</code> object
|
||||
* represents, at position <code>pos</code>. This method forwards the
|
||||
* <code>setCharacterStream()</code> call to the underlying <code>Clob</code>
|
||||
* object in the event that this <code>SerialClob</code> object is instantiated with a
|
||||
* <code>Clob</code> object. If this <code>SerialClob</code> object is instantiated with
|
||||
* a <code>char</code> array, a <code>SerialException</code> is thrown.
|
||||
*
|
||||
* @param pos the position at which to start writing to the
|
||||
* <code>CLOB</code> value
|
||||
*
|
||||
* @return a stream to which Unicode encoded characters can be written
|
||||
* @throws SerialException if the SerialClob is not instantiated with
|
||||
* a Clob object;
|
||||
* 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 {
|
||||
throw new SerialException("Unsupported operation. SerialClob cannot " +
|
||||
"return a writable character stream\n unless instantiated with a Clob object " +
|
||||
"that has a setCharacterStream implementation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the <code>CLOB</code> value that this <code>SerialClob</code>
|
||||
* object represents so that it has a length of <code>len</code>
|
||||
* characters.
|
||||
* <p>
|
||||
* Truncating a <code>SerialClob</code> object to length 0 has the effect of
|
||||
* clearing its contents.
|
||||
*
|
||||
* @param length the length, in bytes, to which the <code>CLOB</code>
|
||||
* value should be truncated
|
||||
* @throws SerialException 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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
if (buf != null) {
|
||||
buf = null;
|
||||
if (clob != null) {
|
||||
clob.free();
|
||||
}
|
||||
clob = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialClob to the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
* SerialClob} object that represents the same sequence of characters as this
|
||||
* object.
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialClob} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialClob}
|
||||
* equivalent to this SerialClob, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialClob) {
|
||||
SerialClob sc = (SerialClob)obj;
|
||||
if (this.len == sc.len) {
|
||||
return Arrays.equals(buf, sc.buf);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialClob}.
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((31 + Arrays.hashCode(buf)) * 31 + (int)len) * 31 + (int)origLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialClob}. The copy will contain a
|
||||
* reference to a clone of the internal character array, not a reference
|
||||
* to the original internal character array of this {@code SerialClob} object.
|
||||
* The underlying {@code Clob} object will be set to null.
|
||||
*
|
||||
* @return a clone of this SerialClob
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialClob sc = (SerialClob) super.clone();
|
||||
sc.buf = (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
|
||||
sc.clob = null;
|
||||
return sc;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the SerialClob from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
char[] tmp = (char[])fields.get("buf", null);
|
||||
if (tmp == null)
|
||||
throw new InvalidObjectException("buf is null and should not be!");
|
||||
buf = tmp.clone();
|
||||
len = fields.get("len", 0L);
|
||||
if (buf.length != len)
|
||||
throw new InvalidObjectException("buf is not the expected size");
|
||||
origLen = fields.get("origLen", 0L);
|
||||
clob = (Clob) fields.get("clob", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the SerialClob
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("buf", buf);
|
||||
fields.put("len", len);
|
||||
fields.put("origLen", origLen);
|
||||
// Note: this check to see if it is an instance of Serializable
|
||||
// is for backwards compatibiity
|
||||
fields.put("clob", clob instanceof Serializable ? clob : null);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
170
jdkSrc/jdk8/javax/sql/rowset/serial/SerialDatalink.java
Normal file
170
jdkSrc/jdk8/javax/sql/rowset/serial/SerialDatalink.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* <code>DATALINK</code> value. A <code>DATALINK</code> value
|
||||
* references a file outside of the underlying data source that the
|
||||
* data source manages.
|
||||
* <P>
|
||||
* <code>RowSet</code> implementations can use the method <code>RowSet.getURL</code>
|
||||
* to retrieve a <code>java.net.URL</code> object, which can be used
|
||||
* to manipulate the external data.
|
||||
* <pre>
|
||||
* java.net.URL url = rowset.getURL(1);
|
||||
* </pre>
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* The extracted URL field retrieved from the DATALINK field.
|
||||
* @serial
|
||||
*/
|
||||
private URL url;
|
||||
|
||||
/**
|
||||
* The SQL type of the elements in this <code>SerialDatalink</code>
|
||||
* object. The type is expressed as one of the contants 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>DATALINK</code> value that this SerialDatalink object
|
||||
* represents.
|
||||
* @serial
|
||||
*/
|
||||
private String baseTypeName;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SerialDatalink</code> object from the given
|
||||
* <code>java.net.URL</code> object.
|
||||
* <P>
|
||||
* @param url the {@code URL} to create the {@code SerialDataLink} from
|
||||
* @throws SerialException if url parameter is a null
|
||||
*/
|
||||
public SerialDatalink(URL url) throws SerialException {
|
||||
if (url == null) {
|
||||
throw new SerialException("Cannot serialize empty URL instance");
|
||||
}
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new URL that is a copy of this <code>SerialDatalink</code>
|
||||
* object.
|
||||
*
|
||||
* @return a copy of this <code>SerialDatalink</code> object as a
|
||||
* <code>URL</code> object in the Java programming language.
|
||||
* @throws SerialException if the <code>URL</code> object cannot be de-serialized
|
||||
*/
|
||||
public URL getDatalink() throws SerialException {
|
||||
|
||||
URL aURL = null;
|
||||
|
||||
try {
|
||||
aURL = new URL((this.url).toString());
|
||||
} catch (java.net.MalformedURLException e) {
|
||||
throw new SerialException("MalformedURLException: " + e.getMessage());
|
||||
}
|
||||
return aURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code SerialDatalink} to the specified object.
|
||||
* The result is {@code true} if and only if the argument is not
|
||||
* {@code null} and is a {@code SerialDatalink} object whose URL is
|
||||
* identical to this object's URL
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialDatalink} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialDatalink}
|
||||
* equivalent to this SerialDatalink, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialDatalink) {
|
||||
SerialDatalink sdl = (SerialDatalink) obj;
|
||||
return url.equals(sdl.url);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialDatalink}. The hash code for a
|
||||
* {@code SerialDatalink} object is taken as the hash code of
|
||||
* the {@code URL} it stores
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 31 + url.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialDatalink}.
|
||||
*
|
||||
* @return a clone of this SerialDatalink
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialDatalink sdl = (SerialDatalink) super.clone();
|
||||
return sdl;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject and writeObject are called to restore the state
|
||||
* of the {@code SerialDatalink}
|
||||
* from a stream. Note: we leverage the default Serialized form
|
||||
*/
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* {@code SerialDatalink} object.
|
||||
*/
|
||||
static final long serialVersionUID = 2826907821828733626L;
|
||||
}
|
56
jdkSrc/jdk8/javax/sql/rowset/serial/SerialException.java
Normal file
56
jdkSrc/jdk8/javax/sql/rowset/serial/SerialException.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Indicates and an error with the serialization or de-serialization of
|
||||
* SQL types such as <code>BLOB, CLOB, STRUCT or ARRAY</code> in
|
||||
* addition to SQL types such as <code>DATALINK and JAVAOBJECT</code>
|
||||
*
|
||||
*/
|
||||
public class SerialException extends java.sql.SQLException {
|
||||
|
||||
/**
|
||||
* Creates a new <code>SerialException</code> without a
|
||||
* message.
|
||||
*/
|
||||
public SerialException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>SerialException</code> with the
|
||||
* specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public SerialException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
static final long serialVersionUID = -489794565168592690L;
|
||||
}
|
281
jdkSrc/jdk8/javax/sql/rowset/serial/SerialJavaObject.java
Normal file
281
jdkSrc/jdk8/javax/sql/rowset/serial/SerialJavaObject.java
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Vector;
|
||||
import javax.sql.rowset.RowSetWarning;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* A serializable mapping in the Java programming language of an SQL
|
||||
* <code>JAVA_OBJECT</code> value. Assuming the Java object
|
||||
* implements the <code>Serializable</code> interface, this class simply wraps the
|
||||
* serialization process.
|
||||
* <P>
|
||||
* If however, the serialization is not possible because
|
||||
* the Java object is not immediately serializable, this class will
|
||||
* attempt to serialize all non-static members to permit the object
|
||||
* state to be serialized.
|
||||
* Static or transient fields cannot be serialized; an attempt to serialize
|
||||
* them will result in a <code>SerialException</code> object being thrown.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Placeholder for object to be serialized.
|
||||
*/
|
||||
private Object obj;
|
||||
|
||||
|
||||
/**
|
||||
* Placeholder for all fields in the <code>JavaObject</code> being serialized.
|
||||
*/
|
||||
private transient Field[] fields;
|
||||
|
||||
/**
|
||||
* Constructor for <code>SerialJavaObject</code> helper class.
|
||||
* <p>
|
||||
*
|
||||
* @param obj the Java <code>Object</code> to be serialized
|
||||
* @throws SerialException if the object is found not to be serializable
|
||||
*/
|
||||
public SerialJavaObject(Object obj) throws SerialException {
|
||||
|
||||
// if any static fields are found, an exception
|
||||
// should be thrown
|
||||
|
||||
|
||||
// get Class. Object instance should always be available
|
||||
Class<?> c = obj.getClass();
|
||||
|
||||
// determine if object implements Serializable i/f
|
||||
if (!(obj instanceof java.io.Serializable)) {
|
||||
setWarning(new RowSetWarning("Warning, the object passed to the constructor does not implement Serializable"));
|
||||
}
|
||||
|
||||
// can only determine public fields (obviously). If
|
||||
// any of these are static, this should invalidate
|
||||
// the action of attempting to persist these fields
|
||||
// in a serialized form
|
||||
fields = c.getFields();
|
||||
|
||||
if (hasStaticFields(fields)) {
|
||||
throw new SerialException("Located static fields in " +
|
||||
"object instance. Cannot serialize");
|
||||
}
|
||||
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Object</code> that is a copy of this <code>SerialJavaObject</code>
|
||||
* object.
|
||||
*
|
||||
* @return a copy of this <code>SerialJavaObject</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if the instance is corrupt
|
||||
*/
|
||||
public Object getObject() throws SerialException {
|
||||
return this.obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>Field</code> objects that contains each
|
||||
* field of the object that this helper class is serializing.
|
||||
*
|
||||
* @return an array of <code>Field</code> objects
|
||||
* @throws SerialException if an error is encountered accessing
|
||||
* the serialized object
|
||||
* @throws SecurityException If a security manager, <i>s</i>, is present
|
||||
* and the caller's class loader is not the same as or an
|
||||
* ancestor of the class loader for the class of the
|
||||
* {@linkplain #getObject object} being serialized
|
||||
* and invocation of {@link SecurityManager#checkPackageAccess
|
||||
* s.checkPackageAccess()} denies access to the package
|
||||
* of that class.
|
||||
* @see Class#getFields
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Field[] getFields() throws SerialException {
|
||||
if (fields != null) {
|
||||
Class<?> c = this.obj.getClass();
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
/*
|
||||
* Check if the caller is allowed to access the specified class's package.
|
||||
* If access is denied, throw a SecurityException.
|
||||
*/
|
||||
Class<?> caller = sun.reflect.Reflection.getCallerClass();
|
||||
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
|
||||
c.getClassLoader())) {
|
||||
ReflectUtil.checkPackageAccess(c);
|
||||
}
|
||||
}
|
||||
return c.getFields();
|
||||
} else {
|
||||
throw new SerialException("SerialJavaObject does not contain" +
|
||||
" a serialized object instance");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* <code>SerialJavaObject</code> object.
|
||||
*/
|
||||
static final long serialVersionUID = -1465795139032831023L;
|
||||
|
||||
/**
|
||||
* A container for the warnings issued on this <code>SerialJavaObject</code>
|
||||
* object. When there are multiple warnings, each warning is chained to the
|
||||
* previous warning.
|
||||
*/
|
||||
Vector<RowSetWarning> chain;
|
||||
|
||||
/**
|
||||
* Compares this SerialJavaObject to the specified object.
|
||||
* The result is {@code true} if and only if the argument
|
||||
* is not {@code null} and is a {@code SerialJavaObject}
|
||||
* object that is identical to this object
|
||||
*
|
||||
* @param o The object to compare this {@code SerialJavaObject} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialJavaObject}
|
||||
* equivalent to this SerialJavaObject, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof SerialJavaObject) {
|
||||
SerialJavaObject sjo = (SerialJavaObject) o;
|
||||
return obj.equals(sjo.obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this SerialJavaObject. The hash code for a
|
||||
* {@code SerialJavaObject} object is taken as the hash code of
|
||||
* the {@code Object} it stores
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 31 + obj.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialJavaObject}.
|
||||
*
|
||||
* @return a clone of this SerialJavaObject
|
||||
*/
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialJavaObject sjo = (SerialJavaObject) super.clone();
|
||||
sjo.fields = Arrays.copyOf(fields, fields.length);
|
||||
if (chain != null)
|
||||
sjo.chain = new Vector<>(chain);
|
||||
return sjo;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given warning.
|
||||
*/
|
||||
private void setWarning(RowSetWarning e) {
|
||||
if (chain == null) {
|
||||
chain = new Vector<>();
|
||||
}
|
||||
chain.add(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the {@code SerialJavaObject}
|
||||
* from a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields1 = s.readFields();
|
||||
@SuppressWarnings("unchecked")
|
||||
Vector<RowSetWarning> tmp = (Vector<RowSetWarning>)fields1.get("chain", null);
|
||||
if (tmp != null)
|
||||
chain = new Vector<>(tmp);
|
||||
|
||||
obj = fields1.get("obj", null);
|
||||
if (obj != null) {
|
||||
fields = obj.getClass().getFields();
|
||||
if(hasStaticFields(fields))
|
||||
throw new IOException("Located static fields in " +
|
||||
"object instance. Cannot serialize");
|
||||
} else {
|
||||
throw new IOException("Object cannot be null!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the {@code SerialJavaObject}
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException {
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("obj", obj);
|
||||
fields.put("chain", chain);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if there are any Static Fields in this object
|
||||
*/
|
||||
private static boolean hasStaticFields(Field[] fields) {
|
||||
for (Field field : fields) {
|
||||
if ( field.getModifiers() == Modifier.STATIC) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
257
jdkSrc/jdk8/javax/sql/rowset/serial/SerialRef.java
Normal file
257
jdkSrc/jdk8/javax/sql/rowset/serial/SerialRef.java
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A serialized mapping of a <code>Ref</code> object, which is the mapping in the
|
||||
* Java programming language of an SQL <code>REF</code> value.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* String containing the base type name.
|
||||
* @serial
|
||||
*/
|
||||
private String baseTypeName;
|
||||
|
||||
/**
|
||||
* This will store the type <code>Ref</code> as an <code>Object</code>.
|
||||
*/
|
||||
private Object object;
|
||||
|
||||
/**
|
||||
* Private copy of the Ref reference.
|
||||
*/
|
||||
private Ref reference;
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialRef</code> object from the given <code>Ref</code>
|
||||
* object.
|
||||
*
|
||||
* @param ref a Ref object; cannot be <code>null</code>
|
||||
* @throws SQLException if a database access occurs; if <code>ref</code>
|
||||
* is <code>null</code>; or if the <code>Ref</code> object returns a
|
||||
* <code>null</code> value base type name.
|
||||
* @throws SerialException if an error occurs serializing the <code>Ref</code>
|
||||
* object
|
||||
*/
|
||||
public SerialRef(Ref ref) throws SerialException, SQLException {
|
||||
if (ref == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialRef object " +
|
||||
"with a null Ref object");
|
||||
}
|
||||
reference = ref;
|
||||
object = ref;
|
||||
if (ref.getBaseTypeName() == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialRef object " +
|
||||
"that returns a null base type name");
|
||||
} else {
|
||||
baseTypeName = ref.getBaseTypeName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing the base type name of the <code>Ref</code>.
|
||||
*
|
||||
* @return a string of the base type name of the Ref
|
||||
* @throws SerialException in no Ref object has been set
|
||||
*/
|
||||
public String getBaseTypeName() throws SerialException {
|
||||
return baseTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Object</code> representing the SQL structured type
|
||||
* to which this <code>SerialRef</code> object refers. The attributes
|
||||
* of the structured type are mapped according to the given type map.
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object containing zero or
|
||||
* more entries, with each entry consisting of 1) a <code>String</code>
|
||||
* 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 an object instance resolved from the Ref reference and mapped
|
||||
* according to the supplied type map
|
||||
* @throws SerialException if an error is encountered in the reference
|
||||
* resolution
|
||||
*/
|
||||
public Object getObject(java.util.Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
map = new Hashtable<String, Class<?>>(map);
|
||||
if (object != null) {
|
||||
return map.get(object);
|
||||
} else {
|
||||
throw new SerialException("The object is not set");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Object</code> representing the SQL structured type
|
||||
* to which this <code>SerialRef</code> object refers.
|
||||
*
|
||||
* @return an object instance resolved from the Ref reference
|
||||
* @throws SerialException if an error is encountered in the reference
|
||||
* resolution
|
||||
*/
|
||||
public Object getObject() throws SerialException {
|
||||
|
||||
if (reference != null) {
|
||||
try {
|
||||
return reference.getObject();
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException("SQLException: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (object != null) {
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
throw new SerialException("The object is not set");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SQL structured type that this <code>SerialRef</code> object
|
||||
* references to the given <code>Object</code> object.
|
||||
*
|
||||
* @param obj an <code>Object</code> representing the SQL structured type
|
||||
* to be referenced
|
||||
* @throws SerialException if an error is encountered generating the
|
||||
* the structured type referenced by this <code>SerialRef</code> object
|
||||
*/
|
||||
public void setObject(Object obj) throws SerialException {
|
||||
try {
|
||||
reference.setObject(obj);
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException("SQLException: " + e.getMessage());
|
||||
}
|
||||
object = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialRef to the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
* SerialRef} object that represents the same object as this
|
||||
* object.
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialRef} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialRef}
|
||||
* equivalent to this SerialRef, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if(obj instanceof SerialRef) {
|
||||
SerialRef ref = (SerialRef)obj;
|
||||
return baseTypeName.equals(ref.baseTypeName) &&
|
||||
object.equals(ref.object);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialRef}.
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (31 + object.hashCode()) * 31 + baseTypeName.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialRef}.
|
||||
* The underlying {@code Ref} object will be set to null.
|
||||
*
|
||||
* @return a clone of this SerialRef
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialRef ref = (SerialRef) super.clone();
|
||||
ref.reference = null;
|
||||
return ref;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the SerialRef from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
object = fields.get("object", null);
|
||||
baseTypeName = (String) fields.get("baseTypeName", null);
|
||||
reference = (Ref) fields.get("reference", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the SerialRef
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("baseTypeName", baseTypeName);
|
||||
fields.put("object", object);
|
||||
// Note: this check to see if it is an instance of Serializable
|
||||
// is for backwards compatibiity
|
||||
fields.put("reference", reference instanceof Serializable ? reference : null);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this <code>SerialRef</code>
|
||||
* object.
|
||||
*/
|
||||
static final long serialVersionUID = -4727123500609662274L;
|
||||
|
||||
|
||||
}
|
347
jdkSrc/jdk8/javax/sql/rowset/serial/SerialStruct.java
Normal file
347
jdkSrc/jdk8/javax/sql/rowset/serial/SerialStruct.java
Normal file
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.sql.rowset.*;
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* structured type. Each attribute that is not already serialized
|
||||
* is mapped to a serialized form, and if an attribute is itself
|
||||
* a structured type, each of its attributes that is not already
|
||||
* serialized is mapped to a serialized form.
|
||||
* <P>
|
||||
* In addition, the structured type is custom mapped to a class in the
|
||||
* Java programming language if there is such a mapping, as are
|
||||
* its attributes, if appropriate.
|
||||
* <P>
|
||||
* The <code>SerialStruct</code> class provides a constructor for creating
|
||||
* 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.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* 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 {
|
||||
|
||||
|
||||
/**
|
||||
* The SQL type name for the structured type that this
|
||||
* <code>SerialStruct</code> object represents. This is the name
|
||||
* used in the SQL definition of the SQL structured type.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private String SQLTypeName;
|
||||
|
||||
/**
|
||||
* An array of <code>Object</code> instances in which each
|
||||
* element is an attribute of the SQL structured type that this
|
||||
* <code>SerialStruct</code> object represents. The attributes are
|
||||
* ordered according to their order in the definition of the
|
||||
* SQL structured type.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private Object attribs[];
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialStruct</code> object from the given
|
||||
* <code>Struct</code> object, using the given <code>java.util.Map</code>
|
||||
* object for custom mapping the SQL structured type or any of its
|
||||
* attributes that are SQL structured types.
|
||||
*
|
||||
* @param in an instance of {@code Struct}
|
||||
* @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
|
||||
* @throws SerialException if an error occurs
|
||||
* @see java.sql.Struct
|
||||
*/
|
||||
public SerialStruct(Struct in, Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
// get the type name
|
||||
SQLTypeName = in.getSQLTypeName();
|
||||
System.out.println("SQLTypeName: " + SQLTypeName);
|
||||
|
||||
// get the attributes of the struct
|
||||
attribs = in.getAttributes(map);
|
||||
|
||||
/*
|
||||
* the array may contain further Structs
|
||||
* and/or classes that have been mapped,
|
||||
* other types that we have to serialize
|
||||
*/
|
||||
mapToSerial(map);
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialStruct</code> object from the
|
||||
* given <code>SQLData</code> object, using the given type
|
||||
* map to custom map it to a class in the Java programming
|
||||
* language. The type map gives the SQL type and the class
|
||||
* to which it is mapped. The <code>SQLData</code> object
|
||||
* defines the class to which the SQL type will be mapped.
|
||||
*
|
||||
* @param in an instance of the <code>SQLData</code> class
|
||||
* that defines the mapping of the SQL structured
|
||||
* type to one or more objects in the Java programming language
|
||||
* @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
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public SerialStruct(SQLData in, Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
//set the type name
|
||||
SQLTypeName = in.getSQLTypeName();
|
||||
|
||||
Vector<Object> tmp = new Vector<>();
|
||||
in.writeSQL(new SQLOutputImpl(tmp, map));
|
||||
attribs = tmp.toArray();
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the SQL type name for this <code>SerialStruct</code>
|
||||
* object. This is the name used in the SQL definition of the
|
||||
* structured type
|
||||
*
|
||||
* @return a <code>String</code> object representing the SQL
|
||||
* type name for the SQL structured type that this
|
||||
* <code>SerialStruct</code> object represents
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public String getSQLTypeName() throws SerialException {
|
||||
return SQLTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array of <code>Object</code> values containing the
|
||||
* attributes of the SQL structured type that this
|
||||
* <code>SerialStruct</code> object represents.
|
||||
*
|
||||
* @return an array of <code>Object</code> values, with each
|
||||
* element being an attribute of the SQL structured type
|
||||
* that this <code>SerialStruct</code> object represents
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public Object[] getAttributes() throws SerialException {
|
||||
Object[] val = this.attribs;
|
||||
return (val == null) ? null : Arrays.copyOf(val, val.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the attributes for the SQL structured type that
|
||||
* this <code>SerialStruct</code> represents as an array of
|
||||
* <code>Object</code> values, using the given type map for
|
||||
* custom mapping if appropriate.
|
||||
*
|
||||
* @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 an array of <code>Object</code> values, with each
|
||||
* element being an attribute of the SQL structured
|
||||
* type that this <code>SerialStruct</code> object
|
||||
* represents
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public Object[] getAttributes(Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
Object[] val = this.attribs;
|
||||
return (val == null) ? null : Arrays.copyOf(val, val.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps attributes of an SQL structured type that are not
|
||||
* serialized to a serialized form, using the given type map
|
||||
* for custom mapping when appropriate. The following types
|
||||
* in the Java programming language are mapped to their
|
||||
* serialized forms: <code>Struct</code>, <code>SQLData</code>,
|
||||
* <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, and
|
||||
* <code>Array</code>.
|
||||
* <P>
|
||||
* This method is called internally and is not used by an
|
||||
* application programmer.
|
||||
*
|
||||
* @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
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
private void mapToSerial(Map<String,Class<?>> map) throws SerialException {
|
||||
|
||||
try {
|
||||
|
||||
for (int i = 0; i < attribs.length; i++) {
|
||||
if (attribs[i] instanceof Struct) {
|
||||
attribs[i] = new SerialStruct((Struct)attribs[i], map);
|
||||
} else if (attribs[i] instanceof SQLData) {
|
||||
attribs[i] = new SerialStruct((SQLData)attribs[i], map);
|
||||
} else if (attribs[i] instanceof Blob) {
|
||||
attribs[i] = new SerialBlob((Blob)attribs[i]);
|
||||
} else if (attribs[i] instanceof Clob) {
|
||||
attribs[i] = new SerialClob((Clob)attribs[i]);
|
||||
} else if (attribs[i] instanceof Ref) {
|
||||
attribs[i] = new SerialRef((Ref)attribs[i]);
|
||||
} else if (attribs[i] instanceof java.sql.Array) {
|
||||
attribs[i] = new SerialArray((java.sql.Array)attribs[i], map);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException(e.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialStruct to the specified object. The result is
|
||||
* {@code true} if and only if the argument is not {@code null} and is a
|
||||
* {@code SerialStruct} object whose attributes are identical to this
|
||||
* object's attributes
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialStruct} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialStruct}
|
||||
* equivalent to this SerialStruct, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialStruct) {
|
||||
SerialStruct ss = (SerialStruct)obj;
|
||||
return SQLTypeName.equals(ss.SQLTypeName) &&
|
||||
Arrays.equals(attribs, ss.attribs);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialStruct}. The hash code for a
|
||||
* {@code SerialStruct} object is computed using the hash codes
|
||||
* of the attributes of the {@code SerialStruct} object and its
|
||||
* {@code SQLTypeName}
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((31 + Arrays.hashCode(attribs)) * 31) * 31
|
||||
+ SQLTypeName.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialStruct}. The copy will contain a
|
||||
* reference to a clone of the underlying attribs array, not a reference
|
||||
* to the original underlying attribs array of this {@code SerialStruct} object.
|
||||
*
|
||||
* @return a clone of this SerialStruct
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialStruct ss = (SerialStruct) super.clone();
|
||||
ss.attribs = Arrays.copyOf(attribs, attribs.length);
|
||||
return ss;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the {@code SerialStruct} from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
Object[] tmp = (Object[])fields.get("attribs", null);
|
||||
attribs = tmp == null ? null : tmp.clone();
|
||||
SQLTypeName = (String)fields.get("SQLTypeName", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the {@code SerialStruct}
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("attribs", attribs);
|
||||
fields.put("SQLTypeName", SQLTypeName);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* <code>SerialStruct</code> object.
|
||||
*/
|
||||
static final long serialVersionUID = -8322445504027483372L;
|
||||
}
|
Reference in New Issue
Block a user