1 /* 2 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.sql.rowset.serial; 27 28 import java.sql.*; 29 import javax.sql.*; 30 import java.io.*; 31 import java.math.*; 32 import java.util.Map; 33 34 /** 35 * An input stream used for custom mapping user-defined types (UDTs). 36 * An <code>SQLInputImpl</code> object is an input stream that contains a 37 * stream of values that are the attributes of a UDT. 38 * <p> 39 * This class is used by the driver behind the scenes when the method 40 * <code>getObject</code> is called on an SQL structured or distinct type 41 * that has a custom mapping; a programmer never invokes 42 * <code>SQLInputImpl</code> methods directly. They are provided here as a 43 * convenience for those who write <code>RowSet</code> implementations. 44 * <P> 45 * The <code>SQLInputImpl</code> class provides a set of 46 * reader methods analogous to the <code>ResultSet</code> getter 47 * methods. These methods make it possible to read the values in an 48 * <code>SQLInputImpl</code> object. 49 * <P> 50 * The method <code>wasNull</code> is used to determine whether the 51 * the last value read was SQL <code>NULL</code>. 52 * <P>When the method <code>getObject</code> is called with an 53 * object of a class implementing the interface <code>SQLData</code>, 54 * the JDBC driver calls the method <code>SQLData.getSQLType</code> 55 * to determine the SQL type of the UDT being custom mapped. The driver 56 * creates an instance of <code>SQLInputImpl</code>, populating it with the 57 * attributes of the UDT. The driver then passes the input 58 * stream to the method <code>SQLData.readSQL</code>, which in turn 59 * calls the <code>SQLInputImpl</code> reader methods 60 * to read the attributes from the input stream. 61 * @see java.sql.SQLData 62 */ 63 public class SQLInputImpl implements SQLInput { 64 65 /** 66 * <code>true</code> if the last value returned was <code>SQL NULL</code>; 67 * <code>false</code> otherwise. 68 */ 69 private boolean lastValueWasNull; 70 71 /** 72 * The current index into the array of SQL structured type attributes 73 * that will be read from this <code>SQLInputImpl</code> object and 74 * mapped to the fields of a class in the Java programming language. 75 */ 76 private int idx; 77 78 /** 79 * The array of attributes to be read from this stream. The order 80 * of the attributes is the same as the order in which they were 81 * listed in the SQL definition of the UDT. 82 */ 83 private Object attrib[]; 84 85 /** 86 * The type map to use when the method <code>readObject</code> 87 * is invoked. This is a <code>java.util.Map</code> object in which 88 * there may be zero or more entries. Each entry consists of the 89 * fully qualified name of a UDT (the value to be mapped) and the 90 * <code>Class</code> object for a class that implements 91 * <code>SQLData</code> (the Java class that defines how the UDT 92 * will be mapped). 93 */ 94 private Map map; 95 96 97 /** 98 * Creates an <code>SQLInputImpl</code> object initialized with the 99 * given array of attributes and the given type map. If any of the 100 * attributes is a UDT whose name is in an entry in the type map, 101 * the attribute will be mapped according to the corresponding 102 * <code>SQLData</code> implementation. 103 * 104 * @param attributes an array of <code>Object</code> instances in which 105 * each element is an attribute of a UDT. The order of the 106 * attributes in the array is the same order in which 107 * the attributes were defined in the UDT definition. 108 * @param map a <code>java.util.Map</code> object containing zero or more 109 * entries, with each entry consisting of 1) a <code>String</code> 110 * giving the fully 111 * qualified name of the UDT and 2) the <code>Class</code> object 112 * for the <code>SQLData</code> implementation that defines how 113 * the UDT is to be mapped 114 * @throws SQLException if the <code>attributes</code> or the <code>map</code> 115 * is a <code>null</code> value 116 */ 117 118 public SQLInputImpl(Object[] attributes, Map<String,Class<?>> map) 119 throws SQLException 120 { 121 if ((attributes == null) || (map == null)) { 122 throw new SQLException("Cannot instantiate a SQLInputImpl " + 123 "object with null parameters"); 124 } 125 // assign our local reference to the attribute stream 126 attrib = attributes; 127 // init the index point before the head of the stream 128 idx = -1; 129 // set the map 130 this.map = map; 131 } 132 133 134 /** 135 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 136 * as an <code>Object</code> in the Java programming language. 137 * 138 * @return the next value in the input stream 139 * as an <code>Object</code> in the Java programming language 140 * @throws SQLException if the read position is located at an invalid 141 * position or if there are no further values in the stream 142 */ 143 private Object getNextAttribute() throws SQLException { 144 if (++idx >= attrib.length) { 145 throw new SQLException("SQLInputImpl exception: Invalid read " + 146 "position"); 147 } else { 148 return attrib[idx]; 149 } 150 } 151 152 153 //================================================================ 154 // Methods for reading attributes from the stream of SQL data. 155 // These methods correspond to the column-accessor methods of 156 // java.sql.ResultSet. 157 //================================================================ 158 159 /** 160 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 161 * a <code>String</code> in the Java programming language. 162 * <p> 163 * This method does not perform type-safe checking to determine if the 164 * returned type is the expected type; this responsibility is delegated 165 * to the UDT mapping as defined by a <code>SQLData</code> 166 * implementation. 167 * <p> 168 * @return the next attribute in this <code>SQLInputImpl</code> object; 169 * if the value is <code>SQL NULL</code>, return <code>null</code> 170 * @throws SQLException if the read position is located at an invalid 171 * position or if there are no further values in the stream. 172 */ 173 public String readString() throws SQLException { 174 175 String attrib = (String)getNextAttribute(); 176 177 if (attrib == null) { 178 lastValueWasNull = true; 179 return null; 180 } else { 181 lastValueWasNull = false; 182 return attrib; 183 } 184 } 185 186 /** 187 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 188 * a <code>boolean</code> in the Java programming language. 189 * <p> 190 * This method does not perform type-safe checking to determine if the 191 * returned type is the expected type; this responsibility is delegated 192 * to the UDT mapping as defined by a <code>SQLData</code> 193 * implementation. 194 * <p> 195 * @return the next attribute in this <code>SQLInputImpl</code> object; 196 * if the value is <code>SQL NULL</code>, return <code>null</code> 197 * @throws SQLException if the read position is located at an invalid 198 * position or if there are no further values in the stream. 199 */ 200 public boolean readBoolean() throws SQLException { 201 202 Boolean attrib = (Boolean)getNextAttribute(); 203 204 if (attrib == null) { 205 lastValueWasNull = true; 206 return false; 207 } else { 208 lastValueWasNull = false; 209 return attrib.booleanValue(); 210 } 211 } 212 213 /** 214 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 215 * a <code>byte</code> in the Java programming language. 216 * <p> 217 * This method does not perform type-safe checking to determine if the 218 * returned type is the expected type; this responsibility is delegated 219 * to the UDT mapping as defined by a <code>SQLData</code> 220 * 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 invalid 225 * position or if there are no further values in the stream 226 */ 227 public byte readByte() throws SQLException { 228 Byte attrib = (Byte)getNextAttribute(); 229 230 if (attrib == null) { 231 lastValueWasNull = true; 232 return (byte)0; 233 } else { 234 lastValueWasNull = false; 235 return attrib.byteValue(); 236 } 237 } 238 239 /** 240 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 241 * as a <code>short</code> in the Java programming language. 242 * <P> 243 * This method does not perform type-safe checking to determine if the 244 * returned type is the expected type; this responsibility is delegated 245 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 246 * <P> 247 * @return the next attribute in this <code>SQLInputImpl</code> object; 248 * if the value is <code>SQL NULL</code>, return <code>null</code> 249 * @throws SQLException if the read position is located at an invalid 250 * position or if there are no more values in the stream 251 */ 252 public short readShort() throws SQLException { 253 Short attrib = (Short)getNextAttribute(); 254 255 if (attrib == null) { 256 lastValueWasNull = true; 257 return (short)0; 258 } else { 259 lastValueWasNull = false; 260 return attrib.shortValue(); 261 } 262 } 263 264 /** 265 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 266 * as an <code>int</code> in the Java programming language. 267 * <P> 268 * This method does not perform type-safe checking to determine if the 269 * returned type is the expected type; this responsibility is delegated 270 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 271 * <P> 272 * @return the next attribute in this <code>SQLInputImpl</code> object; 273 * if the value is <code>SQL NULL</code>, return <code>null</code> 274 * @throws SQLException if the read position is located at an invalid 275 * position or if there are no more values in the stream 276 */ 277 public int readInt() throws SQLException { 278 Integer attrib = (Integer)getNextAttribute(); 279 280 if (attrib == null) { 281 lastValueWasNull = true; 282 return (int)0; 283 } else { 284 lastValueWasNull = false; 285 return attrib.intValue(); 286 } 287 } 288 289 /** 290 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 291 * as a <code>long</code> in the Java programming language. 292 * <P> 293 * This method does not perform type-safe checking to determine if the 294 * returned type is the expected type; this responsibility is delegated 295 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 296 * <P> 297 * @return the next attribute in this <code>SQLInputImpl</code> object; 298 * if the value is <code>SQL NULL</code>, return <code>null</code> 299 * @throws SQLException if the read position is located at an invalid 300 * position or if there are no more values in the stream 301 */ 302 public long readLong() throws SQLException { 303 Long attrib = (Long)getNextAttribute(); 304 305 if (attrib == null) { 306 lastValueWasNull = true; 307 return (long)0; 308 } else { 309 lastValueWasNull = false; 310 return attrib.longValue(); 311 } 312 } 313 314 /** 315 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 316 * as a <code>float</code> in the Java programming language. 317 * <P> 318 * This method does not perform type-safe checking to determine if the 319 * returned type is the expected type; this responsibility is delegated 320 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 321 * <P> 322 * @return the next attribute in this <code>SQLInputImpl</code> object; 323 * if the value is <code>SQL NULL</code>, return <code>null</code> 324 * @throws SQLException if the read position is located at an invalid 325 * position or if there are no more values in the stream 326 */ 327 public float readFloat() throws SQLException { 328 Float attrib = (Float)getNextAttribute(); 329 330 if (attrib == null) { 331 lastValueWasNull = true; 332 return (float)0; 333 } else { 334 lastValueWasNull = false; 335 return attrib.floatValue(); 336 } 337 } 338 339 /** 340 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 341 * as a <code>double</code> in the Java programming language. 342 * <P> 343 * This method does not perform type-safe checking to determine if the 344 * returned type is the expected type; this responsibility is delegated 345 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 346 * <P> 347 * @return the next attribute in this <code>SQLInputImpl</code> object; 348 * if the value is <code>SQL NULL</code>, return <code>null</code> 349 * @throws SQLException if the read position is located at an invalid 350 * position or if there are no more values in the stream 351 */ 352 public double readDouble() throws SQLException { 353 Double attrib = (Double)getNextAttribute(); 354 355 if (attrib == null) { 356 lastValueWasNull = true; 357 return (double)0; 358 } else { 359 lastValueWasNull = false; 360 return attrib.doubleValue(); 361 } 362 } 363 364 /** 365 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 366 * as a <code>java.math.BigDecimal</code>. 367 * <P> 368 * This method does not perform type-safe checking to determine if the 369 * returned type is the expected type; this responsibility is delegated 370 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 371 * <P> 372 * @return the next attribute in this <code>SQLInputImpl</code> object; 373 * if the value is <code>SQL NULL</code>, return <code>null</code> 374 * @throws SQLException if the read position is located at an invalid 375 * position or if there are no more values in the stream 376 */ 377 public java.math.BigDecimal readBigDecimal() throws SQLException { 378 java.math.BigDecimal attrib = (java.math.BigDecimal)getNextAttribute(); 379 380 if (attrib == null) { 381 lastValueWasNull = true; 382 return null; 383 } else { 384 lastValueWasNull = false; 385 return attrib; 386 } 387 } 388 389 /** 390 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 391 * as an array of bytes. 392 * <p> 393 * This method does not perform type-safe checking to determine if the 394 * returned type is the expected type; this responsibility is delegated 395 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 396 * <P> 397 * @return the next attribute in this <code>SQLInputImpl</code> object; 398 * if the value is <code>SQL NULL</code>, return <code>null</code> 399 * @throws SQLException if the read position is located at an invalid 400 * position or if there are no more values in the stream 401 */ 402 public byte[] readBytes() throws SQLException { 403 byte[] attrib = (byte[])getNextAttribute(); 404 405 if (attrib == null) { 406 lastValueWasNull = true; 407 return null; 408 } else { 409 lastValueWasNull = false; 410 return attrib; 411 } 412 } 413 414 /** 415 * Retrieves the next attribute in this <code>SQLInputImpl</code> as 416 * a <code>java.sql.Date</code> object. 417 * <P> 418 * This method does not perform type-safe checking to determine if the 419 * returned type is the expected type; this responsibility is delegated 420 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 421 * <P> 422 * @return the next attribute in this <code>SQLInputImpl</code> object; 423 * if the value is <code>SQL NULL</code>, return <code>null</code> 424 * @throws SQLException if the read position is located at an invalid 425 * position or if there are no more values in the stream 426 */ 427 public java.sql.Date readDate() throws SQLException { 428 java.sql.Date attrib = (java.sql.Date)getNextAttribute(); 429 430 if (attrib == null) { 431 lastValueWasNull = true; 432 return null; 433 } else { 434 lastValueWasNull = false; 435 return attrib; 436 } 437 } 438 439 /** 440 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 441 * a <code>java.sql.Time</code> object. 442 * <P> 443 * This method does not perform type-safe checking to determine if the 444 * returned type is the expected type as this responsibility is delegated 445 * to the UDT mapping as implemented by a <code>SQLData</code> 446 * implementation. 447 * 448 * @return the attribute; if the value is <code>SQL NULL</code>, return 449 * <code>null</code> 450 * @throws SQLException if the read position is located at an invalid 451 * position; or if there are no further values in the stream. 452 */ 453 public java.sql.Time readTime() throws SQLException { 454 java.sql.Time attrib = (java.sql.Time)getNextAttribute(); 455 456 if (attrib == null) { 457 lastValueWasNull = true; 458 return null; 459 } else { 460 lastValueWasNull = false; 461 return attrib; 462 } 463 } 464 465 /** 466 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 467 * a <code>java.sql.Timestamp</code> object. 468 * 469 * @return the attribute; if the value is <code>SQL NULL</code>, return 470 * <code>null</code> 471 * @throws SQLException if the read position is located at an invalid 472 * position; or if there are no further values in the stream. 473 */ 474 public java.sql.Timestamp readTimestamp() throws SQLException { 475 java.sql.Timestamp attrib = (java.sql.Timestamp)getNextAttribute(); 476 477 if (attrib == null) { 478 lastValueWasNull = true; 479 return null; 480 } else { 481 lastValueWasNull = false; 482 return attrib; 483 } 484 } 485 486 /** 487 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 488 * as a stream of Unicode characters. 489 * <P> 490 * This method does not perform type-safe checking to determine if the 491 * returned type is the expected type as this responsibility is delegated 492 * to the UDT mapping as implemented by a <code>SQLData</code> 493 * implementation. 494 * 495 * @return the attribute; if the value is <code>SQL NULL</code>, return <code>null</code> 496 * @throws SQLException if the read position is located at an invalid 497 * position; or if there are no further values in the stream. 498 */ 499 public java.io.Reader readCharacterStream() throws SQLException { 500 java.io.Reader attrib = (java.io.Reader)getNextAttribute(); 501 502 if (attrib == null) { 503 lastValueWasNull = true; 504 return null; 505 } else { 506 lastValueWasNull = false; 507 return attrib; 508 } 509 } 510 511 /** 512 * Returns the next attribute in this <code>SQLInputImpl</code> object 513 * as a stream of ASCII characters. 514 * <P> 515 * This method does not perform type-safe checking to determine if the 516 * returned type is the expected type as this responsibility is delegated 517 * to the UDT mapping as implemented by a <code>SQLData</code> 518 * implementation. 519 * 520 * @return the attribute; if the value is <code>SQL NULL</code>, 521 * return <code>null</code> 522 * @throws SQLException if the read position is located at an invalid 523 * position; or if there are no further values in the stream. 524 */ 525 public java.io.InputStream readAsciiStream() throws SQLException { 526 java.io.InputStream attrib = (java.io.InputStream)getNextAttribute(); 527 528 if (attrib == null) { 529 lastValueWasNull = true; 530 return null; 531 } else { 532 lastValueWasNull = false; 533 return attrib; 534 } 535 } 536 537 /** 538 * Returns the next attribute in this <code>SQLInputImpl</code> object 539 * as a stream of uninterpreted bytes. 540 * <P> 541 * This method does not perform type-safe checking to determine if the 542 * returned type is the expected type as this responsibility is delegated 543 * to the UDT mapping as implemented by a <code>SQLData</code> 544 * implementation. 545 * 546 * @return the attribute; if the value is <code>SQL NULL</code>, return 547 * <code>null</code> 548 * @throws SQLException if the read position is located at an invalid 549 * position; or if there are no further values in the stream. 550 */ 551 public java.io.InputStream readBinaryStream() throws SQLException { 552 java.io.InputStream attrib = (java.io.InputStream)getNextAttribute(); 553 554 if (attrib == null) { 555 lastValueWasNull = true; 556 return null; 557 } else { 558 lastValueWasNull = false; 559 return attrib; 560 } 561 } 562 563 //================================================================ 564 // Methods for reading items of SQL user-defined types from the stream. 565 //================================================================ 566 567 /** 568 * Retrieves the value at the head of this <code>SQLInputImpl</code> 569 * object as an <code>Object</code> in the Java programming language. The 570 * actual type of the object returned is determined by the default 571 * mapping of SQL types to types in the Java programming language unless 572 * there is a custom mapping, in which case the type of the object 573 * returned is determined by this stream's type map. 574 * <P> 575 * The JDBC technology-enabled driver registers a type map with the stream 576 * before passing the stream to the application. 577 * <P> 578 * When the datum at the head of the stream is an SQL <code>NULL</code>, 579 * this method returns <code>null</code>. If the datum is an SQL 580 * structured or distinct type with a custom mapping, this method 581 * determines the SQL type of the datum at the head of the stream, 582 * constructs an object of the appropriate class, and calls the method 583 * <code>SQLData.readSQL</code> on that object. The <code>readSQL</code> 584 * method then calls the appropriate <code>SQLInputImpl.readXXX</code> 585 * methods to retrieve the attribute values from the stream. 586 * 587 * @return the value at the head of the stream as an <code>Object</code> 588 * in the Java programming language; <code>null</code> if 589 * the value is SQL <code>NULL</code> 590 * @throws SQLException if the read position is located at an invalid 591 * position; or if there are no further values in the stream. 592 */ 593 public Object readObject() throws SQLException { 594 Object attrib = (Object)getNextAttribute(); 595 596 if (attrib == null) { 597 lastValueWasNull = true; 598 return null; 599 } else { 600 lastValueWasNull = false; 601 if (attrib instanceof Struct) { 602 Struct s = (Struct)attrib; 603 // look up the class in the map 604 Class c = (Class)map.get(s.getSQLTypeName()); 605 if (c != null) { 606 // create new instance of the class 607 SQLData obj = null; 608 try { 609 obj = (SQLData)c.newInstance(); 610 } catch (java.lang.InstantiationException ex) { 611 throw new SQLException("Unable to instantiate: " + 612 ex.getMessage()); 613 } catch (java.lang.IllegalAccessException ex) { 614 throw new SQLException("Unable to instantiate: " + 615 ex.getMessage()); 616 } 617 // get the attributes from the struct 618 Object attribs[] = s.getAttributes(map); 619 // create the SQLInput "stream" 620 SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); 621 // read the values... 622 obj.readSQL(sqlInput, s.getSQLTypeName()); 623 return (Object)obj; 624 } 625 } 626 return (Object)attrib; 627 } 628 } 629 630 /** 631 * Retrieves the value at the head of this <code>SQLInputImpl</code> object 632 * as a <code>Ref</code> object in the Java programming language. 633 * 634 * @return a <code>Ref</code> object representing the SQL 635 * <code>REF</code> value at the head of the stream; if the value 636 * is <code>SQL NULL</code> return <code>null</code> 637 * @throws SQLException if the read position is located at an invalid 638 * position; or if there are no further values in the stream. 639 */ 640 public Ref readRef() throws SQLException { 641 Ref attrib = (Ref)getNextAttribute(); 642 643 if (attrib == null) { 644 lastValueWasNull = true; 645 return null; 646 } else { 647 lastValueWasNull = false; 648 return attrib; 649 } 650 } 651 652 /** 653 * Retrieves the <code>BLOB</code> value at the head of this 654 * <code>SQLInputImpl</code> object as a <code>Blob</code> object 655 * in the Java programming language. 656 * <P> 657 * This method does not perform type-safe checking to determine if the 658 * returned type is the expected type as this responsibility is delegated 659 * to the UDT mapping as implemented by a <code>SQLData</code> 660 * implementation. 661 * 662 * @return a <code>Blob</code> object representing the SQL 663 * <code>BLOB</code> value at the head of this stream; 664 * if the value is <code>SQL NULL</code>, return 665 * <code>null</code> 666 * @throws SQLException if the read position is located at an invalid 667 * position; or if there are no further values in the stream. 668 */ 669 public Blob readBlob() throws SQLException { 670 Blob attrib = (Blob)getNextAttribute(); 671 672 if (attrib == null) { 673 lastValueWasNull = true; 674 return null; 675 } else { 676 lastValueWasNull = false; 677 return attrib; 678 } 679 } 680 681 /** 682 * Retrieves the <code>CLOB</code> value at the head of this 683 * <code>SQLInputImpl</code> object as a <code>Clob</code> object 684 * in the Java programming language. 685 * <P> 686 * This method does not perform type-safe checking to determine if the 687 * returned type is the expected type as this responsibility is delegated 688 * to the UDT mapping as implemented by a <code>SQLData</code> 689 * implementation. 690 * 691 * @return a <code>Clob</code> object representing the SQL 692 * <code>CLOB</code> value at the head of the stream; 693 * if the value is <code>SQL NULL</code>, return 694 * <code>null</code> 695 * @throws SQLException if the read position is located at an invalid 696 * position; or if there are no further values in the stream. 697 */ 698 public Clob readClob() throws SQLException { 699 700 Clob attrib = (Clob)getNextAttribute(); 701 if (attrib == null) { 702 lastValueWasNull = true; 703 return null; 704 } else { 705 lastValueWasNull = false; 706 return attrib; 707 } 708 } 709 710 /** 711 * Reads an SQL <code>ARRAY</code> value from the stream and 712 * returns it as an <code>Array</code> object in the Java programming 713 * language. 714 * <P> 715 * This method does not perform type-safe checking to determine if the 716 * returned type is the expected type as this responsibility is delegated 717 * to the UDT mapping as implemented by a <code>SQLData</code> 718 * implementation. 719 * 720 * @return an <code>Array</code> object representing the SQL 721 * <code>ARRAY</code> value at the head of the stream; * 722 * if the value is <code>SQL NULL</code>, return 723 * <code>null</code> 724 * @throws SQLException if the read position is located at an invalid 725 * position; or if there are no further values in the stream. 726 727 */ 728 public Array readArray() throws SQLException { 729 Array attrib = (Array)getNextAttribute(); 730 731 if (attrib == null) { 732 lastValueWasNull = true; 733 return null; 734 } else { 735 lastValueWasNull = false; 736 return attrib; 737 } 738 } 739 740 /** 741 * Ascertains whether the last value read from this 742 * <code>SQLInputImpl</code> object was <code>null</code>. 743 * 744 * @return <code>true</code> if the SQL value read most recently was 745 * <code>null</code>; otherwise, <code>false</code>; by default it 746 * will return false 747 * @throws SQLException if an error occurs determining the last value 748 * read was a <code>null</code> value or not; 749 */ 750 public boolean wasNull() throws SQLException { 751 return lastValueWasNull; 752 } 753 754 /** 755 * Reads an SQL <code>DATALINK</code> value from the stream and 756 * returns it as an <code>URL</code> object in the Java programming 757 * language. 758 * <P> 759 * This method does not perform type-safe checking to determine if the 760 * returned type is the expected type as this responsibility is delegated 761 * to the UDT mapping as implemented by a <code>SQLData</code> 762 * implementation. 763 * 764 * @return an <code>URL</code> object representing the SQL 765 * <code>DATALINK</code> value at the head of the stream; * 766 * if the value is <code>SQL NULL</code>, return 767 * <code>null</code> 768 * @throws SQLException if the read position is located at an invalid 769 * position; or if there are no further values in the stream. 770 */ 771 public java.net.URL readURL() throws SQLException { 772 throw new SQLException("Operation not supported"); 773 } 774 775 //---------------------------- JDBC 4.0 ------------------------- 776 777 /** 778 * Reads an SQL <code>NCLOB</code> value from the stream and returns it as a 779 * <code>Clob</code> object in the Java programming language. 780 * 781 * @return a <code>NClob</code> object representing data of the SQL <code>NCLOB</code> value 782 * at the head of the stream; <code>null</code> if the value read is 783 * SQL <code>NULL</code> 784 * @exception SQLException if a database access error occurs 785 */ 786 public NClob readNClob() throws SQLException { 787 throw new UnsupportedOperationException("Operation not supported"); 788 } 789 790 /** 791 * Reads the next attribute in the stream and returns it as a <code>String</code> 792 * in the Java programming language. It is intended for use when 793 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 794 * and <code>LONGNVARCHAR</code> columns. 795 * 796 * @return the attribute; if the value is SQL <code>NULL</code>, returns <code>null</code> 797 * @exception SQLException if a database access error occurs 798 */ 799 public String readNString() throws SQLException { 800 throw new UnsupportedOperationException("Operation not supported"); 801 } 802 803 /** 804 * Reads an SQL <code>XML</code> value from the stream and returns it as a 805 * <code>SQLXML</code> object in the Java programming language. 806 * 807 * @return a <code>SQLXML</code> object representing data of the SQL <code>XML</code> value 808 * at the head of the stream; <code>null</code> if the value read is 809 * SQL <code>NULL</code> 810 * @exception SQLException if a database access error occurs 811 */ 812 public SQLXML readSQLXML() throws SQLException { 813 throw new UnsupportedOperationException("Operation not supported"); 814 } 815 816 /** 817 * Reads an SQL <code>ROWID</code> value from the stream and returns it as a 818 * <code>RowId</code> object in the Java programming language. 819 * 820 * @return a <code>RowId</code> object representing data of the SQL <code>ROWID</code> value 821 * at the head of the stream; <code>null</code> if the value read is 822 * SQL <code>NULL</code> 823 * @exception SQLException if a database access error occurs 824 */ 825 public RowId readRowId() throws SQLException { 826 throw new UnsupportedOperationException("Operation not supported"); 827 } 828 829 830 }