/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
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 SQLInputImpl
object is an input stream that contains a
* stream of values that are the attributes of a UDT.
*
* This class is used by the driver behind the scenes when the method
* getObject
is called on an SQL structured or distinct type
* that has a custom mapping; a programmer never invokes
* SQLInputImpl
methods directly. They are provided here as a
* convenience for those who write RowSet
implementations.
*
* The SQLInputImpl
class provides a set of
* reader methods analogous to the ResultSet
getter
* methods. These methods make it possible to read the values in an
* SQLInputImpl
object.
*
* The method wasNull
is used to determine whether the
* the last value read was SQL NULL
.
*
When the method
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* @return the next attribute in this
* 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
* 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
* 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
* 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
* The JDBC technology-enabled driver registers a type map with the stream
* before passing the stream to the application.
*
* When the datum at the head of the stream is an SQL
* 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
* 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
* 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
* 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 getObject
is called with an
* object of a class implementing the interface SQLData
,
* the JDBC driver calls the method SQLData.getSQLType
* to determine the SQL type of the UDT being custom mapped. The driver
* creates an instance of SQLInputImpl
, populating it with the
* attributes of the UDT. The driver then passes the input
* stream to the method SQLData.readSQL
, which in turn
* calls the SQLInputImpl
reader methods
* to read the attributes from the input stream.
* @since 1.5
* @see java.sql.SQLData
*/
public class SQLInputImpl implements SQLInput {
/**
* true
if the last value returned was SQL NULL
;
* false
otherwise.
*/
private boolean lastValueWasNull;
/**
* The current index into the array of SQL structured type attributes
* that will be read from this SQLInputImpl
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 readObject
* is invoked. This is a java.util.Map
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
* Class
object for a class that implements
* SQLData
(the Java class that defines how the UDT
* will be mapped).
*/
private MapSQLInputImpl
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
* SQLData
implementation.
*
* @param attributes an array of Object
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 java.util.Map
object containing zero or more
* entries, with each entry consisting of 1) a String
* giving the fully
* qualified name of the UDT and 2) the Class
object
* for the SQLData
implementation that defines how
* the UDT is to be mapped
* @throws SQLException if the attributes
or the map
* is a null
value
*/
public SQLInputImpl(Object[] attributes, MapSQLInputImpl
object
* as an Object
in the Java programming language.
*
* @return the next value in the input stream
* as an Object
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 SQLInputImpl
object as
* a String
in the Java programming language.
* SQLData
* implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object as
* a boolean
in the Java programming language.
* SQLData
* implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object as
* a byte
in the Java programming language.
* SQLData
* implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as a short
in the Java programming language.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as an int
in the Java programming language.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as a long
in the Java programming language.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as a float
in the Java programming language.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as a double
in the Java programming language.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as a java.math.BigDecimal
.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as an array of bytes.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
as
* a java.sql.Date
object.
* SQLData
implementation.
* SQLInputImpl
object;
* if the value is SQL NULL
, return null
* @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 SQLInputImpl
object as
* a java.sql.Time
object.
* SQLData
* implementation.
*
* @return the attribute; if the value is SQL NULL
, return
* null
* @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 SQLInputImpl
object as
* a java.sql.Timestamp
object.
*
* @return the attribute; if the value is SQL NULL
, return
* null
* @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 SQLInputImpl
object
* as a stream of Unicode characters.
* SQLData
* implementation.
*
* @return the attribute; if the value is SQL NULL
, return null
* @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 SQLInputImpl
object
* as a stream of ASCII characters.
* SQLData
* implementation.
*
* @return the attribute; if the value is SQL NULL
,
* return null
* @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 SQLInputImpl
object
* as a stream of uninterpreted bytes.
* SQLData
* implementation.
*
* @return the attribute; if the value is SQL NULL
, return
* null
* @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 SQLInputImpl
* object as an Object
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.
* NULL
,
* this method returns null
. 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
* SQLData.readSQL
on that object. The readSQL
* method then calls the appropriate SQLInputImpl.readXXX
* methods to retrieve the attribute values from the stream.
*
* @return the value at the head of the stream as an Object
* in the Java programming language; null
if
* the value is SQL NULL
* @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 SQLInputImpl
object
* as a Ref
object in the Java programming language.
*
* @return a Ref
object representing the SQL
* REF
value at the head of the stream; if the value
* is SQL NULL
return null
* @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 BLOB
value at the head of this
* SQLInputImpl
object as a Blob
object
* in the Java programming language.
* SQLData
* implementation.
*
* @return a Blob
object representing the SQL
* BLOB
value at the head of this stream;
* if the value is SQL NULL
, return
* null
* @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 CLOB
value at the head of this
* SQLInputImpl
object as a Clob
object
* in the Java programming language.
* SQLData
* implementation.
*
* @return a Clob
object representing the SQL
* CLOB
value at the head of the stream;
* if the value is SQL NULL
, return
* null
* @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 ARRAY
value from the stream and
* returns it as an Array
object in the Java programming
* language.
* SQLData
* implementation.
*
* @return an Array
object representing the SQL
* ARRAY
value at the head of the stream; *
* if the value is SQL NULL
, return
* null
* @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
* SQLInputImpl
object was null
.
*
* @return true
if the SQL value read most recently was
* null
; otherwise, false
; by default it
* will return false
* @throws SQLException if an error occurs determining the last value
* read was a null
value or not;
*/
public boolean wasNull() throws SQLException {
return lastValueWasNull;
}
/**
* Reads an SQL DATALINK
value from the stream and
* returns it as an URL
object in the Java programming
* language.
* SQLData
* implementation.
*
* @return an URL
object representing the SQL
* DATALINK
value at the head of the stream; *
* if the value is SQL NULL
, return
* null
* @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 NCLOB
value from the stream and returns it as a
* Clob
object in the Java programming language.
*
* @return a NClob
object representing data of the SQL NCLOB
value
* at the head of the stream; null
if the value read is
* SQL NULL
* @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 String
* in the Java programming language. It is intended for use when
* accessing NCHAR
,NVARCHAR
* and LONGNVARCHAR
columns.
*
* @return the attribute; if the value is SQL NULL
, returns null
* @exception SQLException if a database access error occurs
* @since 1.6
*/
public String readNString() throws SQLException {
return (String)getNextAttribute();
}
/**
* Reads an SQL XML
value from the stream and returns it as a
* SQLXML
object in the Java programming language.
*
* @return a SQLXML
object representing data of the SQL XML
value
* at the head of the stream; null
if the value read is
* SQL NULL
* @exception SQLException if a database access error occurs
* @since 1.6
*/
public SQLXML readSQLXML() throws SQLException {
return (SQLXML)getNextAttribute();
}
/**
* Reads an SQL ROWID
value from the stream and returns it as a
* RowId
object in the Java programming language.
*
* @return a RowId
object representing data of the SQL ROWID
value
* at the head of the stream; null
if the value read is
* SQL NULL
* @exception SQLException if a database access error occurs
* @since 1.6
*/
public RowId readRowId() throws SQLException {
return (RowId)getNextAttribute();
}
}