Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/sql/rowset/serial/SQLInputImpl.java
38918 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package javax.sql.rowset.serial;2526import java.sql.*;27import java.util.Arrays;28import java.util.Map;29import sun.reflect.misc.ReflectUtil;3031/**32* An input stream used for custom mapping user-defined types (UDTs).33* An <code>SQLInputImpl</code> object is an input stream that contains a34* stream of values that are the attributes of a UDT.35* <p>36* This class is used by the driver behind the scenes when the method37* <code>getObject</code> is called on an SQL structured or distinct type38* that has a custom mapping; a programmer never invokes39* <code>SQLInputImpl</code> methods directly. They are provided here as a40* convenience for those who write <code>RowSet</code> implementations.41* <P>42* The <code>SQLInputImpl</code> class provides a set of43* reader methods analogous to the <code>ResultSet</code> getter44* methods. These methods make it possible to read the values in an45* <code>SQLInputImpl</code> object.46* <P>47* The method <code>wasNull</code> is used to determine whether the48* the last value read was SQL <code>NULL</code>.49* <P>When the method <code>getObject</code> is called with an50* object of a class implementing the interface <code>SQLData</code>,51* the JDBC driver calls the method <code>SQLData.getSQLType</code>52* to determine the SQL type of the UDT being custom mapped. The driver53* creates an instance of <code>SQLInputImpl</code>, populating it with the54* attributes of the UDT. The driver then passes the input55* stream to the method <code>SQLData.readSQL</code>, which in turn56* calls the <code>SQLInputImpl</code> reader methods57* to read the attributes from the input stream.58* @since 1.559* @see java.sql.SQLData60*/61public class SQLInputImpl implements SQLInput {6263/**64* <code>true</code> if the last value returned was <code>SQL NULL</code>;65* <code>false</code> otherwise.66*/67private boolean lastValueWasNull;6869/**70* The current index into the array of SQL structured type attributes71* that will be read from this <code>SQLInputImpl</code> object and72* mapped to the fields of a class in the Java programming language.73*/74private int idx;7576/**77* The array of attributes to be read from this stream. The order78* of the attributes is the same as the order in which they were79* listed in the SQL definition of the UDT.80*/81private Object attrib[];8283/**84* The type map to use when the method <code>readObject</code>85* is invoked. This is a <code>java.util.Map</code> object in which86* there may be zero or more entries. Each entry consists of the87* fully qualified name of a UDT (the value to be mapped) and the88* <code>Class</code> object for a class that implements89* <code>SQLData</code> (the Java class that defines how the UDT90* will be mapped).91*/92private Map<String,Class<?>> map;939495/**96* Creates an <code>SQLInputImpl</code> object initialized with the97* given array of attributes and the given type map. If any of the98* attributes is a UDT whose name is in an entry in the type map,99* the attribute will be mapped according to the corresponding100* <code>SQLData</code> implementation.101*102* @param attributes an array of <code>Object</code> instances in which103* each element is an attribute of a UDT. The order of the104* attributes in the array is the same order in which105* the attributes were defined in the UDT definition.106* @param map a <code>java.util.Map</code> object containing zero or more107* entries, with each entry consisting of 1) a <code>String</code>108* giving the fully109* qualified name of the UDT and 2) the <code>Class</code> object110* for the <code>SQLData</code> implementation that defines how111* the UDT is to be mapped112* @throws SQLException if the <code>attributes</code> or the <code>map</code>113* is a <code>null</code> value114*/115116public SQLInputImpl(Object[] attributes, Map<String,Class<?>> map)117throws SQLException118{119if ((attributes == null) || (map == null)) {120throw new SQLException("Cannot instantiate a SQLInputImpl " +121"object with null parameters");122}123// assign our local reference to the attribute stream124attrib = Arrays.copyOf(attributes, attributes.length);125// init the index point before the head of the stream126idx = -1;127// set the map128this.map = map;129}130131132/**133* Retrieves the next attribute in this <code>SQLInputImpl</code> object134* as an <code>Object</code> in the Java programming language.135*136* @return the next value in the input stream137* as an <code>Object</code> in the Java programming language138* @throws SQLException if the read position is located at an invalid139* position or if there are no further values in the stream140*/141private Object getNextAttribute() throws SQLException {142if (++idx >= attrib.length) {143throw new SQLException("SQLInputImpl exception: Invalid read " +144"position");145} else {146lastValueWasNull = attrib[idx] == null;147return attrib[idx];148}149}150151152//================================================================153// Methods for reading attributes from the stream of SQL data.154// These methods correspond to the column-accessor methods of155// java.sql.ResultSet.156//================================================================157158/**159* Retrieves the next attribute in this <code>SQLInputImpl</code> object as160* a <code>String</code> in the Java programming language.161* <p>162* This method does not perform type-safe checking to determine if the163* returned type is the expected type; this responsibility is delegated164* to the UDT mapping as defined by a <code>SQLData</code>165* implementation.166* <p>167* @return the next attribute in this <code>SQLInputImpl</code> object;168* if the value is <code>SQL NULL</code>, return <code>null</code>169* @throws SQLException if the read position is located at an invalid170* position or if there are no further values in the stream.171*/172public String readString() throws SQLException {173return (String)getNextAttribute();174}175176/**177* Retrieves the next attribute in this <code>SQLInputImpl</code> object as178* a <code>boolean</code> in the Java programming language.179* <p>180* This method does not perform type-safe checking to determine if the181* returned type is the expected type; this responsibility is delegated182* to the UDT mapping as defined by a <code>SQLData</code>183* implementation.184* <p>185* @return the next attribute in this <code>SQLInputImpl</code> object;186* if the value is <code>SQL NULL</code>, return <code>null</code>187* @throws SQLException if the read position is located at an invalid188* position or if there are no further values in the stream.189*/190public boolean readBoolean() throws SQLException {191Boolean attrib = (Boolean)getNextAttribute();192return (attrib == null) ? false : attrib.booleanValue();193}194195/**196* Retrieves the next attribute in this <code>SQLInputImpl</code> object as197* a <code>byte</code> in the Java programming language.198* <p>199* This method does not perform type-safe checking to determine if the200* returned type is the expected type; this responsibility is delegated201* to the UDT mapping as defined by a <code>SQLData</code>202* implementation.203* <p>204* @return the next attribute in this <code>SQLInputImpl</code> object;205* if the value is <code>SQL NULL</code>, return <code>null</code>206* @throws SQLException if the read position is located at an invalid207* position or if there are no further values in the stream208*/209public byte readByte() throws SQLException {210Byte attrib = (Byte)getNextAttribute();211return (attrib == null) ? 0 : attrib.byteValue();212}213214/**215* Retrieves the next attribute in this <code>SQLInputImpl</code> object216* as a <code>short</code> in the Java programming language.217* <P>218* This method does not perform type-safe checking to determine if the219* returned type is the expected type; this responsibility is delegated220* to the UDT mapping as defined by a <code>SQLData</code> implementation.221* <P>222* @return the next attribute in this <code>SQLInputImpl</code> object;223* if the value is <code>SQL NULL</code>, return <code>null</code>224* @throws SQLException if the read position is located at an invalid225* position or if there are no more values in the stream226*/227public short readShort() throws SQLException {228Short attrib = (Short)getNextAttribute();229return (attrib == null) ? 0 : attrib.shortValue();230}231232/**233* Retrieves the next attribute in this <code>SQLInputImpl</code> object234* as an <code>int</code> in the Java programming language.235* <P>236* This method does not perform type-safe checking to determine if the237* returned type is the expected type; this responsibility is delegated238* to the UDT mapping as defined by a <code>SQLData</code> implementation.239* <P>240* @return the next attribute in this <code>SQLInputImpl</code> object;241* if the value is <code>SQL NULL</code>, return <code>null</code>242* @throws SQLException if the read position is located at an invalid243* position or if there are no more values in the stream244*/245public int readInt() throws SQLException {246Integer attrib = (Integer)getNextAttribute();247return (attrib == null) ? 0 : attrib.intValue();248}249250/**251* Retrieves the next attribute in this <code>SQLInputImpl</code> object252* as a <code>long</code> in the Java programming language.253* <P>254* This method does not perform type-safe checking to determine if the255* returned type is the expected type; this responsibility is delegated256* to the UDT mapping as defined by a <code>SQLData</code> implementation.257* <P>258* @return the next attribute in this <code>SQLInputImpl</code> object;259* if the value is <code>SQL NULL</code>, return <code>null</code>260* @throws SQLException if the read position is located at an invalid261* position or if there are no more values in the stream262*/263public long readLong() throws SQLException {264Long attrib = (Long)getNextAttribute();265return (attrib == null) ? 0 : attrib.longValue();266}267268/**269* Retrieves the next attribute in this <code>SQLInputImpl</code> object270* as a <code>float</code> in the Java programming language.271* <P>272* This method does not perform type-safe checking to determine if the273* returned type is the expected type; this responsibility is delegated274* to the UDT mapping as defined by a <code>SQLData</code> implementation.275* <P>276* @return the next attribute in this <code>SQLInputImpl</code> object;277* if the value is <code>SQL NULL</code>, return <code>null</code>278* @throws SQLException if the read position is located at an invalid279* position or if there are no more values in the stream280*/281public float readFloat() throws SQLException {282Float attrib = (Float)getNextAttribute();283return (attrib == null) ? 0 : attrib.floatValue();284}285286/**287* Retrieves the next attribute in this <code>SQLInputImpl</code> object288* as a <code>double</code> in the Java programming language.289* <P>290* This method does not perform type-safe checking to determine if the291* returned type is the expected type; this responsibility is delegated292* to the UDT mapping as defined by a <code>SQLData</code> implementation.293* <P>294* @return the next attribute in this <code>SQLInputImpl</code> object;295* if the value is <code>SQL NULL</code>, return <code>null</code>296* @throws SQLException if the read position is located at an invalid297* position or if there are no more values in the stream298*/299public double readDouble() throws SQLException {300Double attrib = (Double)getNextAttribute();301return (attrib == null) ? 0 : attrib.doubleValue();302}303304/**305* Retrieves the next attribute in this <code>SQLInputImpl</code> object306* as a <code>java.math.BigDecimal</code>.307* <P>308* This method does not perform type-safe checking to determine if the309* returned type is the expected type; this responsibility is delegated310* to the UDT mapping as defined by a <code>SQLData</code> implementation.311* <P>312* @return the next attribute in this <code>SQLInputImpl</code> object;313* if the value is <code>SQL NULL</code>, return <code>null</code>314* @throws SQLException if the read position is located at an invalid315* position or if there are no more values in the stream316*/317public java.math.BigDecimal readBigDecimal() throws SQLException {318return (java.math.BigDecimal)getNextAttribute();319}320321/**322* Retrieves the next attribute in this <code>SQLInputImpl</code> object323* as an array of bytes.324* <p>325* This method does not perform type-safe checking to determine if the326* returned type is the expected type; this responsibility is delegated327* to the UDT mapping as defined by a <code>SQLData</code> implementation.328* <P>329* @return the next attribute in this <code>SQLInputImpl</code> object;330* if the value is <code>SQL NULL</code>, return <code>null</code>331* @throws SQLException if the read position is located at an invalid332* position or if there are no more values in the stream333*/334public byte[] readBytes() throws SQLException {335return (byte[])getNextAttribute();336}337338/**339* Retrieves the next attribute in this <code>SQLInputImpl</code> as340* a <code>java.sql.Date</code> object.341* <P>342* This method does not perform type-safe checking to determine if the343* returned type is the expected type; this responsibility is delegated344* to the UDT mapping as defined by a <code>SQLData</code> implementation.345* <P>346* @return the next attribute in this <code>SQLInputImpl</code> object;347* if the value is <code>SQL NULL</code>, return <code>null</code>348* @throws SQLException if the read position is located at an invalid349* position or if there are no more values in the stream350*/351public java.sql.Date readDate() throws SQLException {352return (java.sql.Date)getNextAttribute();353}354355/**356* Retrieves the next attribute in this <code>SQLInputImpl</code> object as357* a <code>java.sql.Time</code> object.358* <P>359* This method does not perform type-safe checking to determine if the360* returned type is the expected type as this responsibility is delegated361* to the UDT mapping as implemented by a <code>SQLData</code>362* implementation.363*364* @return the attribute; if the value is <code>SQL NULL</code>, return365* <code>null</code>366* @throws SQLException if the read position is located at an invalid367* position; or if there are no further values in the stream.368*/369public java.sql.Time readTime() throws SQLException {370return (java.sql.Time)getNextAttribute();371}372373/**374* Retrieves the next attribute in this <code>SQLInputImpl</code> object as375* a <code>java.sql.Timestamp</code> object.376*377* @return the attribute; if the value is <code>SQL NULL</code>, return378* <code>null</code>379* @throws SQLException if the read position is located at an invalid380* position; or if there are no further values in the stream.381*/382public java.sql.Timestamp readTimestamp() throws SQLException {383return (java.sql.Timestamp)getNextAttribute();384}385386/**387* Retrieves the next attribute in this <code>SQLInputImpl</code> object388* as a stream of Unicode characters.389* <P>390* This method does not perform type-safe checking to determine if the391* returned type is the expected type as this responsibility is delegated392* to the UDT mapping as implemented by a <code>SQLData</code>393* implementation.394*395* @return the attribute; if the value is <code>SQL NULL</code>, return <code>null</code>396* @throws SQLException if the read position is located at an invalid397* position; or if there are no further values in the stream.398*/399public java.io.Reader readCharacterStream() throws SQLException {400return (java.io.Reader)getNextAttribute();401}402403/**404* Returns the next attribute in this <code>SQLInputImpl</code> object405* as a stream of ASCII characters.406* <P>407* This method does not perform type-safe checking to determine if the408* returned type is the expected type as this responsibility is delegated409* to the UDT mapping as implemented by a <code>SQLData</code>410* implementation.411*412* @return the attribute; if the value is <code>SQL NULL</code>,413* return <code>null</code>414* @throws SQLException if the read position is located at an invalid415* position; or if there are no further values in the stream.416*/417public java.io.InputStream readAsciiStream() throws SQLException {418return (java.io.InputStream)getNextAttribute();419}420421/**422* Returns the next attribute in this <code>SQLInputImpl</code> object423* as a stream of uninterpreted bytes.424* <P>425* This method does not perform type-safe checking to determine if the426* returned type is the expected type as this responsibility is delegated427* to the UDT mapping as implemented by a <code>SQLData</code>428* implementation.429*430* @return the attribute; if the value is <code>SQL NULL</code>, return431* <code>null</code>432* @throws SQLException if the read position is located at an invalid433* position; or if there are no further values in the stream.434*/435public java.io.InputStream readBinaryStream() throws SQLException {436return (java.io.InputStream)getNextAttribute();437}438439//================================================================440// Methods for reading items of SQL user-defined types from the stream.441//================================================================442443/**444* Retrieves the value at the head of this <code>SQLInputImpl</code>445* object as an <code>Object</code> in the Java programming language. The446* actual type of the object returned is determined by the default447* mapping of SQL types to types in the Java programming language unless448* there is a custom mapping, in which case the type of the object449* returned is determined by this stream's type map.450* <P>451* The JDBC technology-enabled driver registers a type map with the stream452* before passing the stream to the application.453* <P>454* When the datum at the head of the stream is an SQL <code>NULL</code>,455* this method returns <code>null</code>. If the datum is an SQL456* structured or distinct type with a custom mapping, this method457* determines the SQL type of the datum at the head of the stream,458* constructs an object of the appropriate class, and calls the method459* <code>SQLData.readSQL</code> on that object. The <code>readSQL</code>460* method then calls the appropriate <code>SQLInputImpl.readXXX</code>461* methods to retrieve the attribute values from the stream.462*463* @return the value at the head of the stream as an <code>Object</code>464* in the Java programming language; <code>null</code> if465* the value is SQL <code>NULL</code>466* @throws SQLException if the read position is located at an invalid467* position; or if there are no further values in the stream.468*/469public Object readObject() throws SQLException {470Object attrib = getNextAttribute();471if (attrib instanceof Struct) {472Struct s = (Struct)attrib;473// look up the class in the map474Class<?> c = map.get(s.getSQLTypeName());475if (c != null) {476// create new instance of the class477SQLData obj = null;478try {479obj = (SQLData)ReflectUtil.newInstance(c);480} catch (Exception ex) {481throw new SQLException("Unable to Instantiate: ", ex);482}483// get the attributes from the struct484Object attribs[] = s.getAttributes(map);485// create the SQLInput "stream"486SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);487// read the values...488obj.readSQL(sqlInput, s.getSQLTypeName());489return obj;490}491}492return attrib;493}494495/**496* Retrieves the value at the head of this <code>SQLInputImpl</code> object497* as a <code>Ref</code> object in the Java programming language.498*499* @return a <code>Ref</code> object representing the SQL500* <code>REF</code> value at the head of the stream; if the value501* is <code>SQL NULL</code> return <code>null</code>502* @throws SQLException if the read position is located at an invalid503* position; or if there are no further values in the stream.504*/505public Ref readRef() throws SQLException {506return (Ref)getNextAttribute();507}508509/**510* Retrieves the <code>BLOB</code> value at the head of this511* <code>SQLInputImpl</code> object as a <code>Blob</code> object512* in the Java programming language.513* <P>514* This method does not perform type-safe checking to determine if the515* returned type is the expected type as this responsibility is delegated516* to the UDT mapping as implemented by a <code>SQLData</code>517* implementation.518*519* @return a <code>Blob</code> object representing the SQL520* <code>BLOB</code> value at the head of this stream;521* if the value is <code>SQL NULL</code>, return522* <code>null</code>523* @throws SQLException if the read position is located at an invalid524* position; or if there are no further values in the stream.525*/526public Blob readBlob() throws SQLException {527return (Blob)getNextAttribute();528}529530/**531* Retrieves the <code>CLOB</code> value at the head of this532* <code>SQLInputImpl</code> object as a <code>Clob</code> object533* in the Java programming language.534* <P>535* This method does not perform type-safe checking to determine if the536* returned type is the expected type as this responsibility is delegated537* to the UDT mapping as implemented by a <code>SQLData</code>538* implementation.539*540* @return a <code>Clob</code> object representing the SQL541* <code>CLOB</code> value at the head of the stream;542* if the value is <code>SQL NULL</code>, return543* <code>null</code>544* @throws SQLException if the read position is located at an invalid545* position; or if there are no further values in the stream.546*/547public Clob readClob() throws SQLException {548return (Clob)getNextAttribute();549}550551/**552* Reads an SQL <code>ARRAY</code> value from the stream and553* returns it as an <code>Array</code> object in the Java programming554* language.555* <P>556* This method does not perform type-safe checking to determine if the557* returned type is the expected type as this responsibility is delegated558* to the UDT mapping as implemented by a <code>SQLData</code>559* implementation.560*561* @return an <code>Array</code> object representing the SQL562* <code>ARRAY</code> value at the head of the stream; *563* if the value is <code>SQL NULL</code>, return564* <code>null</code>565* @throws SQLException if the read position is located at an invalid566* position; or if there are no further values in the stream.567568*/569public Array readArray() throws SQLException {570return (Array)getNextAttribute();571}572573/**574* Ascertains whether the last value read from this575* <code>SQLInputImpl</code> object was <code>null</code>.576*577* @return <code>true</code> if the SQL value read most recently was578* <code>null</code>; otherwise, <code>false</code>; by default it579* will return false580* @throws SQLException if an error occurs determining the last value581* read was a <code>null</code> value or not;582*/583public boolean wasNull() throws SQLException {584return lastValueWasNull;585}586587/**588* Reads an SQL <code>DATALINK</code> value from the stream and589* returns it as an <code>URL</code> object in the Java programming590* language.591* <P>592* This method does not perform type-safe checking to determine if the593* returned type is the expected type as this responsibility is delegated594* to the UDT mapping as implemented by a <code>SQLData</code>595* implementation.596*597* @return an <code>URL</code> object representing the SQL598* <code>DATALINK</code> value at the head of the stream; *599* if the value is <code>SQL NULL</code>, return600* <code>null</code>601* @throws SQLException if the read position is located at an invalid602* position; or if there are no further values in the stream.603*/604public java.net.URL readURL() throws SQLException {605return (java.net.URL)getNextAttribute();606}607608//---------------------------- JDBC 4.0 -------------------------609610/**611* Reads an SQL <code>NCLOB</code> value from the stream and returns it as a612* <code>Clob</code> object in the Java programming language.613*614* @return a <code>NClob</code> object representing data of the SQL <code>NCLOB</code> value615* at the head of the stream; <code>null</code> if the value read is616* SQL <code>NULL</code>617* @exception SQLException if a database access error occurs618* @since 1.6619*/620public NClob readNClob() throws SQLException {621return (NClob)getNextAttribute();622}623624/**625* Reads the next attribute in the stream and returns it as a <code>String</code>626* in the Java programming language. It is intended for use when627* accessing <code>NCHAR</code>,<code>NVARCHAR</code>628* and <code>LONGNVARCHAR</code> columns.629*630* @return the attribute; if the value is SQL <code>NULL</code>, returns <code>null</code>631* @exception SQLException if a database access error occurs632* @since 1.6633*/634public String readNString() throws SQLException {635return (String)getNextAttribute();636}637638/**639* Reads an SQL <code>XML</code> value from the stream and returns it as a640* <code>SQLXML</code> object in the Java programming language.641*642* @return a <code>SQLXML</code> object representing data of the SQL <code>XML</code> value643* at the head of the stream; <code>null</code> if the value read is644* SQL <code>NULL</code>645* @exception SQLException if a database access error occurs646* @since 1.6647*/648public SQLXML readSQLXML() throws SQLException {649return (SQLXML)getNextAttribute();650}651652/**653* Reads an SQL <code>ROWID</code> value from the stream and returns it as a654* <code>RowId</code> object in the Java programming language.655*656* @return a <code>RowId</code> object representing data of the SQL <code>ROWID</code> value657* at the head of the stream; <code>null</code> if the value read is658* SQL <code>NULL</code>659* @exception SQLException if a database access error occurs660* @since 1.6661*/662public RowId readRowId() throws SQLException {663return (RowId)getNextAttribute();664}665666667}668669670