src/share/classes/com/sun/rowset/JdbcRowSetImpl.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 2011, 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 com.sun.rowset;
  27 
  28 import java.sql.*;
  29 import javax.sql.*;
  30 import javax.naming.*;
  31 import java.io.*;
  32 import java.math.*;
  33 import java.util.*;
  34 import java.beans.*;
  35 
  36 import javax.sql.rowset.*;
  37 
  38 /**
  39  * The standard implementation of the <code>JdbcRowSet</code> interface. See the interface
  40  * defintion for full behavior and implementation requirements.
  41  *
  42  * @author Jonathan Bruce, Amit Handa
  43  */
  44 
  45 public class JdbcRowSetImpl extends BaseRowSet implements JdbcRowSet, Joinable {
  46 
  47     /**
  48      * The <code>Connection</code> object that is this rowset's
  49      * current connection to the database.  This field is set
  50      * internally when the connection is established.
  51      */
  52     private Connection conn;
  53 
  54     /**


  66      * creates the rowset's <code>ResultSet</code> object.
  67      */
  68     private ResultSet rs;
  69 
  70     /**
  71      * The <code>RowSetMetaDataImpl</code> object that is contructed when
  72      * a <code>ResultSet</code> object is passed to the <code>JdbcRowSet</code>
  73      * constructor. This helps in constructing all metadata associated
  74      * with the <code>ResultSet</code> object using the setter methods of
  75      * <code>RowSetMetaDataImpl</code>.
  76      */
  77     private RowSetMetaDataImpl rowsMD;
  78 
  79     /**
  80      * The <code>ResultSetMetaData</code> object from which this
  81      * <code>RowSetMetaDataImpl</code> is formed and which  helps in getting
  82      * the metadata information.
  83      */
  84     private ResultSetMetaData resMD;
  85 
  86     /**
  87      * The property that helps to fire the property changed event when certain
  88      * properties are changed in the <code>JdbcRowSet</code> object. This property
  89      * is being added to satisfy Rave requirements.
  90      */
  91     private PropertyChangeSupport propertyChangeSupport;
  92 
  93     /**
  94      * The Vector holding the Match Columns
  95      */
  96     private Vector<Integer> iMatchColumns;
  97 
  98     /**
  99      * The Vector that will hold the Match Column names.
 100      */
 101     private Vector<String> strMatchColumns;
 102 
 103 
 104     protected transient JdbcRowSetResourceBundle resBundle;
 105 
 106     /**
 107      * Constructs a default <code>JdbcRowSet</code> object.
 108      * The new instance of <code>JdbcRowSet</code> will serve as a proxy
 109      * for the <code>ResultSet</code> object it creates, and by so doing,
 110      * it will make it possible to use the result set as a JavaBeans
 111      * component.


 128      * A newly created <code>JdbcRowSet</code> object must have its
 129      * <code>execute</code> method invoked before other public methods
 130      * are called on it; otherwise, such method calls will cause an
 131      * exception to be thrown.
 132      *
 133      * @throws SQLException [1] if any of its public methods are called prior
 134      * to calling the <code>execute</code> method; [2] if invalid JDBC driver
 135      * properties are set or [3] if no connection to a data source exists.
 136      */
 137     public JdbcRowSetImpl() {
 138         conn = null;
 139         ps   = null;
 140         rs   = null;
 141 
 142         try {
 143            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 144         } catch(IOException ioe) {
 145             throw new RuntimeException(ioe);
 146         }
 147 
 148         propertyChangeSupport = new PropertyChangeSupport(this);
 149 
 150         initParams();
 151 
 152         // set the defaults
 153 
 154         try {
 155             setShowDeleted(false);
 156         } catch(SQLException sqle) {
 157              System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setshowdeleted").toString() +
 158                                 sqle.getLocalizedMessage());
 159         }
 160 
 161         try {
 162             setQueryTimeout(0);
 163         } catch(SQLException sqle) {
 164             System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
 165                                 sqle.getLocalizedMessage());
 166         }
 167 
 168         try {


 251      * <code>execute</code> method invoked before other public methods
 252      * are called on it; otherwise, such method calls will cause an
 253      * exception to be thrown.
 254      *
 255      * @throws SQLException [1] if any of its public methods are called prior
 256      * to calling the <code>execute</code> method, [2] if invalid JDBC driver
 257      * properties are set, or [3] if no connection to a data source exists.
 258      */
 259     public JdbcRowSetImpl(Connection con) throws SQLException {
 260 
 261         conn = con;
 262         ps = null;
 263         rs = null;
 264 
 265         try {
 266            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 267         } catch(IOException ioe) {
 268             throw new RuntimeException(ioe);
 269         }
 270 
 271         propertyChangeSupport = new PropertyChangeSupport(this);
 272 
 273         initParams();
 274         // set the defaults
 275         setShowDeleted(false);
 276         setQueryTimeout(0);
 277         setMaxRows(0);
 278         setMaxFieldSize(0);
 279 
 280         setParams();
 281 
 282         setReadOnly(true);
 283         setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
 284         setEscapeProcessing(true);
 285         setTypeMap(null);
 286 
 287         //Instantiating the vector for MatchColumns
 288 
 289         iMatchColumns = new Vector<Integer>(10);
 290         for(int i = 0; i < 10 ; i++) {
 291            iMatchColumns.add(i,Integer.valueOf(-1));


 326      *        object will be connected. The form for a JDBC URL is
 327      *        <code>jdbc:subprotocol:subname</code>.
 328      * @param user - the database user on whose behalf the connection
 329      *        is being made
 330      * @param password - the user's password
 331      *
 332      * @throws SQLException if a database access error occurs
 333      *
 334      */
 335     public JdbcRowSetImpl(String url, String user, String password) throws SQLException {
 336         conn = null;
 337         ps = null;
 338         rs = null;
 339 
 340         try {
 341            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 342         } catch(IOException ioe) {
 343             throw new RuntimeException(ioe);
 344         }
 345 
 346         propertyChangeSupport = new PropertyChangeSupport(this);
 347 
 348         initParams();
 349 
 350         // Pass the arguments to BaseRowSet
 351         // setter methods now.
 352 
 353         setUsername(user);
 354         setPassword(password);
 355         setUrl(url);
 356 
 357         // set the defaults
 358         setShowDeleted(false);
 359         setQueryTimeout(0);
 360         setMaxRows(0);
 361         setMaxFieldSize(0);
 362 
 363         // to ensure connection to a db call connect now
 364         // and associate a conn with "this" object
 365         // in this case.
 366         conn = connect();
 367         setParams();
 368 
 369         setReadOnly(true);
 370         setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
 371         setEscapeProcessing(true);
 372         setTypeMap(null);
 373 
 374         //Instantiating the vector for MatchColumns
 375 
 376         iMatchColumns = new Vector<Integer>(10);
 377         for(int i = 0; i < 10 ; i++) {
 378            iMatchColumns.add(i,Integer.valueOf(-1));
 379         }
 380 
 381         strMatchColumns = new Vector<String>(10);
 382         for(int j = 0; j < 10; j++) {
 383            strMatchColumns.add(j,null);
 384         }
 385     }
 386 


 418     public JdbcRowSetImpl(ResultSet res) throws SQLException {
 419 
 420         // A ResultSet handle encapsulates a connection handle.
 421         // But there is no way we can retrieve a Connection handle
 422         // from a ResultSet object.
 423         // So to avoid any anomalies we keep the conn = null
 424         // The passed rs handle will be a wrapper around for
 425         // "this" object's all operations.
 426         conn = null;
 427 
 428         ps = null;
 429 
 430         rs = res;
 431 
 432         try {
 433            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 434         } catch(IOException ioe) {
 435             throw new RuntimeException(ioe);
 436         }
 437 
 438         propertyChangeSupport = new PropertyChangeSupport(this);
 439 
 440         initParams();
 441 
 442         // get the values from the resultset handle.
 443         setShowDeleted(false);
 444         setQueryTimeout(0);
 445         setMaxRows(0);
 446         setMaxFieldSize(0);
 447 
 448         setParams();
 449 
 450         setReadOnly(true);
 451         setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
 452         setEscapeProcessing(true);
 453         setTypeMap(null);
 454 
 455         // Get a handle to ResultSetMetaData
 456         // Construct RowSetMetaData out of it.
 457 
 458         resMD = rs.getMetaData();


 603             System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxfieldsize").toString() +
 604                                 ex.getLocalizedMessage());
 605         }
 606 
 607         try {
 608             ps.setMaxRows(getMaxRows());
 609         } catch (SQLException ex) {
 610            System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxrows").toString() +
 611                                 ex.getLocalizedMessage());
 612         }
 613 
 614         try {
 615             ps.setQueryTimeout(getQueryTimeout());
 616         } catch (SQLException ex) {
 617            System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
 618                                 ex.getLocalizedMessage());
 619         }
 620 
 621     }
 622 
 623     // An alternate solution is required instead of having the
 624     // connect method as protected.
 625     // This is a work around to assist Rave Team
 626     // :ah
 627 
 628     protected Connection connect() throws SQLException {
 629 
 630         // Get a JDBC connection.
 631 
 632         // First check for Connection handle object as such if
 633         // "this" initialized  using conn.
 634 
 635         if(conn != null) {
 636             return conn;
 637 
 638         } else if (getDataSourceName() != null) {
 639 
 640             // Connect using JNDI.
 641             try {
 642                 Context ctx = new InitialContext();
 643                 DataSource ds = (DataSource)ctx.lookup
 644                     (getDataSourceName());
 645                 //return ds.getConnection(getUsername(),getPassword());
 646 
 647                 if(getUsername() != null && !getUsername().equals("")) {
 648                      return ds.getConnection(getUsername(),getPassword());


4039      * Commits all updates in this <code>JdbcRowSet</code> object by
4040      * wrapping the internal <code>Connection</code> object and calling
4041      * its <code>commit</code> method.
4042      * This method sets this <code>JdbcRowSet</code> object's private field
4043      * <code>rs</code> to <code>null</code> after saving its value to another
4044      * object, but only if the <code>ResultSet</code>
4045      * constant <code>HOLD_CURSORS_OVER_COMMIT</code> has not been set.
4046      * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4047      * <code>ResultSet</code> object.)
4048      *
4049      * @throws SQLException if autoCommit is set to true or if a database
4050      * access error occurs
4051      */
4052     public void commit() throws SQLException {
4053       conn.commit();
4054 
4055       // Checking the holadbility value and making the result set handle null
4056       // Added as per Rave requirements
4057 
4058       if( conn.getHoldability() != HOLD_CURSORS_OVER_COMMIT) {
4059          ResultSet oldVal = rs;
4060          rs = null;
4061          // propertyChangeSupport.firePropertyChange("ResultSet",oldVal,rs);
4062       }
4063     }
4064 
4065     /**
4066      * Sets auto-commit on the internal <code>Connection</code> object with this
4067      * <code>JdbcRowSet</code>
4068      *
4069      * @throws SQLException if a database access error occurs
4070      */
4071     public void setAutoCommit(boolean autoCommit) throws SQLException {
4072         // The connection object should be there
4073         // in order to commit the connection handle on or off.
4074 
4075         if(conn != null) {
4076            conn.setAutoCommit(autoCommit);
4077         } else {
4078            // Coming here means the connection object is null.
4079            // So generate a connection handle internally, since
4080            // a JdbcRowSet is always connected to a db, it is fine
4081            // to get a handle to the connection.


4102     }
4103 
4104     /**
4105      * Rolls back all the updates in this <code>JdbcRowSet</code> object by
4106      * wrapping the internal <code>Connection</code> object and calling its
4107      * <code>rollback</code> method.
4108      * This method sets this <code>JdbcRowSet</code> object's private field
4109      * <code>rs</code> to <code>null</code> after saving its value to another object.
4110      * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4111      * internal <code>ResultSet</code> object.)
4112      *
4113      * @throws SQLException if autoCommit is set to true or a database
4114      * access error occurs
4115      */
4116     public void rollback() throws SQLException {
4117         conn.rollback();
4118 
4119         // Makes the result ste handle null after rollback
4120         // Added as per Rave requirements
4121 
4122         ResultSet oldVal = rs;
4123         rs = null;
4124         // propertyChangeSupport.firePropertyChange("ResultSet", oldVal,rs);
4125     }
4126 
4127 
4128     /**
4129      * Rollbacks all the updates in the <code>JdbcRowSet</code> back to the
4130      * last <code>Savepoint</code> transaction marker. Wraps the internal
4131      * <code>Connection</code> object and call it's rollback method
4132      *
4133      * @param s the <code>Savepoint</code> transaction marker to roll the
4134      * transaction to.
4135      * @throws SQLException if autoCommit is set to true; or ia a database
4136      * access error occurs
4137      */
4138     public void rollback(Savepoint s) throws SQLException {
4139         conn.rollback(s);
4140     }
4141 
4142     // Setting the ResultSet Type and Concurrency
4143     protected void setParams() throws SQLException {
4144         if(rs == null) {


4230 
4231        checkState();
4232 
4233        return rs;
4234     }
4235 
4236     // Sets the result set handle to the parameter
4237     // Added as per Rave requirements
4238 
4239     /**
4240      * Sets this <code>JdbcRowSet</code> object's resultset property
4241      * to the given <code>ResultSet</code> object.
4242      *
4243      * @param resultSet the <code>ResultSet</code> object
4244      *
4245      */
4246     protected void setResultSet(ResultSet resultSet) {
4247        rs = resultSet;
4248     }
4249 
4250 
4251     // Over riding the setCommand from BaseRowSet for
4252     // firing the propertyChangeSupport Event for
4253     // Rave requirements when this property's value
4254     // changes.
4255 
4256     /**
4257      * Sets this <code>JdbcRowSet</code> object's <code>command</code> property to
4258      * the given <code>String</code> object and clears the parameters, if any,
4259      * that were set for the previous command. In addition,
4260      * if the <code>command</code> property has previously been set to a
4261      * non-null value and it is
4262      * different from the <code>String</code> object supplied,
4263      * this method sets this <code>JdbcRowSet</code> object's private fields
4264      * <code>ps</code> and <code>rs</code> to <code>null</code>.
4265      * (The field <code>ps</code> is its <code>PreparedStatement</code> object, and
4266      * the field <code>rs</code> is its <code>ResultSet</code> object.)
4267      * <P>
4268      * The <code>command</code> property may not be needed if the <code>RowSet</code>
4269      * object gets its data from a source that does not support commands,
4270      * such as a spreadsheet or other tabular file.
4271      * Thus, this property is optional and may be <code>null</code>.
4272      *
4273      * @param command a <code>String</code> object containing an SQL query
4274      *            that will be set as this <code>RowSet</code> object's command
4275      *            property; may be <code>null</code> but may not be an empty string
4276      * @throws SQLException if an empty string is provided as the command value
4277      * @see #getCommand
4278      */
4279     public void setCommand(String command) throws SQLException {
4280        String oldVal;
4281 
4282        if (getCommand() != null) {
4283           if(!getCommand().equals(command)) {
4284              oldVal = getCommand();
4285              super.setCommand(command);
4286              ps = null;
4287              rs = null;
4288              propertyChangeSupport.firePropertyChange("command", oldVal,command);
4289           }
4290        }
4291        else {
4292           super.setCommand(command);
4293           propertyChangeSupport.firePropertyChange("command", null,command);
4294        }
4295     }
4296 
4297     // Over riding the setDataSourceName from BaseRowSet for
4298     // firing the propertyChangeSupport Event for
4299     // Rave requirements when this property's values
4300     // changes.
4301 
4302     /**
4303      * Sets the <code>dataSourceName</code> property for this <code>JdbcRowSet</code>
4304      * object to the given logical name and sets this <code>JdbcRowSet</code> object's
4305      * Url property to <code>null</code>. In addition, if the <code>dataSourceName</code>
4306      * property has previously been set and is different from the one supplied,
4307      * this method sets this <code>JdbcRowSet</code> object's private fields
4308      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4309      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4310      * the field <code>rs</code> is its <code>ResultSet</code> object, and
4311      * the field <code>conn</code> is its <code>Connection</code> object.)
4312      * <P>
4313      * The name supplied to this method must have been bound to a
4314      * <code>DataSource</code> object in a JNDI naming service so that an
4315      * application can do a lookup using that name to retrieve the
4316      * <code>DataSource</code> object bound to it. The <code>DataSource</code>
4317      * object can then be used to establish a connection to the data source it
4318      * represents.
4319      * <P>
4320      * Users should set either the Url property or the dataSourceName property.
4321      * If both properties are set, the driver will use the property set most recently.
4322      *
4323      * @param dsName a <code>String</code> object with the name that can be supplied
4324      *        to a naming service based on JNDI technology to retrieve the
4325      *        <code>DataSource</code> object that can be used to get a connection;
4326      *        may be <code>null</code>
4327      * @throws SQLException if there is a problem setting the
4328      *          <code>dataSourceName</code> property
4329      * @see #getDataSourceName
4330      */
4331     public void setDataSourceName(String dsName) throws SQLException{
4332        String oldVal;
4333 
4334        if(getDataSourceName() != null) {
4335           if(!getDataSourceName().equals(dsName)) {
4336              oldVal = getDataSourceName();
4337              super.setDataSourceName(dsName);
4338              conn = null;
4339              ps = null;
4340              rs = null;
4341              propertyChangeSupport.firePropertyChange("dataSourceName",oldVal,dsName);
4342           }
4343        }
4344        else {
4345           super.setDataSourceName(dsName);
4346           propertyChangeSupport.firePropertyChange("dataSourceName",null,dsName);
4347        }
4348     }
4349 
4350     // Over riding the setUrl from BaseRowSet for
4351     // firing the propertyChangeSupport Event for
4352     // Rave requirements when this property's values
4353     // changes.
4354 
4355     /**
4356      * Sets the Url property for this <code>JdbcRowSet</code> object
4357      * to the given <code>String</code> object and sets the dataSource name
4358      * property to <code>null</code>. In addition, if the Url property has
4359      * previously been set to a non <code>null</code> value and its value
4360      * is different from the value to be set,
4361      * this method sets this <code>JdbcRowSet</code> object's private fields
4362      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4363      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4364      * the field <code>rs</code> is its <code>ResultSet</code> object, and
4365      * the field <code>conn</code> is its <code>Connection</code> object.)
4366      * <P>
4367      * The Url property is a JDBC URL that is used when
4368      * the connection is created using a JDBC technology-enabled driver
4369      * ("JDBC driver") and the <code>DriverManager</code>.
4370      * The correct JDBC URL for the specific driver to be used can be found
4371      * in the driver documentation.  Although there are guidelines for for how
4372      * a JDBC URL is formed,
4373      * a driver vendor can specify any <code>String</code> object except


4377      * a <code>DataSource</code> object instead of the <code>DriverManager</code>.
4378      * The driver will use either the URL property or the
4379      * dataSourceName property to create a connection, whichever was
4380      * specified most recently. If an application uses a JDBC URL, it
4381      * must load a JDBC driver that accepts the JDBC URL before it uses the
4382      * <code>RowSet</code> object to connect to a database.  The <code>RowSet</code>
4383      * object will use the URL internally to create a database connection in order
4384      * to read or write data.
4385      *
4386      * @param url a <code>String</code> object that contains the JDBC URL
4387      *            that will be used to establish the connection to a database for this
4388      *            <code>RowSet</code> object; may be <code>null</code> but must not
4389      *            be an empty string
4390      * @throws SQLException if an error occurs setting the Url property or the
4391      *         parameter supplied is a string with a length of <code>0</code> (an
4392      *         empty string)
4393      * @see #getUrl
4394      */
4395 
4396     public void setUrl(String url) throws SQLException {
4397        String oldVal;
4398 
4399        if(getUrl() != null) {
4400           if(!getUrl().equals(url)) {
4401              oldVal = getUrl();
4402              super.setUrl(url);
4403              conn = null;
4404              ps = null;
4405              rs = null;
4406              propertyChangeSupport.firePropertyChange("url", oldVal, url);
4407           }
4408        }
4409        else {
4410           super.setUrl(url);
4411           propertyChangeSupport.firePropertyChange("url", null, url);
4412        }
4413     }
4414 
4415     // Over riding the setUsername from BaseRowSet for
4416     // firing the propertyChangeSupport Event for
4417     // Rave requirements when this property's values
4418     // changes.
4419 
4420      /**
4421      * Sets the username property for this <code>JdbcRowSet</code> object
4422      * to the given user name. Because it
4423      * is not serialized, the username property is set at run time before
4424      * calling the method <code>execute</code>. In addition,
4425      * if the <code>username</code> property is already set with a
4426      * non-null value and that value is different from the <code>String</code>
4427      * object to be set,
4428      * this method sets this <code>JdbcRowSet</code> object's private fields
4429      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4430      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4431      * <code>rs</code> is its <code>ResultSet</code> object, and
4432      * <code>conn</code> is its <code>Connection</code> object.)
4433      * Setting these fields to <code>null</code> ensures that only current
4434      * values will be used.
4435      *
4436      * @param uname the <code>String</code> object containing the user name that
4437      *     is supplied to the data source to create a connection. It may be null.
4438      * @see #getUsername
4439      */
4440     public void setUsername(String uname) {
4441        String oldVal;
4442 
4443        if( getUsername() != null) {
4444           if(!getUsername().equals(uname)) {
4445              oldVal = getUsername();
4446              super.setUsername(uname);
4447              conn = null;
4448              ps = null;
4449              rs = null;
4450              propertyChangeSupport.firePropertyChange("username",oldVal,uname);
4451           }
4452        }
4453        else{
4454           super.setUsername(uname);
4455           propertyChangeSupport.firePropertyChange("username",null,uname);
4456        }
4457     }
4458 
4459     // Over riding the setPassword from BaseRowSet for
4460     // firing the propertyChangeSupport Event for
4461     // Rave requirements when this property's values
4462     // changes.
4463 
4464      /**
4465      * Sets the password property for this <code>JdbcRowSet</code> object
4466      * to the given <code>String</code> object. Because it
4467      * is not serialized, the password property is set at run time before
4468      * calling the method <code>execute</code>. Its default valus is
4469      * <code>null</code>. In addition,
4470      * if the <code>password</code> property is already set with a
4471      * non-null value and that value is different from the one being set,
4472      * this method sets this <code>JdbcRowSet</code> object's private fields
4473      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4474      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4475      * <code>rs</code> is its <code>ResultSet</code> object, and
4476      * <code>conn</code> is its <code>Connection</code> object.)
4477      * Setting these fields to <code>null</code> ensures that only current
4478      * values will be used.
4479      *
4480      * @param password the <code>String</code> object that represents the password
4481      *     that must be supplied to the database to create a connection
4482      */
4483     public void setPassword(String password) {
4484        String oldVal;
4485 
4486        if ( getPassword() != null) {
4487           if(!getPassword().equals(password)) {
4488              oldVal = getPassword();
4489              super.setPassword(password);
4490              conn = null;
4491              ps = null;
4492              rs = null;
4493              propertyChangeSupport.firePropertyChange("password",oldVal,password);
4494           }
4495        }
4496        else{
4497           super.setPassword(password);
4498           propertyChangeSupport.firePropertyChange("password",null,password);
4499        }
4500     }
4501 
4502     /**
4503      * Sets the type for this <code>RowSet</code> object to the specified type.
4504      * The default type is <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>.
4505      *
4506      * @param type one of the following constants:
4507      *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
4508      *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
4509      *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4510      * @throws SQLException if the parameter supplied is not one of the
4511      *         following constants:
4512      *          <code>ResultSet.TYPE_FORWARD_ONLY</code> or
4513      *          <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
4514      *          <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4515      * @see #getConcurrency
4516      * @see #getType
4517      */
4518 
4519     public void setType(int type) throws SQLException {
4520 
4521        int oldVal;
4522 
4523        try {
4524           oldVal = getType();
4525         }catch(SQLException ex) {
4526            oldVal = 0;
4527         }
4528 
4529        if(oldVal != type) {
4530            super.setType(type);
4531            propertyChangeSupport.firePropertyChange("type",oldVal,type);
4532        }
4533 
4534     }
4535 
4536     /**
4537      * Sets the concurrency for this <code>RowSet</code> object to
4538      * the specified concurrency. The default concurrency for any <code>RowSet</code>
4539      * object (connected or disconnected) is <code>ResultSet.CONCUR_UPDATABLE</code>,
4540      * but this method may be called at any time to change the concurrency.
4541      *
4542      * @param concur one of the following constants:
4543      *                    <code>ResultSet.CONCUR_READ_ONLY</code> or
4544      *                    <code>ResultSet.CONCUR_UPDATABLE</code>
4545      * @throws SQLException if the parameter supplied is not one of the
4546      *         following constants:
4547      *          <code>ResultSet.CONCUR_UPDATABLE</code> or
4548      *          <code>ResultSet.CONCUR_READ_ONLY</code>
4549      * @see #getConcurrency
4550      * @see #isReadOnly
4551      */
4552     public void setConcurrency(int concur) throws SQLException {
4553 
4554        int oldVal;
4555 
4556        try {
4557           oldVal = getConcurrency();
4558         }catch(NullPointerException ex) {
4559            oldVal = 0;
4560         }
4561 
4562        if(oldVal != concur) {
4563            super.setConcurrency(concur);
4564            propertyChangeSupport.firePropertyChange("concurrency",oldVal,concur);
4565        }
4566 
4567     }
4568 
4569     /**
4570      * Sets the transaction isolation property for this JDBC <code>RowSet</code> object to the given
4571      * constant. The DBMS will use this transaction isolation level for
4572      * transactions if it can.
4573      * <p>
4574      * For <code>RowSet</code> implementations such as
4575      * the <code>CachedRowSet</code> that operate in a disconnected environment,
4576      * the <code>SyncProvider</code> object being used
4577      * offers complementary locking and data integrity options. The
4578      * options described below are pertinent only to connected <code>RowSet</code>
4579      * objects (<code>JdbcRowSet</code> objects).
4580      *
4581      * @param transIso one of the following constants, listed in ascending order:
4582      *              <code>Connection.TRANSACTION_NONE</code>,
4583      *              <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
4584      *              <code>Connection.TRANSACTION_READ_COMMITTED</code>,
4585      *              <code>Connection.TRANSACTION_REPEATABLE_READ</code>, or
4586      *              <code>Connection.TRANSACTION_SERIALIZABLE</code>
4587      * @throws SQLException if the given parameter is not one of the Connection
4588      *          constants
4589      * @see javax.sql.rowset.spi.SyncFactory
4590      * @see javax.sql.rowset.spi.SyncProvider
4591      * @see #getTransactionIsolation
4592      */
4593     public void setTransactionIsolation(int transIso) throws SQLException {
4594 
4595        int oldVal;
4596 
4597        try {
4598           oldVal = getTransactionIsolation();
4599         }catch(NullPointerException ex) {
4600            oldVal = 0;
4601         }
4602 
4603        if(oldVal != transIso) {
4604            super.setTransactionIsolation(transIso);
4605            propertyChangeSupport.firePropertyChange("transactionIsolation",oldVal,transIso);
4606        }
4607 
4608     }
4609 
4610     /**
4611      * Sets the maximum number of rows that this <code>RowSet</code> object may contain to
4612      * the given number. If this limit is exceeded, the excess rows are
4613      * silently dropped.
4614      *
4615      * @param mRows an <code>int</code> indicating the current maximum number
4616      *     of rows; zero means that there is no limit
4617      * @throws SQLException if an error occurs internally setting the
4618      *     maximum limit on the number of rows that a JDBC <code>RowSet</code> object
4619      *     can contain; or if <i>max</i> is less than <code>0</code>; or
4620      *     if <i>max</i> is less than the <code>fetchSize</code> of the
4621      *     <code>RowSet</code>
4622      */
4623     public void setMaxRows(int mRows) throws SQLException {
4624 
4625        int oldVal;
4626 
4627        try {
4628           oldVal = getMaxRows();
4629         }catch(NullPointerException ex) {
4630            oldVal = 0;
4631         }
4632 
4633        if(oldVal != mRows) {
4634            super.setMaxRows(mRows);
4635            propertyChangeSupport.firePropertyChange("maxRows",oldVal,mRows);
4636        }
4637 
4638     }
4639 
4640     /**
4641      * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4642      * <code>SQLXML</code> object in the Java programming language.
4643      * @param columnIndex the first column is 1, the second is 2, ...
4644      * @return a SQLXML object that maps an SQL XML value
4645      * @throws SQLException if a database access error occurs
4646      * @since 6.0
4647      */
4648     public SQLXML getSQLXML(int columnIndex) throws SQLException {
4649         throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString());
4650     }
4651 
4652     /**
4653      * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4654      * <code>SQLXML</code> object in the Java programming language.
4655      * @param colName the name of the column from which to retrieve the value


   1 /*
   2  * Copyright (c) 2003, 2012, 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 com.sun.rowset;
  27 
  28 import java.sql.*;
  29 import javax.sql.*;
  30 import javax.naming.*;
  31 import java.io.*;
  32 import java.math.*;
  33 import java.util.*;

  34 
  35 import javax.sql.rowset.*;
  36 
  37 /**
  38  * The standard implementation of the <code>JdbcRowSet</code> interface. See the interface
  39  * defintion for full behavior and implementation requirements.
  40  *
  41  * @author Jonathan Bruce, Amit Handa
  42  */
  43 
  44 public class JdbcRowSetImpl extends BaseRowSet implements JdbcRowSet, Joinable {
  45 
  46     /**
  47      * The <code>Connection</code> object that is this rowset's
  48      * current connection to the database.  This field is set
  49      * internally when the connection is established.
  50      */
  51     private Connection conn;
  52 
  53     /**


  65      * creates the rowset's <code>ResultSet</code> object.
  66      */
  67     private ResultSet rs;
  68 
  69     /**
  70      * The <code>RowSetMetaDataImpl</code> object that is contructed when
  71      * a <code>ResultSet</code> object is passed to the <code>JdbcRowSet</code>
  72      * constructor. This helps in constructing all metadata associated
  73      * with the <code>ResultSet</code> object using the setter methods of
  74      * <code>RowSetMetaDataImpl</code>.
  75      */
  76     private RowSetMetaDataImpl rowsMD;
  77 
  78     /**
  79      * The <code>ResultSetMetaData</code> object from which this
  80      * <code>RowSetMetaDataImpl</code> is formed and which  helps in getting
  81      * the metadata information.
  82      */
  83     private ResultSetMetaData resMD;
  84 






  85 
  86     /**
  87      * The Vector holding the Match Columns
  88      */
  89     private Vector<Integer> iMatchColumns;
  90 
  91     /**
  92      * The Vector that will hold the Match Column names.
  93      */
  94     private Vector<String> strMatchColumns;
  95 
  96 
  97     protected transient JdbcRowSetResourceBundle resBundle;
  98 
  99     /**
 100      * Constructs a default <code>JdbcRowSet</code> object.
 101      * The new instance of <code>JdbcRowSet</code> will serve as a proxy
 102      * for the <code>ResultSet</code> object it creates, and by so doing,
 103      * it will make it possible to use the result set as a JavaBeans
 104      * component.


 121      * A newly created <code>JdbcRowSet</code> object must have its
 122      * <code>execute</code> method invoked before other public methods
 123      * are called on it; otherwise, such method calls will cause an
 124      * exception to be thrown.
 125      *
 126      * @throws SQLException [1] if any of its public methods are called prior
 127      * to calling the <code>execute</code> method; [2] if invalid JDBC driver
 128      * properties are set or [3] if no connection to a data source exists.
 129      */
 130     public JdbcRowSetImpl() {
 131         conn = null;
 132         ps   = null;
 133         rs   = null;
 134 
 135         try {
 136            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 137         } catch(IOException ioe) {
 138             throw new RuntimeException(ioe);
 139         }
 140 

 141 
 142         initParams();
 143 
 144         // set the defaults
 145 
 146         try {
 147             setShowDeleted(false);
 148         } catch(SQLException sqle) {
 149              System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setshowdeleted").toString() +
 150                                 sqle.getLocalizedMessage());
 151         }
 152 
 153         try {
 154             setQueryTimeout(0);
 155         } catch(SQLException sqle) {
 156             System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
 157                                 sqle.getLocalizedMessage());
 158         }
 159 
 160         try {


 243      * <code>execute</code> method invoked before other public methods
 244      * are called on it; otherwise, such method calls will cause an
 245      * exception to be thrown.
 246      *
 247      * @throws SQLException [1] if any of its public methods are called prior
 248      * to calling the <code>execute</code> method, [2] if invalid JDBC driver
 249      * properties are set, or [3] if no connection to a data source exists.
 250      */
 251     public JdbcRowSetImpl(Connection con) throws SQLException {
 252 
 253         conn = con;
 254         ps = null;
 255         rs = null;
 256 
 257         try {
 258            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 259         } catch(IOException ioe) {
 260             throw new RuntimeException(ioe);
 261         }
 262 

 263 
 264         initParams();
 265         // set the defaults
 266         setShowDeleted(false);
 267         setQueryTimeout(0);
 268         setMaxRows(0);
 269         setMaxFieldSize(0);
 270 
 271         setParams();
 272 
 273         setReadOnly(true);
 274         setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
 275         setEscapeProcessing(true);
 276         setTypeMap(null);
 277 
 278         //Instantiating the vector for MatchColumns
 279 
 280         iMatchColumns = new Vector<Integer>(10);
 281         for(int i = 0; i < 10 ; i++) {
 282            iMatchColumns.add(i,Integer.valueOf(-1));


 317      *        object will be connected. The form for a JDBC URL is
 318      *        <code>jdbc:subprotocol:subname</code>.
 319      * @param user - the database user on whose behalf the connection
 320      *        is being made
 321      * @param password - the user's password
 322      *
 323      * @throws SQLException if a database access error occurs
 324      *
 325      */
 326     public JdbcRowSetImpl(String url, String user, String password) throws SQLException {
 327         conn = null;
 328         ps = null;
 329         rs = null;
 330 
 331         try {
 332            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 333         } catch(IOException ioe) {
 334             throw new RuntimeException(ioe);
 335         }
 336 

 337 
 338         initParams();
 339 
 340         // Pass the arguments to BaseRowSet
 341         // setter methods now.
 342 
 343         setUsername(user);
 344         setPassword(password);
 345         setUrl(url);
 346 
 347         // set the defaults
 348         setShowDeleted(false);
 349         setQueryTimeout(0);
 350         setMaxRows(0);
 351         setMaxFieldSize(0);
 352 




 353         setParams();
 354 
 355         setReadOnly(true);
 356         setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
 357         setEscapeProcessing(true);
 358         setTypeMap(null);
 359 
 360         //Instantiating the vector for MatchColumns
 361 
 362         iMatchColumns = new Vector<Integer>(10);
 363         for(int i = 0; i < 10 ; i++) {
 364            iMatchColumns.add(i,Integer.valueOf(-1));
 365         }
 366 
 367         strMatchColumns = new Vector<String>(10);
 368         for(int j = 0; j < 10; j++) {
 369            strMatchColumns.add(j,null);
 370         }
 371     }
 372 


 404     public JdbcRowSetImpl(ResultSet res) throws SQLException {
 405 
 406         // A ResultSet handle encapsulates a connection handle.
 407         // But there is no way we can retrieve a Connection handle
 408         // from a ResultSet object.
 409         // So to avoid any anomalies we keep the conn = null
 410         // The passed rs handle will be a wrapper around for
 411         // "this" object's all operations.
 412         conn = null;
 413 
 414         ps = null;
 415 
 416         rs = res;
 417 
 418         try {
 419            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
 420         } catch(IOException ioe) {
 421             throw new RuntimeException(ioe);
 422         }
 423 

 424 
 425         initParams();
 426 
 427         // get the values from the resultset handle.
 428         setShowDeleted(false);
 429         setQueryTimeout(0);
 430         setMaxRows(0);
 431         setMaxFieldSize(0);
 432 
 433         setParams();
 434 
 435         setReadOnly(true);
 436         setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
 437         setEscapeProcessing(true);
 438         setTypeMap(null);
 439 
 440         // Get a handle to ResultSetMetaData
 441         // Construct RowSetMetaData out of it.
 442 
 443         resMD = rs.getMetaData();


 588             System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxfieldsize").toString() +
 589                                 ex.getLocalizedMessage());
 590         }
 591 
 592         try {
 593             ps.setMaxRows(getMaxRows());
 594         } catch (SQLException ex) {
 595            System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxrows").toString() +
 596                                 ex.getLocalizedMessage());
 597         }
 598 
 599         try {
 600             ps.setQueryTimeout(getQueryTimeout());
 601         } catch (SQLException ex) {
 602            System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
 603                                 ex.getLocalizedMessage());
 604         }
 605 
 606     }
 607 
 608     private Connection connect() throws SQLException {





 609 
 610         // Get a JDBC connection.
 611 
 612         // First check for Connection handle object as such if
 613         // "this" initialized  using conn.
 614 
 615         if(conn != null) {
 616             return conn;
 617 
 618         } else if (getDataSourceName() != null) {
 619 
 620             // Connect using JNDI.
 621             try {
 622                 Context ctx = new InitialContext();
 623                 DataSource ds = (DataSource)ctx.lookup
 624                     (getDataSourceName());
 625                 //return ds.getConnection(getUsername(),getPassword());
 626 
 627                 if(getUsername() != null && !getUsername().equals("")) {
 628                      return ds.getConnection(getUsername(),getPassword());


4019      * Commits all updates in this <code>JdbcRowSet</code> object by
4020      * wrapping the internal <code>Connection</code> object and calling
4021      * its <code>commit</code> method.
4022      * This method sets this <code>JdbcRowSet</code> object's private field
4023      * <code>rs</code> to <code>null</code> after saving its value to another
4024      * object, but only if the <code>ResultSet</code>
4025      * constant <code>HOLD_CURSORS_OVER_COMMIT</code> has not been set.
4026      * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4027      * <code>ResultSet</code> object.)
4028      *
4029      * @throws SQLException if autoCommit is set to true or if a database
4030      * access error occurs
4031      */
4032     public void commit() throws SQLException {
4033       conn.commit();
4034 
4035       // Checking the holadbility value and making the result set handle null
4036       // Added as per Rave requirements
4037 
4038       if( conn.getHoldability() != HOLD_CURSORS_OVER_COMMIT) {

4039          rs = null;

4040       }
4041     }
4042 
4043     /**
4044      * Sets auto-commit on the internal <code>Connection</code> object with this
4045      * <code>JdbcRowSet</code>
4046      *
4047      * @throws SQLException if a database access error occurs
4048      */
4049     public void setAutoCommit(boolean autoCommit) throws SQLException {
4050         // The connection object should be there
4051         // in order to commit the connection handle on or off.
4052 
4053         if(conn != null) {
4054            conn.setAutoCommit(autoCommit);
4055         } else {
4056            // Coming here means the connection object is null.
4057            // So generate a connection handle internally, since
4058            // a JdbcRowSet is always connected to a db, it is fine
4059            // to get a handle to the connection.


4080     }
4081 
4082     /**
4083      * Rolls back all the updates in this <code>JdbcRowSet</code> object by
4084      * wrapping the internal <code>Connection</code> object and calling its
4085      * <code>rollback</code> method.
4086      * This method sets this <code>JdbcRowSet</code> object's private field
4087      * <code>rs</code> to <code>null</code> after saving its value to another object.
4088      * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4089      * internal <code>ResultSet</code> object.)
4090      *
4091      * @throws SQLException if autoCommit is set to true or a database
4092      * access error occurs
4093      */
4094     public void rollback() throws SQLException {
4095         conn.rollback();
4096 
4097         // Makes the result ste handle null after rollback
4098         // Added as per Rave requirements
4099 

4100         rs = null;

4101     }
4102 
4103 
4104     /**
4105      * Rollbacks all the updates in the <code>JdbcRowSet</code> back to the
4106      * last <code>Savepoint</code> transaction marker. Wraps the internal
4107      * <code>Connection</code> object and call it's rollback method
4108      *
4109      * @param s the <code>Savepoint</code> transaction marker to roll the
4110      * transaction to.
4111      * @throws SQLException if autoCommit is set to true; or ia a database
4112      * access error occurs
4113      */
4114     public void rollback(Savepoint s) throws SQLException {
4115         conn.rollback(s);
4116     }
4117 
4118     // Setting the ResultSet Type and Concurrency
4119     protected void setParams() throws SQLException {
4120         if(rs == null) {


4206 
4207        checkState();
4208 
4209        return rs;
4210     }
4211 
4212     // Sets the result set handle to the parameter
4213     // Added as per Rave requirements
4214 
4215     /**
4216      * Sets this <code>JdbcRowSet</code> object's resultset property
4217      * to the given <code>ResultSet</code> object.
4218      *
4219      * @param resultSet the <code>ResultSet</code> object
4220      *
4221      */
4222     protected void setResultSet(ResultSet resultSet) {
4223        rs = resultSet;
4224     }
4225 






4226     /**
4227      * Sets this <code>JdbcRowSet</code> object's <code>command</code> property to
4228      * the given <code>String</code> object and clears the parameters, if any,
4229      * that were set for the previous command. In addition,
4230      * if the <code>command</code> property has previously been set to a
4231      * non-null value and it is
4232      * different from the <code>String</code> object supplied,
4233      * this method sets this <code>JdbcRowSet</code> object's private fields
4234      * <code>ps</code> and <code>rs</code> to <code>null</code>.
4235      * (The field <code>ps</code> is its <code>PreparedStatement</code> object, and
4236      * the field <code>rs</code> is its <code>ResultSet</code> object.)
4237      * <P>
4238      * The <code>command</code> property may not be needed if the <code>RowSet</code>
4239      * object gets its data from a source that does not support commands,
4240      * such as a spreadsheet or other tabular file.
4241      * Thus, this property is optional and may be <code>null</code>.
4242      *
4243      * @param command a <code>String</code> object containing an SQL query
4244      *            that will be set as this <code>RowSet</code> object's command
4245      *            property; may be <code>null</code> but may not be an empty string
4246      * @throws SQLException if an empty string is provided as the command value
4247      * @see #getCommand
4248      */
4249     public void setCommand(String command) throws SQLException {

4250 
4251        if (getCommand() != null) {
4252           if(!getCommand().equals(command)) {

4253              super.setCommand(command);
4254              ps = null;
4255              rs = null;

4256           }
4257        }
4258        else {
4259           super.setCommand(command);

4260        }
4261     }
4262 





4263     /**
4264      * Sets the <code>dataSourceName</code> property for this <code>JdbcRowSet</code>
4265      * object to the given logical name and sets this <code>JdbcRowSet</code> object's
4266      * Url property to <code>null</code>. In addition, if the <code>dataSourceName</code>
4267      * property has previously been set and is different from the one supplied,
4268      * this method sets this <code>JdbcRowSet</code> object's private fields
4269      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4270      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4271      * the field <code>rs</code> is its <code>ResultSet</code> object, and
4272      * the field <code>conn</code> is its <code>Connection</code> object.)
4273      * <P>
4274      * The name supplied to this method must have been bound to a
4275      * <code>DataSource</code> object in a JNDI naming service so that an
4276      * application can do a lookup using that name to retrieve the
4277      * <code>DataSource</code> object bound to it. The <code>DataSource</code>
4278      * object can then be used to establish a connection to the data source it
4279      * represents.
4280      * <P>
4281      * Users should set either the Url property or the dataSourceName property.
4282      * If both properties are set, the driver will use the property set most recently.
4283      *
4284      * @param dsName a <code>String</code> object with the name that can be supplied
4285      *        to a naming service based on JNDI technology to retrieve the
4286      *        <code>DataSource</code> object that can be used to get a connection;
4287      *        may be <code>null</code>
4288      * @throws SQLException if there is a problem setting the
4289      *          <code>dataSourceName</code> property
4290      * @see #getDataSourceName
4291      */
4292     public void setDataSourceName(String dsName) throws SQLException{

4293 
4294        if(getDataSourceName() != null) {
4295           if(!getDataSourceName().equals(dsName)) {

4296              super.setDataSourceName(dsName);
4297              conn = null;
4298              ps = null;
4299              rs = null;

4300           }
4301        }
4302        else {
4303           super.setDataSourceName(dsName);

4304        }
4305     }
4306 




4307 
4308     /**
4309      * Sets the Url property for this <code>JdbcRowSet</code> object
4310      * to the given <code>String</code> object and sets the dataSource name
4311      * property to <code>null</code>. In addition, if the Url property has
4312      * previously been set to a non <code>null</code> value and its value
4313      * is different from the value to be set,
4314      * this method sets this <code>JdbcRowSet</code> object's private fields
4315      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4316      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4317      * the field <code>rs</code> is its <code>ResultSet</code> object, and
4318      * the field <code>conn</code> is its <code>Connection</code> object.)
4319      * <P>
4320      * The Url property is a JDBC URL that is used when
4321      * the connection is created using a JDBC technology-enabled driver
4322      * ("JDBC driver") and the <code>DriverManager</code>.
4323      * The correct JDBC URL for the specific driver to be used can be found
4324      * in the driver documentation.  Although there are guidelines for for how
4325      * a JDBC URL is formed,
4326      * a driver vendor can specify any <code>String</code> object except


4330      * a <code>DataSource</code> object instead of the <code>DriverManager</code>.
4331      * The driver will use either the URL property or the
4332      * dataSourceName property to create a connection, whichever was
4333      * specified most recently. If an application uses a JDBC URL, it
4334      * must load a JDBC driver that accepts the JDBC URL before it uses the
4335      * <code>RowSet</code> object to connect to a database.  The <code>RowSet</code>
4336      * object will use the URL internally to create a database connection in order
4337      * to read or write data.
4338      *
4339      * @param url a <code>String</code> object that contains the JDBC URL
4340      *            that will be used to establish the connection to a database for this
4341      *            <code>RowSet</code> object; may be <code>null</code> but must not
4342      *            be an empty string
4343      * @throws SQLException if an error occurs setting the Url property or the
4344      *         parameter supplied is a string with a length of <code>0</code> (an
4345      *         empty string)
4346      * @see #getUrl
4347      */
4348 
4349     public void setUrl(String url) throws SQLException {

4350 
4351        if(getUrl() != null) {
4352           if(!getUrl().equals(url)) {

4353              super.setUrl(url);
4354              conn = null;
4355              ps = null;
4356              rs = null;

4357           }
4358        }
4359        else {
4360           super.setUrl(url);

4361        }
4362     }
4363 





4364      /**
4365      * Sets the username property for this <code>JdbcRowSet</code> object
4366      * to the given user name. Because it
4367      * is not serialized, the username property is set at run time before
4368      * calling the method <code>execute</code>. In addition,
4369      * if the <code>username</code> property is already set with a
4370      * non-null value and that value is different from the <code>String</code>
4371      * object to be set,
4372      * this method sets this <code>JdbcRowSet</code> object's private fields
4373      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4374      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4375      * <code>rs</code> is its <code>ResultSet</code> object, and
4376      * <code>conn</code> is its <code>Connection</code> object.)
4377      * Setting these fields to <code>null</code> ensures that only current
4378      * values will be used.
4379      *
4380      * @param uname the <code>String</code> object containing the user name that
4381      *     is supplied to the data source to create a connection. It may be null.
4382      * @see #getUsername
4383      */
4384     public void setUsername(String uname) {

4385 
4386        if( getUsername() != null) {
4387           if(!getUsername().equals(uname)) {

4388              super.setUsername(uname);
4389              conn = null;
4390              ps = null;
4391              rs = null;

4392           }
4393        }
4394        else{
4395           super.setUsername(uname);

4396        }
4397     }
4398 





4399      /**
4400      * Sets the password property for this <code>JdbcRowSet</code> object
4401      * to the given <code>String</code> object. Because it
4402      * is not serialized, the password property is set at run time before
4403      * calling the method <code>execute</code>. Its default valus is
4404      * <code>null</code>. In addition,
4405      * if the <code>password</code> property is already set with a
4406      * non-null value and that value is different from the one being set,
4407      * this method sets this <code>JdbcRowSet</code> object's private fields
4408      * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4409      * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4410      * <code>rs</code> is its <code>ResultSet</code> object, and
4411      * <code>conn</code> is its <code>Connection</code> object.)
4412      * Setting these fields to <code>null</code> ensures that only current
4413      * values will be used.
4414      *
4415      * @param password the <code>String</code> object that represents the password
4416      *     that must be supplied to the database to create a connection
4417      */
4418     public void setPassword(String password) {

4419 
4420        if ( getPassword() != null) {
4421           if(!getPassword().equals(password)) {

4422              super.setPassword(password);
4423              conn = null;
4424              ps = null;
4425              rs = null;

4426           }
4427        }
4428        else{
4429           super.setPassword(password);

4430        }
4431     }
4432 
4433     /**
4434      * Sets the type for this <code>RowSet</code> object to the specified type.
4435      * The default type is <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>.
4436      *
4437      * @param type one of the following constants:
4438      *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
4439      *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
4440      *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4441      * @throws SQLException if the parameter supplied is not one of the
4442      *         following constants:
4443      *          <code>ResultSet.TYPE_FORWARD_ONLY</code> or
4444      *          <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
4445      *          <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4446      * @see #getConcurrency
4447      * @see #getType
4448      */
4449 
4450     public void setType(int type) throws SQLException {
4451 
4452        int oldVal;
4453 
4454        try {
4455           oldVal = getType();
4456         }catch(SQLException ex) {
4457            oldVal = 0;
4458         }
4459 
4460        if(oldVal != type) {
4461            super.setType(type);

4462        }
4463 
4464     }
4465 
4466     /**
4467      * Sets the concurrency for this <code>RowSet</code> object to
4468      * the specified concurrency. The default concurrency for any <code>RowSet</code>
4469      * object (connected or disconnected) is <code>ResultSet.CONCUR_UPDATABLE</code>,
4470      * but this method may be called at any time to change the concurrency.
4471      *
4472      * @param concur one of the following constants:
4473      *                    <code>ResultSet.CONCUR_READ_ONLY</code> or
4474      *                    <code>ResultSet.CONCUR_UPDATABLE</code>
4475      * @throws SQLException if the parameter supplied is not one of the
4476      *         following constants:
4477      *          <code>ResultSet.CONCUR_UPDATABLE</code> or
4478      *          <code>ResultSet.CONCUR_READ_ONLY</code>
4479      * @see #getConcurrency
4480      * @see #isReadOnly
4481      */
4482     public void setConcurrency(int concur) throws SQLException {
4483 
4484        int oldVal;
4485 
4486        try {
4487           oldVal = getConcurrency();
4488         }catch(NullPointerException ex) {
4489            oldVal = 0;
4490         }
4491 
4492        if(oldVal != concur) {
4493            super.setConcurrency(concur);








































































4494        }
4495 
4496     }
4497 
4498     /**
4499      * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4500      * <code>SQLXML</code> object in the Java programming language.
4501      * @param columnIndex the first column is 1, the second is 2, ...
4502      * @return a SQLXML object that maps an SQL XML value
4503      * @throws SQLException if a database access error occurs
4504      * @since 6.0
4505      */
4506     public SQLXML getSQLXML(int columnIndex) throws SQLException {
4507         throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString());
4508     }
4509 
4510     /**
4511      * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4512      * <code>SQLXML</code> object in the Java programming language.
4513      * @param colName the name of the column from which to retrieve the value