/*
 * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.sql.rowset;

import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import java.io.*;
import java.math.*;
import java.util.*;

import javax.sql.rowset.spi.*;

/**
 * The interface that all standard implementations of
 * <code>CachedRowSet</code> must implement.
 * <P>
 * The reference implementation of the <code>CachedRowSet</code> interface provided
 * by Sun Microsystems is a standard implementation. Developers may use this implementation
 * just as it is, they may extend it, or they may choose to write their own implementations
 * of this interface.
 * <P>
 * A <code>CachedRowSet</code> object is a container for rows of data
 * that caches its rows in memory, which makes it possible to operate without always being
 * connected to its data source. Further, it is a
 * JavaBeans<sup><font size=-2>TM</font></sup> component and is scrollable,
 * updatable, and serializable. A <code>CachedRowSet</code> object typically
 * contains rows from a result set, but it can also contain rows from any file
 * with a tabular format, such as a spread sheet.  The reference implementation
 * supports getting data only from a <code>ResultSet</code> object, but
 * developers can extend the <code>SyncProvider</code> implementations to provide
 * access to other tabular data sources.
 * <P>
 * An application can modify the data in a <code>CachedRowSet</code> object, and
 * those modifications can then be propagated back to the source of the data.
 * <P>
 * A <code>CachedRowSet</code> object is a <i>disconnected</i> rowset, which means
 * that it makes use of a connection to its data source only briefly. It connects to its
 * data source while it is reading data to populate itself with rows and again
 * while it is propagating changes back to its underlying data source. The rest
 * of the time, a <code>CachedRowSet</code> object is disconnected, including
 * while its data is being modified. Being disconnected makes a <code>RowSet</code>
 * object much leaner and therefore much easier to pass to another component.  For
 * example, a disconnected <code>RowSet</code> object can be serialized and passed
 * over the wire to a thin client such as a personal digital assistant (PDA).
 * <P>
 *
 * <h3>1.0 Creating a <code>CachedRowSet</code> Object</h3>
 * The following line of code uses the default constructor for
 * <code>CachedRowSet</code>
 * supplied in the reference implementation (RI) to create a default
 * <code>CachedRowSet</code> object.
 * <PRE>
 *     CachedRowSetImpl crs = new CachedRowSetImpl();
 * </PRE>
 * This new <code>CachedRowSet</code> object will have its properties set to the
 * default properties of a <code>BaseRowSet</code> object, and, in addition, it will
 * have an <code>RIOptimisticProvider</code> object as its synchronization provider.
 * <code>RIOptimisticProvider</code>, one of two <code>SyncProvider</code>
 * implementations included in the RI, is the default provider that the
 * <code>SyncFactory</code> singleton will supply when no synchronization
 * provider is specified.
 * <P>
 * A <code>SyncProvider</code> object provides a <code>CachedRowSet</code> object
 * with a reader (a <code>RowSetReader</code> object) for reading data from a
 * data source to populate itself with data. A reader can be implemented to read
 * data from a <code>ResultSet</code> object or from a file with a tabular format.
 * A <code>SyncProvider</code> object also provides
 * a writer (a <code>RowSetWriter</code> object) for synchronizing any
 * modifications to the <code>CachedRowSet</code> object's data made while it was
 * disconnected with the data in the underlying data source.
 * <P>
 * A writer can be implemented to exercise various degrees of care in checking
 * for conflicts and in avoiding them.
 * (A conflict occurs when a value in the data source has been changed after
 * the rowset populated itself with that value.)
 * The <code>RIOptimisticProvider</code> implementation assumes there will be
 * few or no conflicts and therefore sets no locks. It updates the data source
 * with values from the <code>CachedRowSet</code> object only if there are no
 * conflicts.
 * Other writers can be implemented so that they always write modified data to
 * the data source, which can be accomplished either by not checking for conflicts
 * or, on the other end of the spectrum, by setting locks sufficient to prevent data
 * in the data source from being changed. Still other writer implementations can be
 * somewhere in between.
 * <P>
 * A <code>CachedRowSet</code> object may use any
 * <code>SyncProvider</code> implementation that has been registered
 * with the <code>SyncFactory</code> singleton. An application
 * can find out which <code>SyncProvider</code> implementations have been
 * registered by calling the following line of code.
 * <PRE>
 *      java.util.Enumeration providers = SyncFactory.getRegisteredProviders();
 * </PRE>
 * <P>
 * There are two ways for a <code>CachedRowSet</code> object to specify which
 * <code>SyncProvider</code> object it will use.
 * <UL)
 *     <LI>Supplying the name of the implementation to the constructor<BR>
 *     The following line of code creates the <code>CachedRowSet</code>
 *     object <i>crs2</i> that is initialized with default values except that its
 *     <code>SyncProvider</code> object is the one specified.
 *     <PRE>
 *          CachedRowSetImpl crs2 = new CachedRowSetImpl(
 *                                 "com.fred.providers.HighAvailabilityProvider");
 *     </PRE>
 *     <LI>Setting the <code>SyncProvider</code> using the <code>CachedRowSet</code>
 *         method <code>setSyncProvider</code><BR>
 *      The following line of code resets the <code>SyncProvider</code> object
 *      for <i>crs</i>, the <code>CachedRowSet</code> object created with the
 *      default constructor.
 *      <PRE>
 *           crs.setSyncProvider("com.fred.providers.HighAvailabilityProvider");
 *      </PRE>
 * </UL)
 * See the comments for <code>SyncFactory</code> and <code>SyncProvider</code> for
 * more details.
 *
 * <P>
 * <h3>2.0 Retrieving Data from a <code>CachedRowSet</code> Object</h3>
 * Data is retrieved from a <code>CachedRowSet</code> object by using the
 * getter methods inherited from the <code>ResultSet</code>
 * interface.  The following examples, in which <code>crs</code> is a
 * <code>CachedRowSet</code>
 * object, demonstrate how to iterate through the rows, retrieving the column
 * values in each row.  The first example uses the version of the
 * getter methods that take a column number; the second example
 * uses the version that takes a column name. Column numbers are generally
 * used when the <code>RowSet</code> object's command
 * is of the form <code>SELECT * FROM TABLENAME</code>; column names are most
 * commonly used when the command specifies columns by name.
 * <PRE>
 *    while (crs.next()) {
 *        String name = crs.getString(1);
 *        int id = crs.getInt(2);
 *        Clob comment = crs.getClob(3);
 *        short dept = crs.getShort(4);
 *        System.out.println(name + "  " + id + "  " + comment + "  " + dept);
 *    }
 * </PRE>
 *
 * <PRE>
 *    while (crs.next()) {
 *        String name = crs.getString("NAME");
 *        int id = crs.getInt("ID");
 *        Clob comment = crs.getClob("COM");
 *        short dept = crs.getShort("DEPT");
 *        System.out.println(name + "  " + id + "  " + comment + "  " + dept);
 *    }
 * </PRE>
 * <h4>2.1 Retrieving <code>RowSetMetaData</code></h4>
 * An application can get information about the columns in a <code>CachedRowSet</code>
 * object by calling <code>ResultSetMetaData</code> and <code>RowSetMetaData</code>
 * methods on a <code>RowSetMetaData</code> object. The following code fragment,
 * in which <i>crs</i> is a <code>CachedRowSet</code> object, illustrates the process.
 * The first line creates a <code>RowSetMetaData</code> object with information
 * about the columns in <i>crs</i>.  The method <code>getMetaData</code>,
 * inherited from the <code>ResultSet</code> interface, returns a
 * <code>ResultSetMetaData</code> object, which is cast to a
 * <code>RowSetMetaData</code> object before being assigned to the variable
 * <i>rsmd</i>.  The second line finds out how many columns <i>jrs</i> has, and
 * the third line gets the JDBC type of values stored in the second column of
 * <code>jrs</code>.
 * <PRE>
 *     RowSetMetaData rsmd = (RowSetMetaData)crs.getMetaData();
 *     int count = rsmd.getColumnCount();
 *     int type = rsmd.getColumnType(2);
 * </PRE>
 * The <code>RowSetMetaData</code> interface differs from the
 * <code>ResultSetMetaData</code> interface in two ways.
 * <UL>
 *   <LI><i>It includes <code>setter</code> methods:</i> A <code>RowSet</code>
 *   object uses these methods internally when it is populated with data from a
 *   different <code>ResultSet</code> object.
 *   <P>
 *   <LI><i>It contains fewer <code>getter</code> methods:</i> Some
 *   <code>ResultSetMetaData</code> methods to not apply to a <code>RowSet</code>
 *   object. For example, methods retrieving whether a column value is writable
 *   or read only do not apply because all of a <code>RowSet</code> object's
 *   columns will be writable or read only, depending on whether the rowset is
 *   updatable or not.
 * </UL>
 * NOTE: In order to return a <code>RowSetMetaData</code> object, implementations must
 * override the <code>getMetaData()</code> method defined in
 * <code>java.sql.ResultSet</code> and return a <code>RowSetMetaData</code> object.
 *
 * <h3>3.0 Updating a <code>CachedRowSet</code> Object</h3>
 * Updating a <code>CachedRowSet</code> object is similar to updating a
 * <code>ResultSet</code> object, but because the rowset is not connected to
 * its data source while it is being updated, it must take an additional step
 * to effect changes in its underlying data source. After calling the method
 * <code>updateRow</code> or <code>insertRow</code>, a
 * <code>CachedRowSet</code>
 * object must also call the method <code>acceptChanges</code> to have updates
 * written to the data source. The following example, in which the cursor is
 * on a row in the <code>CachedRowSet</code> object <i>crs</i>, shows
 * the code required to update two column values in the current row and also
 * update the <code>RowSet</code> object's underlying data source.
 * <PRE>
 *     crs.updateShort(3, 58);
 *     crs.updateInt(4, 150000);
 *     crs.updateRow();
 *     crs.acceptChanges();
 * </PRE>
 * <P>
 * The next example demonstrates moving to the insert row, building a new
 * row on the insert row, inserting it into the rowset, and then calling the
 * method <code>acceptChanges</code> to add the new row to the underlying data
 * source.  Note that as with the getter methods, the  updater methods may take
 * either a column index or a column name to designate the column being acted upon.
 * <PRE>
 *     crs.moveToInsertRow();
 *     crs.updateString("Name", "Shakespeare");
 *     crs.updateInt("ID", 10098347);
 *     crs.updateShort("Age", 58);
 *     crs.updateInt("Sal", 150000);
 *     crs.insertRow();
 *     crs.moveToCurrentRow();
 *     crs.acceptChanges();
 * </PRE>
 * <P>
 * NOTE: Where the <code>insertRow()</code> method inserts the contents of a
 * <code>CachedRowSet</code> object's insert row is implementation-defined.
 * The reference implementation for the <code>CachedRowSet</code> interface
 * inserts a new row immediately following the current row, but it could be
 * implemented to insert new rows in any number of other places.
 * <P>
 * Another thing to note about these examples is how they use the method
 * <code>acceptChanges</code>.  It is this method that propagates changes in
 * a <code>CachedRowSet</code> object back to the underlying data source,
 * calling on the <code>RowSet</code> object's writer internally to write
 * changes to the data source. To do this, the writer has to incur the expense
 * of establishing a connection with that data source. The
 * preceding two code fragments call the method <code>acceptChanges</code>
 * immediately after calling <code>updateRow</code> or <code>insertRow</code>.
 * However, when there are multiple rows being changed, it is more efficient to call
 * <code>acceptChanges</code> after all calls to <code>updateRow</code>
 * and <code>insertRow</code> have been made.  If <code>acceptChanges</code>
 * is called only once, only one connection needs to be established.
 * <P>
 * <h3>4.0 Updating the Underlying Data Source</h3>
 * When the method <code>acceptChanges</code> is executed, the
 * <code>CachedRowSet</code> object's writer, a <code>RowSetWriterImpl</code>
 * object, is called behind the scenes to write the changes made to the
 * rowset to the underlying data source. The writer is implemented to make a
 * connection to the data source and write updates to it.
 * <P>
 * A writer is made available through an implementation of the
 * <code>SyncProvider</code> interface, as discussed in section 1,
 * "Creating a <code>CachedRowSet</code> Object."
 * The default reference implementation provider, <code>RIOptimisticProvider</code>,
 * has its writer implemented to use an optimistic concurrency control
 * mechanism. That is, it maintains no locks in the underlying database while
 * the rowset is disconnected from the database and simply checks to see if there
 * are any conflicts before writing data to the data source.  If there are any
 * conflicts, it does not write anything to the data source.
 * <P>
 * The reader/writer facility
 * provided by the <code>SyncProvider</code> class is pluggable, allowing for the
 * customization of data retrieval and updating. If a different concurrency
 * control mechanism is desired, a different implementation of
 * <code>SyncProvider</code> can be plugged in using the method
 * <code>setSyncProvider</code>.
 * <P>
 * In order to use the optimistic concurrency control routine, the
 * <code>RIOptismisticProvider</code> maintains both its current
 * value and its original value (the value it had immediately preceding the
 * current value). Note that if no changes have been made to the data in a
 * <code>RowSet</code> object, its current values and its original values are the same,
 * both being the values with which the <code>RowSet</code> object was initially
 * populated.  However, once any values in the <code>RowSet</code> object have been
 * changed, the current values and the original values will be different, though at
 * this stage, the original values are still the initial values. With any subsequent
 * changes to data in a <code>RowSet</code> object, its original values and current
 * values will still differ, but its original values will be the values that
 * were previously the current values.
 * <P>
 * Keeping track of original values allows the writer to compare the <code>RowSet</code>
 * object's original value with the value in the database. If the values in
 * the database differ from the <code>RowSet</code> object's original values, which means that
 * the values in the database have been changed, there is a conflict.
 * Whether a writer checks for conflicts, what degree of checking it does, and how
 * it handles conflicts all depend on how it is implemented.
 * <P>
 * <h3>5.0 Registering and Notifying Listeners</h3>
 * Being JavaBeans components, all rowsets participate in the JavaBeans event
 * model, inheriting methods for registering listeners and notifying them of
 * changes from the <code>BaseRowSet</code> class.  A listener for a
 * <code>CachedRowSet</code> object is a component that wants to be notified
 * whenever there is a change in the rowset.  For example, if a
 * <code>CachedRowSet</code> object contains the results of a query and
 * those
 * results are being displayed in, say, a table and a bar graph, the table and
 * bar graph could be registered as listeners with the rowset so that they can
 * update themselves to reflect changes. To become listeners, the table and
 * bar graph classes must implement the <code>RowSetListener</code> interface.
 * Then they can be added to the <Code>CachedRowSet</code> object's list of
 * listeners, as is illustrated in the following lines of code.
 * <PRE>
 *    crs.addRowSetListener(table);
 *    crs.addRowSetListener(barGraph);
 * </PRE>
 * Each <code>CachedRowSet</code> method that moves the cursor or changes
 * data also notifies registered listeners of the changes, so
 * <code>table</code> and <code>barGraph</code> will be notified when there is
 * a change in <code>crs</code>.
 * <P>
 * <h3>6.0 Passing Data to Thin Clients</h3>
 * One of the main reasons to use a <code>CachedRowSet</code> object is to
 * pass data between different components of an application. Because it is
 * serializable, a <code>CachedRowSet</code> object can be used, for example,
 * to send the result of a query executed by an enterprise JavaBeans component
 * running in a server environment over a network to a client running in a
 * web browser.
 * <P>
 * While a <code>CachedRowSet</code> object is disconnected, it can be much
 * leaner than a <code>ResultSet</code> object with the same data.
 * As a result, it can be especially suitable for sending data to a thin client
 * such as a PDA, where it would be inappropriate to use a JDBC driver
 * due to resource limitations or security considerations.
 * Thus, a <code>CachedRowSet</code> object provides a means to "get rows in"
 * without the need to implement the full JDBC API.
 * <P>
 * <h3>7.0 Scrolling and Updating</h3>
 * A second major use for <code>CachedRowSet</code> objects is to provide
 * scrolling and updating for <code>ResultSet</code> objects that
 * do not provide these capabilities themselves.  In other words, a
 * <code>CachedRowSet</code> object can be used to augment the
 * capabilities of a JDBC technology-enabled driver (hereafter called a
 * "JDBC driver") when the DBMS does not provide full support for scrolling and
 * updating. To achieve the effect of making a non-scrollble and read-only
 * <code>ResultSet</code> object scrollable and updatable, a programmer
 * simply needs to create a <code>CachedRowSet</code> object populated
 * with that <code>ResultSet</code> object's data.  This is demonstrated
 * in the following code fragment, where <code>stmt</code> is a
 * <code>Statement</code> object.
 * <PRE>
 *    ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES");
 *    CachedRowSetImpl crs = new CachedRowSetImpl();
 *    crs.populate(rs);
 * </PRE>
 * <P>
 * The object <code>crs</code> now contains the data from the table
 * <code>EMPLOYEES</code>, just as the object <code>rs</code> does.
 * The difference is that the cursor for <code>crs</code> can be moved
 * forward, backward, or to a particular row even if the cursor for
 * <code>rs</code> can move only forward.  In addition, <code>crs</code> is
 * updatable even if <code>rs</code> is not because by default, a
 * <code>CachedRowSet</code> object is both scrollable and updatable.
 * <P>
 * In summary, a <code>CachedRowSet</code> object can be thought of as simply
 * a disconnected set of rows that are being cached outside of a data source.
 * Being thin and serializable, it can easily be sent across a wire,
 * and it is well suited to sending data to a thin client. However, a
 * <code>CachedRowSet</code> object does have a limitation: It is limited in
 * size by the amount of data it can store in memory at one time.
 * <P>
 * <h3>8.0 Getting Universal Data Access</h3>
 * Another advantage of the <code>CachedRowSet</code> class is that it makes it
 * possible to retrieve and store data from sources other than a relational
 * database. The reader for a rowset can be implemented to read and populate
 * its rowset with data from any tabular data source, including a spreadsheet
 * or flat file.
 * Because both a <code>CachedRowSet</code> object and its metadata can be
 * created from scratch, a component that acts as a factory for rowsets
 * can use this capability to create a rowset containing data from
 * non-SQL data sources. Nevertheless, it is expected that most of the time,
 * <code>CachedRowSet</code> objects will contain data that was fetched
 * from an SQL database using the JDBC API.
 * <P>
 * <h3>9.0 Setting Properties</h3>
 * All rowsets maintain a set of properties, which will usually be set using
 * a tool.  The number and kinds of properties a rowset has will vary,
 * depending on what the rowset does and how it gets its data.  For example,
 * rowsets that get their data from a <code>ResultSet</code> object need to
 * set the properties that are required for making a database connection.
 * If a rowset uses the <code>DriverManager</code> facility to make a
 * connection, it needs to set a property for the JDBC URL that identifies
 * the appropriate driver, and it needs to set the properties that give the
 * user name and password.
 * If, on the other hand, the rowset uses a <code>DataSource</code> object
 * to make the connection, which is the preferred method, it does not need to
 * set the property for the JDBC URL.  Instead, it needs to set
 * properties for the logical name of the data source, for the user name,
 * and for the password.
 * <P>
 * NOTE:  In order to use a <code>DataSource</code> object for making a
 * connection, the <code>DataSource</code> object must have been registered
 * with a naming service that uses the Java Naming and Directory
 * Interface<sup><font size=-2>TM</font></sup> (JNDI) API.  This registration
 * is usually done by a person acting in the capacity of a system
 * administrator.
 * <P>
 * In order to be able to populate itself with data from a database, a rowset
 * needs to set a command property.  This property is a query that is a
 * <code>PreparedStatement</code> object, which allows the query to have
 * parameter placeholders that are set at run time, as opposed to design time.
 * To set these placeholder parameters with values, a rowset provides
 * setter methods for setting values of each data type,
 * similar to the setter methods provided by the <code>PreparedStatement</code>
 * interface.
 * <P>
 * The following code fragment illustrates how the <code>CachedRowSet</code>
 * object <code>crs</code> might have its command property set.  Note that if a
 * tool is used to set properties, this is the code that the tool would use.
 * <PRE>
 *    crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS " +
 *                   "WHERE CREDIT_LIMIT > ? AND REGION = ?");
 * </PRE>
 * <P>
 * The values that will be used to set the command's placeholder parameters are
 * contained in the <code>RowSet</code> object's <code>params</code> field, which is a
 * <code>Vector</code> object.
 * The <code>CachedRowSet</code> class provides a set of setter
 * methods for setting the elements in its <code>params</code> field.  The
 * following code fragment demonstrates setting the two parameters in the
 * query from the previous example.
 * <PRE>
 *    crs.setInt(1, 5000);
 *    crs.setString(2, "West");
 * </PRE>
 * <P>
 * The <code>params</code> field now contains two elements, each of which is
 * an array two elements long.  The first element is the parameter number;
 * the second is the value to be set.
 * In this case, the first element of <code>params</code> is
 * <code>1</code>, <code>5000</code>, and the second element is <code>2</code>,
 * <code>"West"</code>.  When an application calls the method
 * <code>execute</code>, it will in turn call on this <code>RowSet</code> object's reader,
 * which will in turn invoke its <code>readData</code> method. As part of
 * its implementation, <code>readData</code> will get the values in
 * <code>params</code> and use them to set the command's placeholder
 * parameters.
 * The following code fragment gives an idea of how the reader
 * does this, after obtaining the <code>Connection</code> object
 * <code>con</code>.
 * <PRE>
 *    PreparedStatement pstmt = con.prepareStatement(crs.getCommand());
 *    reader.decodeParams();
 *    // decodeParams figures out which setter methods to use and does something
 *    // like the following:
 *    //    for (i = 0; i < params.length; i++) {
 *    //        pstmt.setObject(i + 1, params[i]);
 *    //    }
 * </PRE>
 * <P>
 * At this point, the command for <code>crs</code> is the query <code>"SELECT
 * FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS WHERE CREDIT_LIMIT > 5000
 * AND REGION = "West"</code>.  After the <code>readData</code> method executes
 * this command with the following line of code, it will have the data from
 * <code>rs</code> with which to populate <code>crs</code>.
 * <PRE>
 *     ResultSet rs = pstmt.executeQuery();
 * </PRE>
 * <P>
 * The preceding code fragments give an idea of what goes on behind the
 * scenes; they would not appear in an application, which would not invoke
 * methods like <code>readData</code> and <code>decodeParams</code>.
 * In contrast, the following code fragment shows what an application might do.
 * It sets the rowset's command, sets the command's parameters, and executes
 * the command. Simply by calling the <code>execute</code> method,
 * <code>crs</code> populates itself with the requested data from the
 * table <code>CUSTOMERS</code>.
 * <PRE>
 *    crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS" +
 *                   "WHERE CREDIT_LIMIT > ? AND REGION = ?");
 *    crs.setInt(1, 5000);
 *    crs.setString(2, "West");
 *    crs.execute();
 * </PRE>
 *
 * <h3>10.0 Paging Data</h3>
 * Because a <code>CachedRowSet</code> object stores data in memory,
 * the amount of data that it can contain at any one
 * time is determined by the amount of memory available. To get around this limitation,
 * a <code>CachedRowSet</code> object can retrieve data from a <code>ResultSet</code>
 * object in chunks of data, called <i>pages</i>. To take advantage of this mechanism,
 * an application sets the number of rows to be included in a page using the method
 * <code>setPageSize</code>. In other words, if the page size is set to five, a chunk
 * of five rows of
 * data will be fetched from the data source at one time. An application can also
 * optionally set the maximum number of rows that may be fetched at one time.  If the
 * maximum number of rows is set to zero, or no maximum number of rows is set, there is
 * no limit to the number of rows that may be fetched at a time.
 * <P>
 * After properties have been set,
 * the <code>CachedRowSet</code> object must be populated with data
 * using either the method <code>populate</code> or the method <code>execute</code>.
 * The following lines of code demonstrate using the method <code>populate</code>.
 * Note that this version of the method takes two parameters, a <code>ResultSet</code>
 * handle and the row in the <code>ResultSet</code> object from which to start
 * retrieving rows.
 * <PRE>
 *     CachedRowSet crs = new CachedRowSetImpl();
 *     crs.setMaxRows(20);
 *     crs.setPageSize(4);
 *     crs.populate(rsHandle, 10);
 * </PRE>
 * When this code runs, <i>crs</i> will be populated with four rows from
 * <i>rsHandle</i> starting with the tenth row.
 * <P>
 * The next code fragment shows populating a <code>CachedRowSet</code> object using the
 * method <code>execute</code>, which may or may not take a <code>Connection</code>
 * object as a parameter.  This code passes <code>execute</code> the <code>Connection</code>
 * object <i>conHandle</i>.
 * <P>
 * Note that there are two differences between the following code
 * fragment and the previous one. First, the method <code>setMaxRows</code> is not
 * called, so there is no limit set for the number of rows that <i>crs</i> may contain.
 * (Remember that <i>crs</i> always has the overriding limit of how much data it can
 * store in memory.) The second difference is that the you cannot pass the method
 * <code>execute</code> the number of the row in the <code>ResultSet</code> object
 * from which to start retrieving rows. This method always starts with the first row.
 * <PRE>
 *     CachedRowSet crs = new CachedRowSetImpl();
 *     crs.setPageSize(5);
 *     crs.execute(conHandle);
 * </PRE>
 * After this code has run, <i>crs</i> will contain five rows of data from the
 * <code>ResultSet</code> object produced by the command for <i>crs</i>. The writer
 * for <i>crs</i> will use <i>conHandle</i> to connect to the data source and
 * execute the command for <i>crs</i>. An application is then able to operate on the
 * data in <i>crs</i> in the same way that it would operate on data in any other
 * <code>CachedRowSet</code> object.
 * <P>
 * To access the next page (chunk of data), an application calls the method
 * <code>nextPage</code>.  This method creates a new <code>CachedRowSet</code> object
 * and fills it with the next page of data.  For example, assume that the
 * <code>CachedRowSet</code> object's command returns a <code>ResultSet</code> object
 * <i>rs</i> with 1000 rows of data.  If the page size has been set to 100, the first
 *  call to the method <code>nextPage</code> will create a <code>CachedRowSet</code> object
 * containing the first 100 rows of <i>rs</i>. After doing what it needs to do with the
 * data in these first 100 rows, the application can again call the method
 * <code>nextPage</code> to create another <code>CachedRowSet</code> object
 * with the second 100 rows from <i>rs</i>. The data from the first <code>CachedRowSet</code>
 * object will no longer be in memory because it is replaced with the data from the
 * second <code>CachedRowSet</code> object. After the tenth call to the method <code>nextPage</code>,
 * the tenth <code>CachedRowSet</code> object will contain the last 100 rows of data from
 * <i>rs</i>, which are stored in memory. At any given time, the data from only one
 * <code>CachedRowSet</code> object is stored in memory.
 * <P>
 * The method <code>nextPage</code> returns <code>true</code> as long as the current
 * page is not the last page of rows and <code>false</code> when there are no more pages.
 * It can therefore be used in a <code>while</code> loop to retrieve all of the pages,
 * as is demonstrated in the following lines of code.
 * <PRE>
 *     CachedRowSet crs = CachedRowSetImpl();
 *     crs.setPageSize(100);
 *     crs.execute(conHandle);
 *
 *     while(crs.nextPage()) {
 *         while(crs.next()) {
 *             . . . // operate on chunks (of 100 rows each) in crs,
 *                   // row by row
 *         }
 *     }
 * </PRE>
 * After this code fragment has been run, the application will have traversed all
 * 1000 rows, but it will have had no more than 100 rows in memory at a time.
 * <P>
 * The <code>CachedRowSet</code> interface also defines the method <code>previousPage</code>.
 * Just as the method <code>nextPage</code> is analogous to the <code>ResultSet</code>
 * method <code>next</code>, the method <code>previousPage</code> is analogous to
 * the <code>ResultSet</code> method <code>previous</code>.  Similar to the method
 * <code>nextPage</code>, <code>previousPage</code> creates a <code>CachedRowSet</code>
 * object containing the number of rows set as the page size.  So, for instance, the
 * method <code>previousPage</code> could be used in a <code>while</code> loop at
 * the end of the preceding code fragment to navigate back through the pages from the last
 * page to the first page.
 * The method <code>previousPage</code> is also similar to <code>nextPage</code>
 * in that it can be used in a <code>while</code>
 * loop, except that it returns <code>true</code> as long as there is another page
 * preceding it and <code>false</code> when there are no more pages ahead of it.
 * <P>
 * By positioning the cursor after the last row for each page,
 * as is done in the following code fragment, the method <code>previous</code>
 * navigates from the last row to the first row in each page.
 * The code could also have left the cursor before the first row on each page and then
 * used the method <code>next</code> in a <code>while</code> loop to navigate each page
 * from the first row to the last row.
 * <P>
 * The following code fragment assumes a continuation from the previous code fragment,
 * meaning that the cursor for the tenth <code>CachedRowSet</code> object is on the
 * last row.  The code moves the cursor to after the last row so that the first
 * call to the method <code>previous</code> will put the cursor back on the last row.
 * After going through all of the rows in the last page (the <code>CachedRowSet</code>
 * object <i>crs</i>), the code then enters
 * the <code>while</code> loop to get to the ninth page, go through the rows backwards,
 * go to the eighth page, go through the rows backwards, and so on to the first row
 * of the first page.
 *
 * <PRE>
 *     crs.afterLast();
 *     while(crs.previous())  {
 *         . . . // navigate through the rows, last to first
 *     {
 *     while(crs.previousPage())  {
 *         crs.afterLast();
 *         while(crs.previous())  {
 *             . . . // go from the last row to the first row of each page
 *         }
 *     }
 * </PRE>
 *
 * @author Jonathan Bruce
 */

public interface CachedRowSet extends RowSet, Joinable {

   /**
    * Populates this <code>CachedRowSet</code> object with data from
    * the given <code>ResultSet</code> object.
    * <P>
    * This method can be used as an alternative to the <code>execute</code> method when an
    * application has a connection to an open <code>ResultSet</code> object.
    * Using the method <code>populate</code> can be more efficient than using
    * the version of the <code>execute</code> method that takes no parameters
    * because it does not open a new connection and re-execute this
    * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
    * method is more a matter of convenience when compared to using the version
    * of <code>execute</code> that takes a <code>ResultSet</code> object.
    *
    * @param data the <code>ResultSet</code> object containing the data
    *           to be read into this <code>CachedRowSet</code> object
    * @throws SQLException if a null <code>ResultSet</code> object is supplied
    *           or this <code>CachedRowSet</code> object cannot
    *           retrieve the associated <code>ResultSetMetaData</code> object
    * @see #execute
    * @see java.sql.ResultSet
    * @see java.sql.ResultSetMetaData
    */
    public void populate(ResultSet data) throws SQLException;

   /**
    * Populates this <code>CachedRowSet</code> object with data, using the
    * given connection to produce the result set from which the data will be read.
    * This method should close any database connections that it creates to
    * ensure that this <code>CachedRowSet</code> object is disconnected except when
    * it is reading data from its data source or writing data to its data source.
    * <P>
    * The reader for this <code>CachedRowSet</code> object
    * will use <i>conn</i> to establish a connection to the data source
    * so that it can execute the rowset's command and read data from the
    * the resulting <code>ResultSet</code> object into this
    * <code>CachedRowSet</code> object. This method also closes <i>conn</i>
    * after it has populated this <code>CachedRowSet</code> object.
    * <P>
    * If this method is called when an implementation has already been
    * populated, the contents and the metadata are (re)set. Also, if this method is
    * called before the method <code>acceptChanges</code> has been called
    * to commit outstanding updates, those updates are lost.
    *
    * @param conn a standard JDBC <code>Connection</code> object with valid
    *           properties
    * @throws SQLException if an invalid <code>Connection</code> object is supplied
    *           or an error occurs in establishing the connection to the
    *           data source
    * @see #populate
    * @see java.sql.Connection
    */
    public void execute(Connection conn) throws SQLException;

   /**
    * Propagates row update, insert and delete changes made to this
    * <code>CachedRowSet</code> object to the underlying data source.
    * <P>
    * This method calls on this <code>CachedRowSet</code> object's writer
    * to do the work behind the scenes.
    * Standard <code>CachedRowSet</code> implementations should use the
    * <code>SyncFactory</code> singleton
    * to obtain a <code>SyncProvider</code> instance providing a
    * <code>RowSetWriter</code> object (writer).  The writer will attempt
    * to propagate changes made in this <code>CachedRowSet</code> object
    * back to the data source.
    * <P>
    * When the method <code>acceptChanges</code> executes successfully, in
    * addition to writing changes to the data source, it
    * makes the values in the current row be the values in the original row.
    * <P>
    * Depending on the synchronization level of the <code>SyncProvider</code>
    * implementation being used, the writer will compare the original values
    * with those in the data source to check for conflicts. When there is a conflict,
    * the <code>RIOptimisticProvider</code> implementation, for example, throws a
    * <code>SyncProviderException</code> and does not write anything to the
    * data source.
    * <P>
    * An application may choose to catch the <code>SyncProviderException</code>
    * object and retrieve the <code>SyncResolver</code> object it contains.
    * The <code>SyncResolver</code> object lists the conflicts row by row and
    * sets a lock on the data source to avoid further conflicts while the
    * current conflicts are being resolved.
    * Further, for each conflict, it provides methods for examining the conflict
    * and setting the value that should be persisted in the data source.
    * After all conflicts have been resolved, an application must call the
    * <code>acceptChanges</code> method again to write resolved values to the
    * data source.  If all of the values in the data source are already the
    * values to be persisted, the method <code>acceptChanges</code> does nothing.
    * <P>
    * Some provider implementations may use locks to ensure that there are no
    * conflicts.  In such cases, it is guaranteed that the writer will succeed in
    * writing changes to the data source when the method <code>acceptChanges</code>
    * is called.  This method may be called immediately after the methods
    * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
    * have been called, but it is more efficient to call it only once after
    * all changes have been made so that only one connection needs to be
    * established.
    * <P>
    * Note: The <code>acceptChanges()</code> method will determine if the
    * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
    * to true, all updates in the synchronization are committed to the data
    * source. Otherwise, the application <b>must</b> explicity call the
    * <code>commit()</code> or <code>rollback()</code> methods as appropriate.
    *
    * @throws SQLException if the cursor is on the insert row
    * @throws SyncProviderException if the underlying
    *           synchronization provider's writer fails to write the updates
    *           back to the data source
    * @see #acceptChanges(java.sql.Connection)
    * @see javax.sql.RowSetWriter
    * @see javax.sql.rowset.spi.SyncFactory
    * @see javax.sql.rowset.spi.SyncProvider
    * @see javax.sql.rowset.spi.SyncProviderException
    * @see javax.sql.rowset.spi.SyncResolver
    */
    public void acceptChanges() throws SyncProviderException;

   /**
    * Propagates all row update, insert and delete changes to the
    * data source backing this <code>CachedRowSet</code> object
    * using the specified <code>Connection</code> object to establish a
    * connection to the data source.
    * <P>
    * The other version of the <code>acceptChanges</code> method is not passed
    * a connection because it uses
    * the <code>Connection</code> object already defined within the <code>RowSet</code>
    * object, which is the connection used for populating it initially.
    * <P>
    * This form of the method <code>acceptChanges</code> is similar to the
    * form that takes no arguments; however, unlike the other form, this form
    * can be used only when the underlying data source is a JDBC data source.
    * The updated <code>Connection</code> properties must be used by the
    * <code>SyncProvider</code> to reset the <code>RowSetWriter</code>
    * configuration to ensure that the contents of the <code>CachedRowSet</code>
    * object are synchronized correctly.
    * <P>
    * When the method <code>acceptChanges</code> executes successfully, in
    * addition to writing changes to the data source, it
    * makes the values in the current row be the values in the original row.
    * <P>
    * Depending on the synchronization level of the <code>SyncProvider</code>
    * implementation being used, the writer will compare the original values
    * with those in the data source to check for conflicts. When there is a conflict,
    * the <code>RIOptimisticProvider</code> implementation, for example, throws a
    * <code>SyncProviderException</code> and does not write anything to the
    * data source.
    * <P>
    * An application may choose to catch the <code>SyncProviderException</code>
    * object and retrieve the <code>SyncResolver</code> object it contains.
    * The <code>SyncResolver</code> object lists the conflicts row by row and
    * sets a lock on the data source to avoid further conflicts while the
    * current conflicts are being resolved.
    * Further, for each conflict, it provides methods for examining the conflict
    * and setting the value that should be persisted in the data source.
    * After all conflicts have been resolved, an application must call the
    * <code>acceptChanges</code> method again to write resolved values to the
    * data source.  If all of the values in the data source are already the
    * values to be persisted, the method <code>acceptChanges</code> does nothing.
    * <P>
    * Some provider implementations may use locks to ensure that there are no
    * conflicts.  In such cases, it is guaranteed that the writer will succeed in
    * writing changes to the data source when the method <code>acceptChanges</code>
    * is called.  This method may be called immediately after the methods
    * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
    * have been called, but it is more efficient to call it only once after
    * all changes have been made so that only one connection needs to be
    * established.
    * <P>
    * Note: The <code>acceptChanges()</code> method will determine if the
    * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
    * to true, all updates in the synchronization are committed to the data
    * source. Otherwise, the application <b>must</b> explicity call the
    * <code>commit</code> or <code>rollback</code> methods as appropriate.
    *
    * @param con a standard JDBC <code>Connection</code> object
    * @throws SQLException if the cursor is on the insert row
    * @throws SyncProviderException if the underlying
    *           synchronization provider's writer fails to write the updates
    *           back to the data source
    * @see #acceptChanges()
    * @see javax.sql.RowSetWriter
    * @see javax.sql.rowset.spi.SyncFactory
    * @see javax.sql.rowset.spi.SyncProvider
    * @see javax.sql.rowset.spi.SyncProviderException
    * @see javax.sql.rowset.spi.SyncResolver
    */
    public void acceptChanges(Connection con) throws SyncProviderException;

   /**
    * Restores this <code>CachedRowSet</code> object to its original
    * value, that is, its value before the last set of changes. If there
    * have been no changes to the rowset or only one set of changes,
    * the original value is the value with which this <code>CachedRowSet</code> object
    * was populated; otherwise, the original value is
    * the value it had immediately before its current value.
    * <P>
    * When this method is called, a <code>CachedRowSet</code> implementation
    * must ensure that all updates, inserts, and deletes to the current
    * rowset instance are replaced by the previous values. In addition,
    * the cursor should be
    * reset to the first row and a <code>rowSetChanged</code> event
    * should be fired to notify all registered listeners.
    *
    * @throws SQLException if an error occurs rolling back the current value of
    *       this <code>CachedRowSet</code> object to its previous value
    * @see javax.sql.RowSetListener#rowSetChanged
    */
    public void restoreOriginal() throws SQLException;

   /**
    * Releases the current contents of this <code>CachedRowSet</code>
    * object and sends a <code>rowSetChanged</code> event to all
    * registered listeners. Any outstanding updates are discarded and
    * the rowset contains no rows after this method is called. There
    * are no interactions with the underlying data source, and any rowset
    * content, metadata, and content updates should be non-recoverable.
    * <P>
    * This <code>CachedRowSet</code> object should lock until its contents and
    * associated updates are fully cleared, thus preventing 'dirty' reads by
    * other components that hold a reference to this <code>RowSet</code> object.
    * In addition, the contents cannot be released
    * until all all components reading this <code>CachedRowSet</code> object
    * have completed their reads. This <code>CachedRowSet</code> object
    * should be returned to normal behavior after firing the
    * <code>rowSetChanged</code> event.
    * <P>
    * The metadata, including JDBC properties and Synchronization SPI
    * properties, are maintained for future use. It is important that
    * properties such as the <code>command</code> property be
    * relevant to the originating data source from which this <code>CachedRowSet</code>
    * object was originally established.
    * <P>
    * This method empties a rowset, as opposed to the <code>close</code> method,
    * which marks the entire rowset as recoverable to allow the garbage collector
    * the rowset's Java VM resources.
    *
    * @throws SQLException if an error occurs flushing the contents of this
    *           <code>CachedRowSet</code> object
    * @see javax.sql.RowSetListener#rowSetChanged
    * @see java.sql.ResultSet#close
    */
    public void release() throws SQLException;

   /**
    * Cancels the deletion of the current row and notifies listeners that
    * a row has changed. After this method is called, the current row is
    * no longer marked for deletion. This method can be called at any
    * time during the lifetime of the rowset.
    * <P>
    * In addition, multiple cancellations of row deletions can be made
    * by adjusting the position of the cursor using any of the cursor
    * position control methods such as:
    * <ul>
    * <li><code>CachedRowSet.absolute</code>
    * <li><code>CachedRowSet.first</code>
    * <li><code>CachedRowSet.last</code>
    * </ul>
    *
    * @throws SQLException if (1) the current row has not been deleted or
    * (2) the cursor is on the insert row, before the first row, or
    * after the last row
    * @see javax.sql.rowset.CachedRowSet#undoInsert
    * @see java.sql.ResultSet#cancelRowUpdates
    */
    public void undoDelete() throws SQLException;

   /**
    * Immediately removes the current row from this <code>CachedRowSet</code>
    * object if the row has been inserted, and also notifies listeners that a
    * row has changed. This method can be called at any time during the
    * lifetime of a rowset and assuming the current row is within
    * the exception limitations (see below), it cancels the row insertion
    * of the current row.
    * <P>
    * In addition, multiple cancellations of row insertions can be made
    * by adjusting the position of the cursor using any of the cursor
    * position control methods such as:
    * <ul>
    * <li><code>CachedRowSet.absolute</code>
    * <li><code>CachedRowSet.first</code>
    * <li><code>CachedRowSet.last</code>
    * </ul>
    *
    * @throws SQLException if (1) the current row has not been inserted or (2)
    * the cursor is before the first row, after the last row, or on the
    * insert row
    * @see javax.sql.rowset.CachedRowSet#undoDelete
    * @see java.sql.ResultSet#cancelRowUpdates
    */
    public void undoInsert() throws SQLException;


   /**
    * Immediately reverses the last update operation if the
    * row has been modified. This method can be
    * called to reverse updates on all columns until all updates in a row have
    * been rolled back to their state just prior to the last synchronization
    * (<code>acceptChanges</code>) or population. This method may also be called
    * while performing updates to the insert row.
    * <P>
    * <code>undoUpdate</code> may be called at any time during the lifetime of a
    * rowset; however, after a synchronization has occurred, this method has no
    * effect until further modification to the rowset data has occurred.
    *
    * @throws SQLException if the cursor is before the first row or after the last
    *     row in in this <code>CachedRowSet</code> object
    * @see #undoDelete
    * @see #undoInsert
    * @see java.sql.ResultSet#cancelRowUpdates
    */
    public void undoUpdate() throws SQLException;

   /**
    * Indicates whether the designated column in the current row of this
    * <code>CachedRowSet</code> object has been updated.
    *
    * @param idx an <code>int</code> identifying the column to be checked for updates
    * @return <code>true</code> if the designated column has been visibly updated;
    *           <code>false</code> otherwise
    * @throws SQLException if the cursor is on the insert row, before the first row,
    *       or after the last row
    * @see java.sql.DatabaseMetaData#updatesAreDetected
    */
    public boolean columnUpdated(int idx) throws SQLException;


   /**
    * Indicates whether the designated column in the current row of this
    * <code>CachedRowSet</code> object has been updated.
    *
    * @param columnName a <code>String</code> object giving the name of the
    *        column to be checked for updates
    * @return <code>true</code> if the column has been visibly updated;
    *           <code>false</code> otherwise
    * @throws SQLException if the cursor is on the insert row, before the first row,
    *       or after the last row
    * @see java.sql.DatabaseMetaData#updatesAreDetected
    */
    public boolean columnUpdated(String columnName) throws SQLException;

   /**
    * Converts this <code>CachedRowSet</code> object to a <code>Collection</code>
    * object that contains all of this <code>CachedRowSet</code> object's data.
    * Implementations have some latitude in
    * how they can represent this <code>Collection</code> object because of the
    * abstract nature of the <code>Collection</code> framework.
    * Each row must be fully represented in either a
    * general purpose <code>Collection</code> implementation or a specialized
    * <code>Collection</code> implementation, such as a <code>TreeMap</code>
    * object or a <code>Vector</code> object.
    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
    * in the Java programming language.
    * <P>
    * The standard reference implementation for the <code>CachedRowSet</code>
    * interface uses a <code>TreeMap</code> object for the rowset, with the
    * values in each row being contained in  <code>Vector</code> objects. It is
    * expected that most implementations will do the same.
    * <P>
    * The <code>TreeMap</code> type of collection guarantees that the map will be in
    * ascending key order, sorted according to the natural order for the
    * key's class.
    * Each key references a <code>Vector</code> object that corresponds to one
    * row of a <code>RowSet</code> object. Therefore, the size of each
    * <code>Vector</code> object  must be exactly equal to the number of
    * columns in the <code>RowSet</code> object.
    * The key used by the <code>TreeMap</code> collection is determined by the
    * implementation, which may choose to leverage a set key that is
    * available within the internal <code>RowSet</code> tabular structure by
    * virtue of a key already set either on the <code>RowSet</code> object
    * itself or on the underlying SQL data.
    * <P>
    *
    * @return a <code>Collection</code> object that contains the values in
    *           each row in this <code>CachedRowSet</code> object
    * @throws SQLException if an error occurs generating the collection
    * @see #toCollection(int)
    * @see #toCollection(String)
    */
    public Collection<?> toCollection() throws SQLException;

   /**
    * Converts the designated column in this <code>CachedRowSet</code> object
    * to a <code>Collection</code> object. Implementations have some latitude in
    * how they can represent this <code>Collection</code> object because of the
    * abstract nature of the <code>Collection</code> framework.
    * Each column value should be fully represented in either a
    * general purpose <code>Collection</code> implementation or a specialized
    * <code>Collection</code> implementation, such as a <code>Vector</code> object.
    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
    * in the Java programming language.
    * <P>
    * The standard reference implementation uses a <code>Vector</code> object
    * to contain the column values, and it is expected
    * that most implementations will do the same. If a <code>Vector</code> object
    * is used, it size must be exactly equal to the number of rows
    * in this <code>CachedRowSet</code> object.
    *
    * @param column an <code>int</code> indicating the column whose values
    *        are to be represented in a <code>Collection</code> object
    * @return a <code>Collection</code> object that contains the values
    *           stored in the specified column of this <code>CachedRowSet</code>
    *           object
    * @throws SQLException if an error occurs generating the collection or
    *           an invalid column id is provided
    * @see #toCollection
    * @see #toCollection(String)
    */
    public Collection<?> toCollection(int column) throws SQLException;

   /**
    * Converts the designated column in this <code>CachedRowSet</code> object
    * to a <code>Collection</code> object. Implementations have some latitude in
    * how they can represent this <code>Collection</code> object because of the
    * abstract nature of the <code>Collection</code> framework.
    * Each column value should be fully represented in either a
    * general purpose <code>Collection</code> implementation or a specialized
    * <code>Collection</code> implementation, such as a <code>Vector</code> object.
    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
    * in the Java programming language.
    * <P>
    * The standard reference implementation uses a <code>Vector</code> object
    * to contain the column values, and it is expected
    * that most implementations will do the same. If a <code>Vector</code> object
    * is used, it size must be exactly equal to the number of rows
    * in this <code>CachedRowSet</code> object.
    *
    * @param column a <code>String</code> object giving the name of the
    *        column whose values are to be represented in a collection
    * @return a <code>Collection</code> object that contains the values
    *           stored in the specified column of this <code>CachedRowSet</code>
    *           object
    * @throws SQLException if an error occurs generating the collection or
    *           an invalid column id is provided
    * @see #toCollection
    * @see #toCollection(int)
    */
    public Collection<?> toCollection(String column) throws SQLException;

   /**
    * Retrieves the <code>SyncProvider</code> implementation for this
    * <code>CachedRowSet</code> object. Internally, this method is used by a rowset
    * to trigger read or write actions between the rowset
    * and the data source. For example, a rowset may need to get a handle
    * on the the rowset reader (<code>RowSetReader</code> object) from the
    * <code>SyncProvider</code> to allow the rowset to be populated.
    * <pre>
    *     RowSetReader rowsetReader = null;
    *     SyncProvider provider =
    *         SyncFactory.getInstance("javax.sql.rowset.provider.RIOptimisticProvider");
    *         if (provider instanceof RIOptimisticProvider) {
    *             rowsetReader = provider.getRowSetReader();
    *         }
    * </pre>
    * Assuming <i>rowsetReader</i> is a private, accessible field within
    * the rowset implementation, when an application calls the <code>execute</code>
    * method, it in turn calls on the reader's <code>readData</code> method
    * to populate the <code>RowSet</code> object.
    *<pre>
    *     rowsetReader.readData((RowSetInternal)this);
    * </pre>
    * <P>
    * In addition, an application can use the <code>SyncProvider</code> object
    * returned by this method to call methods that return information about the
    * <code>SyncProvider</code> object, including information about the
    * vendor, version, provider identification, synchronization grade, and locks
    * it currently has set.
    *
    * @return the <code>SyncProvider</code> object that was set when the rowset
    *      was instantiated, or if none was was set, the default provider
    * @throws SQLException if an error occurs while returning the
    *           <code>SyncProvider</code> object
    * @see #setSyncProvider
    */
    public SyncProvider getSyncProvider() throws SQLException;

   /**
    * Sets the <code>SyncProvider</code> objec for this <code>CachedRowSet</code>
    * object to the one specified.  This method
    * allows the <code>SyncProvider</code> object to be reset.
    * <P>
    * A <code>CachedRowSet</code> implementation should always be instantiated
    * with an available <code>SyncProvider</code> mechanism, but there are
    * cases where resetting the <code>SyncProvider</code> object is desirable
    * or necessary. For example, an application might want to use the default
    * <code>SyncProvider</code> object for a time and then choose to use a provider
    * that has more recently become available and better fits its needs.
    * <P>
    * Resetting the <code>SyncProvider</code> object causes the
    * <code>RowSet</code> object to request a new <code>SyncProvider</code> implementation
    * from the <code>SyncFactory</code>. This has the effect of resetting
    * all previous connections and relationships with the originating
    * data source and can potentially drastically change the synchronization
    * behavior of a disconnected rowset.
    *
    * @param provider a <code>String</code> object giving the fully qualified class
    *        name of a <code>SyncProvider</code> implementation
    * @throws SQLException if an error occurs while attempting to reset the
    *           <code>SyncProvider</code> implementation
    * @see #getSyncProvider
    */
    public void setSyncProvider(String provider) throws SQLException;

   /**
    * Returns the number of rows in this <code>CachedRowSet</code>
    * object.
    *
    * @return number of rows in the rowset
    */
    public int size();

   /**
    * Sets the metadata for this <code>CachedRowSet</code> object with
    * the given <code>RowSetMetaData</code> object. When a
    * <code>RowSetReader</code> object is reading the contents of a rowset,
    * it creates a <code>RowSetMetaData</code> object and initializes
    * it using the methods in the <code>RowSetMetaData</code> implementation.
    * The reference implementation uses the <code>RowSetMetaDataImpl</code>
    * class. When the reader has completed reading the rowset contents,
    * this method is called internally to pass the <code>RowSetMetaData</code>
    * object to the rowset.
    *
    * @param md a <code>RowSetMetaData</code> object containing
    *           metadata about the columns in this <code>CachedRowSet</code> object
    * @throws SQLException if invalid metadata is supplied to the
    *           rowset
    */
    public void setMetaData(RowSetMetaData md) throws SQLException;

   /**
    * Returns a <code>ResultSet</code> object containing the original value of this
    * <code>CachedRowSet</code> object.
    * <P>
    * The cursor for the <code>ResultSet</code>
    * object should be positioned before the first row.
    * In addition, the returned <code>ResultSet</code> object should have the following
    * properties:
    * <UL>
    * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
    * <LI>ResultSet.CONCUR_UPDATABLE
    * </UL>
    * <P>
    * The original value for a <code>RowSet</code> object is the value it had before
    * the last synchronization with the underlying data source.  If there have been
    * no synchronizations, the original value will be the value with which the
    * <code>RowSet</code> object was populated.  This method is called internally
    * when an aplication calls the method <code>acceptChanges</code> and the
    * <code>SyncProvider</code> object has been implemented to check for conflicts.
    * If this is the case, the writer compares the original value with the value
    * currently in the data source to check for conflicts.
    *
    * @return a <code>ResultSet</code> object that contains the original value for
    *         this <code>CachedRowSet</code> object
    * @throws SQLException if an error occurs producing the
    *           <code>ResultSet</code> object
    */
   public ResultSet getOriginal() throws SQLException;

   /**
    * Returns a <code>ResultSet</code> object containing the original value for the
    * current row only of this <code>CachedRowSet</code> object.
    * <P>
    * The cursor for the <code>ResultSet</code>
    * object should be positioned before the first row.
    * In addition, the returned <code>ResultSet</code> object should have the following
    * properties:
    * <UL>
    * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
    * <LI>ResultSet.CONCUR_UPDATABLE
    * </UL>
    *
    * @return the original result set of the row
    * @throws SQLException if there is no current row
    * @see #setOriginalRow
    */
    public ResultSet getOriginalRow() throws SQLException;

   /**
    * Sets the current row in this <code>CachedRowSet</code> object as the original
    * row.
    * <P>
    * This method is called internally after the any modified values in the current
    * row have been synchronized with the data source. The current row must be tagged
    * as no longer inserted, deleted or updated.
    * <P>
    * A call to <code>setOriginalRow</code> is irreversible.
    *
    * @throws SQLException if there is no current row or an error is
    *           encountered resetting the contents of the original row
    * @see #getOriginalRow
    */
    public void setOriginalRow() throws SQLException;

   /**
    * Returns an identifier for the object (table) that was used to
    * create this <code>CachedRowSet</code> object. This name may be set on multiple occasions,
    * and the specification imposes no limits on how many times this
    * may occur or whether standard implementations should keep track
    * of previous table names.
    *
    * @return a <code>String</code> object giving the name of the table that is the
    *         source of data for this <code>CachedRowSet</code> object or <code>null</code>
    *         if no name has been set for the table
    * @throws SQLException if an error is encountered returning the table name
    * @see javax.sql.RowSetMetaData#getTableName
    */
    public String getTableName() throws SQLException;

   /**
    * Sets the identifier for the table from which this <code>CachedRowSet</code>
    * object was derived to the given table name. The writer uses this name to
    * determine which table to use when comparing the values in the data source with the
    * <code>CachedRowSet</code> object's values during a synchronization attempt.
    * The table identifier also indicates where modified values from this
    * <code>CachedRowSet</code> object should be written.
    * <P>
    * The implementation of this <code>CachedRowSet</code> object may obtain the
    * the name internally from the <code>RowSetMetaDataImpl</code> object.
    *
    * @param tabName a <code>String</code> object identifying the table from which this
             <code>CachedRowSet</code> object was derived; cannot be <code>null</code>
    *         but may be an empty string
    * @throws SQLException if an error is encountered naming the table or
    *     <i>tabName</i> is <code>null</code>
    * @see javax.sql.RowSetMetaData#setTableName
    * @see javax.sql.RowSetWriter
    * @see javax.sql.rowset.spi.SyncProvider
    */
   public void setTableName(String tabName) throws SQLException;

   /**
    * Returns an array containing one or more column numbers indicating the columns
    * that form a key that uniquely
    * identifies a row in this <code>CachedRowSet</code> object.
    *
    * @return an array containing the column number or numbers that indicate which columns
    *       constitute a primary key
    *       for a row in this <code>CachedRowSet</code> object. This array should be
    *       empty if no columns are representative of a primary key.
    * @throws SQLException if this <code>CachedRowSet</code> object is empty
    * @see #setKeyColumns
    * @see Joinable#getMatchColumnIndexes
    * @see Joinable#getMatchColumnNames
    */
    public int[] getKeyColumns() throws SQLException;

   /**
    * Sets this <code>CachedRowSet</code> object's <code>keyCols</code>
    * field with the given array of column numbers, which forms a key
    * for uniquely identifying a row in this <code>CachedRowSet</code> object.
    * <p>
    * If a <code>CachedRowSet</code> object becomes part of a <code>JoinRowSet</code>
    * object, the keys defined by this method and the resulting constraints are
    * maintained if the columns designated as key columns also become match
    * columns.
    *
    * @param keys an array of <code>int</code> indicating the columns that form
    *        a primary key for this <code>CachedRowSet</code> object; every
    *        element in the array must be greater than <code>0</code> and
    *        less than or equal to the number of columns in this rowset
    * @throws SQLException if any of the numbers in the given array
    *            are not valid for this rowset
    * @see #getKeyColumns
    * @see Joinable#setMatchColumn(String)
    * @see Joinable#setMatchColumn(int)

    */
    public void setKeyColumns(int[] keys) throws SQLException;


   /**
    * Returns a new <code>RowSet</code> object backed by the same data as
    * that of this <code>CachedRowSet</code> object. In effect, both
    * <code>CachedRowSet</code> objects have a cursor over the same data.
    * As a result, any changes made by a duplicate are visible to the original
    * and to any other duplicates, just as a change made by the original is visible
    * to all of its duplicates. If a duplicate calls a method that changes the
    * underlying data, the method it calls notifies all registered listeners
    * just as it would when it is called by the original <code>CachedRowSet</code>
    * object.
    * <P>
    * In addition, any <code>RowSet</code> object
    * created by this method will have the same properties as this
    * <code>CachedRowSet</code> object. For example, if this <code>CachedRowSet</code>
    * object is read-only, all of its duplicates will also be read-only. If it is
    * changed to be updatable, the duplicates also become updatable.
    * <P>
    * NOTE: If multiple threads access <code>RowSet</code> objects created from
    * the <code>createShared()</code> method, the following behavior is specified
    * to preserve shared data integrity: reads and writes of all
    * shared <code>RowSet</code> objects should be made serially between each
    * object and the single underlying tabular structure.
    *
    * @return a new shared <code>RowSet</code> object that has the same properties
    *         as this <code>CachedRowSet</code> object and that has a cursor over
    *         the same data
    * @throws SQLException if an error occurs or cloning is not
    *           supported in the underlying platform
    * @see javax.sql.RowSetEvent
    * @see javax.sql.RowSetListener
    */
    public RowSet createShared() throws SQLException;

   /**
    * Creates a <code>RowSet</code> object that is a deep copy of the data in
    * this <code>CachedRowSet</code> object. In contrast to
    * the <code>RowSet</code> object generated from a <code>createShared</code>
    * call, updates made to the copy of the original <code>RowSet</code> object
    * must not be visible to the original <code>RowSet</code> object. Also, any
    * event listeners that are registered with the original
    * <code>RowSet</code> must not have scope over the new
    * <code>RowSet</code> copies. In addition, any constraint restrictions
    * established must be maintained.
    *
    * @return a new <code>RowSet</code> object that is a deep copy
    *         of this <code>CachedRowSet</code> object and is
    *         completely independent of this <code>CachedRowSet</code> object
    * @throws SQLException if an error occurs in generating the copy of
    *         the of this <code>CachedRowSet</code> object
    * @see #createShared
    * @see #createCopySchema
    * @see #createCopyNoConstraints
    * @see javax.sql.RowSetEvent
    * @see javax.sql.RowSetListener
    */
    public CachedRowSet createCopy() throws SQLException;

    /**
     * Creates a <code>CachedRowSet</code> object that is an empty copy of this
     * <code>CachedRowSet</code> object.  The copy
     * must not contain any contents but only represent the table
     * structure of the original <code>CachedRowSet</code> object. In addition, primary
     * or foreign key constraints set in the originating <code>CachedRowSet</code> object must
     * be equally enforced in the new empty <code>CachedRowSet</code> object.
     * In contrast to
     * the <code>RowSet</code> object generated from a <code>createShared</code> method
     * call, updates made to a copy of this <code>CachedRowSet</code> object with the
     * <code>createCopySchema</code> method must not be visible to it.
     * <P>
     * Applications can form a <code>WebRowSet</code> object from the <code>CachedRowSet</code>
     * object returned by this method in order
     * to export the <code>RowSet</code> schema definition to XML for future use.
     *
     * @throws SQLException if an error occurs in cloning the structure of this
     *         <code>CachedRowSet</code> object
     * @see #createShared
     * @see #createCopySchema
     * @see #createCopyNoConstraints
     * @see javax.sql.RowSetEvent
     * @see javax.sql.RowSetListener
     */
    public CachedRowSet createCopySchema() throws SQLException;

    /**
     * Creates a <code>CachedRowSet</code> object that is a deep copy of
     * this <code>CachedRowSet</code> object's data but is independent of it.
     * In contrast to
     * the <code>RowSet</code> object generated from a <code>createShared</code>
     * method call, updates made to a copy of this <code>CachedRowSet</code> object
     * must not be visible to it. Also, any
     * event listeners that are registered with this
     * <code>CachedRowSet</code> object must not have scope over the new
     * <code>RowSet</code> object. In addition, any constraint restrictions
     * established for this <code>CachedRowSet</code> object must <b>not</b> be maintained
     * in the copy.
     *
     * @return a new <code>CachedRowSet</code> object that is a deep copy
     *        of this <code>CachedRowSet</code> object and is
     *        completely independent of this  <code>CachedRowSet</code> object
     * @throws SQLException if an error occurs in generating the copy of
     *        the of this <code>CachedRowSet</code> object
     * @see #createCopy
     * @see #createShared
     * @see #createCopySchema
     * @see javax.sql.RowSetEvent
     * @see javax.sql.RowSetListener
     */
    public CachedRowSet createCopyNoConstraints() throws SQLException;

    /**
     * Retrieves the first warning reported by calls on this <code>RowSet</code> object.
     * Subsequent warnings on this <code>RowSet</code> object will be chained to the
     * <code>RowSetWarning</code> object that this method returns.
     *
     * The warning chain is automatically cleared each time a new row is read.
     * This method may not be called on a RowSet object that has been closed;
     * doing so will cause a <code>SQLException</code> to be thrown.
     *
     * @return RowSetWarning the first <code>RowSetWarning</code>
     * object reported or null if there are none
     * @throws SQLException if this method is called on a closed RowSet
     * @see RowSetWarning
     */
    public RowSetWarning getRowSetWarnings() throws SQLException;

    /**
     * Retrieves a <code>boolean</code> indicating whether rows marked
     * for deletion appear in the set of current rows. If <code>true</code> is
     * returned, deleted rows are visible with the current rows. If
     * <code>false</code> is returned, rows are not visible with the set of
     * current rows. The default value is <code>false</code>.
     * <P>
     * Standard rowset implementations may choose to restrict this behavior
     * due to security considerations or to better fit certain deployment
     * scenarios. This is left as implementation defined and does not
     * represent standard behavior.
     * <P>
     * Note: Allowing deleted rows to remain visible complicates the behavior
     * of some standard JDBC <code>RowSet</code> Implementations methods.
     * However, most rowset users can simply ignore this extra detail because
     * only very specialized applications will likely want to take advantage of
     * this feature.
     *
     * @return <code>true</code> if deleted rows are visible;
     *         <code>false</code> otherwise
     * @throws SQLException if a rowset implementation is unable to
     *          to determine whether rows marked for deletion are visible
     * @see #setShowDeleted
     */
    public boolean getShowDeleted() throws SQLException;

    /**
     * Sets the property <code>showDeleted</code> to the given
     * <code>boolean</code> value, which determines whether
     * rows marked for deletion appear in the set of current rows.
     * If the value is set to <code>true</code>, deleted rows are immediately
     * visible with the set of current rows. If the value is set to
     * <code>false</code>, the deleted rows are set as invisible with the
     * current set of rows.
     * <P>
     * Standard rowset implementations may choose to restrict this behavior
     * due to security considerations or to better fit certain deployment
     * scenarios. This is left as implementations defined and does not
     * represent standard behavior.
     *
     * @param b <code>true</code> if deleted rows should be shown;
     *              <code>false</code> otherwise
     * @exception SQLException if a rowset implementation is unable to
     *          to reset whether deleted rows should be visible
     * @see #getShowDeleted
     */
    public void setShowDeleted(boolean b) throws SQLException;

    /**
     * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
     * a <code>Connection</code> object from the <code>ResultSet</code> or JDBC
     * properties passed to it's constructors. This method wraps the
     * <code>Connection</code> commit method to allow flexible
     * auto commit or non auto commit transactional control support.
     * <p>
     * Makes all changes that are performed by the <code>acceptChanges()</code>
     * method since the previous commit/rollback permanent. This method should
     * be used only when auto-commit mode has been disabled.
     *
     * @throws SQLException if a database access error occurs or this
     * Connection object within this <code>CachedRowSet</code> is in auto-commit mode
     * @see java.sql.Connection#setAutoCommit
     */
    public void commit() throws SQLException;

    /**
     * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
     * a <code>Connection</code> object from the original <code>ResultSet</code>
     * or JDBC properties passed to it.
     * <p>
     * Undoes all changes made in the current transaction.  This method
     * should be used only when auto-commit mode has been disabled.
     *
     * @throws SQLException if a database access error occurs or this Connection
     * object within this <code>CachedRowSet</code> is in auto-commit mode.
     */
    public void rollback() throws SQLException;

    /**
     * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
     * a <code>Connection</code> object from the original <code>ResultSet</code>
     * or JDBC properties passed to it.
     * <p>
     * Undoes all changes made in the current transaction back to the last
     * <code>Savepoint</code> transaction marker. This method should be used only
     * when auto-commit mode has been disabled.
     *
     * @param s A <code>Savepoint</code> transaction marker
     * @throws SQLException if a database access error occurs or this Connection
     * object within this <code>CachedRowSet</code> is in auto-commit mode.
     */
    public void rollback(Savepoint s) throws SQLException;

    /**
     * Causes the <code>CachedRowSet</code> object's <code>SyncProvider</code>
     * to commit the changes when <code>acceptChanges()</code> is called. If
     * set to false, the changes will <b>not</b> be committed until one of the
     * <code>CachedRowSet</code> interface transaction methods is called.
     *
     * @see #commit
     * @see #rollback
     */
    public static final boolean COMMIT_ON_ACCEPT_CHANGES = true;

    /**
     * Notifies registered listeners that a RowSet object in the given RowSetEvent
     * object has populated a number of additional rows. The <code>numRows</code> parameter
     * ensures that this event will only be fired every <code>numRow</code>.
     * <p>
     * The source of the event can be retrieved with the method event.getSource.
     *
     * @param event a <code>RowSetEvent</code> object that contains the
     *     <code>RowSet</code> object that is the source of the events
     * @param numRows when populating, the number of rows interval on which the
     *     <code>CachedRowSet</code> populated should fire; the default value
     *     is zero; cannot be less than <code>fetchSize</code> or zero
     */
    public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException;

    /**
     * Populates this <code>CachedRowSet</code> object with data from
     * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code>
     * method, an additional parameter is provided to allow starting position within
     * the <code>ResultSet</code> from where to populate the CachedRowSet
     * instance.
     * <P>
     * This method can be used as an alternative to the <code>execute</code> method when an
     * application has a connection to an open <code>ResultSet</code> object.
     * Using the method <code>populate</code> can be more efficient than using
     * the version of the <code>execute</code> method that takes no parameters
     * because it does not open a new connection and re-execute this
     * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
     *  method is more a matter of convenience when compared to using the version
     * of <code>execute</code> that takes a <code>ResultSet</code> object.
     *
     * @param startRow the position in the <code>ResultSet</code> from where to start
     *                populating the records in this <code>CachedRowSet</code>
     * @param rs the <code>ResultSet</code> object containing the data
     *          to be read into this <code>CachedRowSet</code> object
     * @throws SQLException if a null <code>ResultSet</code> object is supplied
     *          or this <code>CachedRowSet</code> object cannot
     *          retrieve the associated <code>ResultSetMetaData</code> object
     * @see #execute
     * @see #populate(ResultSet)
     * @see java.sql.ResultSet
     * @see java.sql.ResultSetMetaData
    */
    public void populate(ResultSet rs, int startRow) throws SQLException;

    /**
     * Sets the <code>CachedRowSet</code> object's page-size. A <code>CachedRowSet</code>
     * may be configured to populate itself in page-size sized batches of rows. When
     * either <code>populate()</code> or <code>execute()</code> are called, the
     * <code>CachedRowSet</code> fetches an additional page according to the
     * original SQL query used to populate the RowSet.
     *
     * @param size the page-size of the <code>CachedRowSet</code>
     * @throws SQLException if an error occurs setting the <code>CachedRowSet</code>
     *      page size or if the page size is less than 0.
     */
    public void setPageSize(int size) throws SQLException;

    /**
     * Returns the page-size for the <code>CachedRowSet</code> object
     *
     * @return an <code>int</code> page size
     */
    public int getPageSize();

    /**
     * Increments the current page of the <code>CachedRowSet</code>. This causes
     * the <code>CachedRowSet</code> implementation to fetch the next page-size
     * rows and populate the RowSet, if remaining rows remain within scope of the
     * original SQL query used to populated the RowSet.
     *
     * @return true if more pages exist; false if this is the last page
     * @throws SQLException if an error occurs fetching the next page, or if this
     *     method is called prematurely before populate or execute.
     */
    public boolean nextPage() throws SQLException;

    /**
     * Decrements the current page of the <code>CachedRowSet</code>. This causes
     * the <code>CachedRowSet</code> implementation to fetch the previous page-size
     * rows and populate the RowSet. The amount of rows returned in the previous
     * page must always remain within scope of the original SQL query used to
     * populate the RowSet.
     *
     * @return true if the previous page is successfully retrieved; false if this
     *     is the first page.
     * @throws SQLException if an error occurs fetching the previous page, or if
     *     this method is called prematurely before populate or execute.
     */
    public boolean previousPage() throws SQLException;

}
