KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > sql > rowset > CachedRowSet


1 /*
2  * @(#)CachedRowSet.java 1.7 04/05/29
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.sql.rowset;
9
10 import java.sql.*;
11 import javax.sql.*;
12 import javax.naming.*;
13 import java.io.*;
14 import java.math.*;
15 import java.util.*;
16
17 import javax.sql.rowset.spi.*;
18
19 /**
20  * The interface that all standard implementations of
21  * <code>CachedRowSet</code> must implement.
22  * <P>
23  * The reference implementation of the <code>CachedRowSet</code> interface provided
24  * by Sun Microsystems is a standard implementation. Developers may use this implementation
25  * just as it is, they may extend it, or they may choose to write their own implementations
26  * of this interface.
27  * <P>
28  * A <code>CachedRowSet</code> object is a container for rows of data
29  * that caches its rows in memory, which makes it possible to operate without always being
30  * connected to its data source. Further, it is a
31  * JavaBeans<sup><font size=-2>TM</font></sup> component and is scrollable,
32  * updatable, and serializable. A <code>CachedRowSet</code> object typically
33  * contains rows from a result set, but it can also contain rows from any file
34  * with a tabular format, such as a spread sheet. The reference implementation
35  * supports getting data only from a <code>ResultSet</code> object, but
36  * developers can extend the <code>SyncProvider</code> implementations to provide
37  * access to other tabular data sources.
38  * <P>
39  * An application can modify the data in a <code>CachedRowSet</code> object, and
40  * those modifications can then be propagated back to the source of the data.
41  * <P>
42  * A <code>CachedRowSet</code> object is a <i>disconnected</i> rowset, which means
43  * that it makes use of a connection to its data source only briefly. It connects to its
44  * data source while it is reading data to populate itself with rows and again
45  * while it is propagating changes back to its underlying data source. The rest
46  * of the time, a <code>CachedRowSet</code> object is disconnected, including
47  * while its data is being modified. Being disconnected makes a <code>RowSet</code>
48  * object much leaner and therefore much easier to pass to another component. For
49  * example, a disconnected <code>RowSet</code> object can be serialized and passed
50  * over the wire to a thin client such as a personal digital assistant (PDA).
51  * <P>
52  *
53  * <h3>1.0 Creating a <code>CachedRowSet</code> Object</h3>
54  * The following line of code uses the default constructor for
55  * <code>CachedRowSet</code>
56  * supplied in the reference implementation (RI) to create a default
57  * <code>CachedRowSet</code> object.
58  * <PRE>
59  * CachedRowSetImpl crs = new CachedRowSetImpl();
60  * </PRE>
61  * This new <code>CachedRowSet</code> object will have its properties set to the
62  * default properties of a <code>BaseRowSet</code> object, and, in addition, it will
63  * have an <code>RIOptimisticProvider</code> object as its synchronization provider.
64  * <code>RIOptimisticProvider</code>, one of two <code>SyncProvider</code>
65  * implementations included in the RI, is the default provider that the
66  * <code>SyncFactory</code> singleton will supply when no synchronization
67  * provider is specified.
68  * <P>
69  * A <code>SyncProvider</code> object provides a <code>CachedRowSet</code> object
70  * with a reader (a <code>RowSetReader</code> object) for reading data from a
71  * data source to populate itself with data. A reader can be implemented to read
72  * data from a <code>ResultSet</code> object or from a file with a tabular format.
73  * A <code>SyncProvider</code> object also provides
74  * a writer (a <code>RowSetWriter</code> object) for synchronizing any
75  * modifications to the <code>CachedRowSet</code> object's data made while it was
76  * disconnected with the data in the underlying data source.
77  * <P>
78  * A writer can be implemented to exercise various degrees of care in checking
79  * for conflicts and in avoiding them.
80  * (A conflict occurs when a value in the data source has been changed after
81  * the rowset populated itself with that value.)
82  * The <code>RIOptimisticProvider</code> implementation assumes there will be
83  * few or no conflicts and therefore sets no locks. It updates the data source
84  * with values from the <code>CachedRowSet</code> object only if there are no
85  * conflicts.
86  * Other writers can be implemented so that they always write modified data to
87  * the data source, which can be accomplished either by not checking for conflicts
88  * or, on the other end of the spectrum, by setting locks sufficient to prevent data
89  * in the data source from being changed. Still other writer implementations can be
90  * somewhere in between.
91  * <P>
92  * A <code>CachedRowSet</code> object may use any
93  * <code>SyncProvider</code> implementation that has been registered
94  * with the <code>SyncFactory</code> singleton. An application
95  * can find out which <code>SyncProvider</code> implementations have been
96  * registered by calling the following line of code.
97  * <PRE>
98  * java.util.Enumeration providers = SyncFactory.getRegisteredProviders();
99  * </PRE>
100  * <P>
101  * There are two ways for a <code>CachedRowSet</code> object to specify which
102  * <code>SyncProvider</code> object it will use.
103  * <UL)
104  * <LI>Supplying the name of the implementation to the constructor<BR>
105  * The following line of code creates the <code>CachedRowSet</code>
106  * object <i>crs2</i> that is initialized with default values except that its
107  * <code>SyncProvider</code> object is the one specified.
108  * <PRE>
109  * CachedRowSetImpl crs2 = new CachedRowSetImpl(
110  * "com.fred.providers.HighAvailabilityProvider");
111  * </PRE>
112  * <LI>Setting the <code>SyncProvider</code> using the <code>CachedRowSet</code>
113  * method <code>setSyncProvider</code><BR>
114  * The following line of code resets the <code>SyncProvider</code> object
115  * for <i>crs</i>, the <code>CachedRowSet</code> object created with the
116  * default constructor.
117  * <PRE>
118  * crs.setSyncProvider("com.fred.providers.HighAvailabilityProvider");
119  * </PRE>
120  * </UL)
121  * See the comments for <code>SyncFactory</code> and <code>SyncProvider</code> for
122  * more details.
123  *
124  * <P>
125  * <h3>2.0 Retrieving Data from a <code>CachedRowSet</code> Object</h3>
126  * Data is retrieved from a <code>CachedRowSet</code> object by using the
127  * getter methods inherited from the <code>ResultSet</code>
128  * interface. The following examples, in which <code>crs</code> is a
129  * <code>CachedRowSet</code>
130  * object, demonstrate how to iterate through the rows, retrieving the column
131  * values in each row. The first example uses the version of the
132  * getter methods that take a column number; the second example
133  * uses the version that takes a column name. Column numbers are generally
134  * used when the <code>RowSet</code> object's command
135  * is of the form <code>SELECT * FROM TABLENAME</code>; column names are most
136  * commonly used when the command specifies columns by name.
137  * <PRE>
138  * while (crs.next()) {
139  * String name = crs.getString(1);
140  * int id = crs.getInt(2);
141  * Clob comment = crs.getClob(3);
142  * short dept = crs.getShort(4);
143  * System.out.println(name + " " + id + " " + comment + " " + dept);
144  * }
145  * </PRE>
146  *
147  * <PRE>
148  * while (crs.next()) {
149  * String name = crs.getString("NAME");
150  * int id = crs.getInt("ID");
151  * Clob comment = crs.getClob("COM");
152  * short dept = crs.getShort("DEPT");
153  * System.out.println(name + " " + id + " " + comment + " " + dept);
154  * }
155  * </PRE>
156  * <h4>2.1 Retrieving <code>RowSetMetaData</code></h4>
157  * An application can get information about the columns in a <code>CachedRowSet</code>
158  * object by calling <code>ResultSetMetaData</code> and <code>RowSetMetaData</code>
159  * methods on a <code>RowSetMetaData</code> object. The following code fragment,
160  * in which <i>crs</i> is a <code>CachedRowSet</code> object, illustrates the process.
161  * The first line creates a <code>RowSetMetaData</code> object with information
162  * about the columns in <i>crs</i>. The method <code>getMetaData</code>,
163  * inherited from the <code>ResultSet</code> interface, returns a
164  * <code>ResultSetMetaData</code> object, which is cast to a
165  * <code>RowSetMetaData</code> object before being assigned to the variable
166  * <i>rsmd</i>. The second line finds out how many columns <i>jrs</i> has, and
167  * the third line gets the JDBC type of values stored in the second column of
168  * <code>jrs</code>.
169  * <PRE>
170  * RowSetMetaData rsmd = (RowSetMetaData)crs.getMetaData();
171  * int count = rsmd.getColumnCount();
172  * int type = rsmd.getColumnType(2);
173  * </PRE>
174  * The <code>RowSetMetaData</code> interface differs from the
175  * <code>ResultSetMetaData</code> interface in two ways.
176  * <UL>
177  * <LI><i>It includes <code>setter</code> methods:</i> A <code>RowSet</code>
178  * object uses these methods internally when it is populated with data from a
179  * different <code>ResultSet</code> object.
180  * <P>
181  * <LI><i>It contains fewer <code>getter</code> methods:</i> Some
182  * <code>ResultSetMetaData</code> methods to not apply to a <code>RowSet</code>
183  * object. For example, methods retrieving whether a column value is writable
184  * or read only do not apply because all of a <code>RowSet</code> object's
185  * columns will be writable or read only, depending on whether the rowset is
186  * updatable or not.
187  * </UL>
188  * NOTE: In order to return a <code>RowSetMetaData</code> object, implementations must
189  * override the <code>getMetaData()</code> method defined in
190  * <code>java.sql.ResultSet</code> and return a <code>RowSetMetaData</code> object.
191  *
192  * <h3>3.0 Updating a <code>CachedRowSet</code> Object</h3>
193  * Updating a <code>CachedRowSet</code> object is similar to updating a
194  * <code>ResultSet</code> object, but because the rowset is not connected to
195  * its data source while it is being updated, it must take an additional step
196  * to effect changes in its underlying data source. After calling the method
197  * <code>updateRow</code> or <code>insertRow</code>, a
198  * <code>CachedRowSet</code>
199  * object must also call the method <code>acceptChanges</code> to have updates
200  * written to the data source. The following example, in which the cursor is
201  * on a row in the <code>CachedRowSet</code> object <i>crs</i>, shows
202  * the code required to update two column values in the current row and also
203  * update the <code>RowSet</code> object's underlying data source.
204  * <PRE>
205  * crs.updateShort(3, 58);
206  * crs.updateInt(4, 150000);
207  * crs.updateRow();
208  * crs.acceptChanges();
209  * </PRE>
210  * <P>
211  * The next example demonstrates moving to the insert row, building a new
212  * row on the insert row, inserting it into the rowset, and then calling the
213  * method <code>acceptChanges</code> to add the new row to the underlying data
214  * source. Note that as with the getter methods, the updater methods may take
215  * either a column index or a column name to designate the column being acted upon.
216  * <PRE>
217  * crs.moveToInsertRow();
218  * crs.updateString("Name", "Shakespeare");
219  * crs.updateInt("ID", 10098347);
220  * crs.updateShort("Age", 58);
221  * crs.updateInt("Sal", 150000);
222  * crs.insertRow();
223  * crs.moveToCurrentRow();
224  * crs.acceptChanges();
225  * </PRE>
226  * <P>
227  * NOTE: Where the <code>insertRow()</code> method inserts the contents of a
228  * <code>CachedRowSet</code> object's insert row is implementation-defined.
229  * The reference implementation for the <code>CachedRowSet</code> interface
230  * inserts a new row immediately following the current row, but it could be
231  * implemented to insert new rows in any number of other places.
232  * <P>
233  * Another thing to note about these examples is how they use the method
234  * <code>acceptChanges</code>. It is this method that propagates changes in
235  * a <code>CachedRowSet</code> object back to the underlying data source,
236  * calling on the <code>RowSet</code> object's writer internally to write
237  * changes to the data source. To do this, the writer has to incur the expense
238  * of establishing a connection with that data source. The
239  * preceding two code fragments call the method <code>acceptChanges</code>
240  * immediately after calling <code>updateRow</code> or <code>insertRow</code>.
241  * However, when there are multiple rows being changed, it is more efficient to call
242  * <code>acceptChanges</code> after all calls to <code>updateRow</code>
243  * and <code>insertRow</code> have been made. If <code>acceptChanges</code>
244  * is called only once, only one connection needs to be established.
245  * <P>
246  * <h3>4.0 Updating the Underlying Data Source</h3>
247  * When the method <code>acceptChanges</code> is executed, the
248  * <code>CachedRowSet</code> object's writer, a <code>RowSetWriterImpl</code>
249  * object, is called behind the scenes to write the changes made to the
250  * rowset to the underlying data source. The writer is implemented to make a
251  * connection to the data source and write updates to it.
252  * <P>
253  * A writer is made available through an implementation of the
254  * <code>SyncProvider</code> interface, as discussed in section 1,
255  * "Creating a <code>CachedRowSet</code> Object."
256  * The default reference implementation provider, <code>RIOptimisticProvider</code>,
257  * has its writer implemented to use an optimistic concurrency control
258  * mechanism. That is, it maintains no locks in the underlying database while
259  * the rowset is disconnected from the database and simply checks to see if there
260  * are any conflicts before writing data to the data source. If there are any
261  * conflicts, it does not write anything to the data source.
262  * <P>
263  * The reader/writer facility
264  * provided by the <code>SyncProvider</code> class is pluggable, allowing for the
265  * customization of data retrieval and updating. If a different concurrency
266  * control mechanism is desired, a different implementation of
267  * <code>SyncProvider</code> can be plugged in using the method
268  * <code>setSyncProvider</code>.
269  * <P>
270  * In order to use the optimistic concurrency control routine, the
271  * <code>RIOptismisticProvider</code> maintains both its current
272  * value and its original value (the value it had immediately preceding the
273  * current value). Note that if no changes have been made to the data in a
274  * <code>RowSet</code> object, its current values and its original values are the same,
275  * both being the values with which the <code>RowSet</code> object was initially
276  * populated. However, once any values in the <code>RowSet</code> object have been
277  * changed, the current values and the original values will be different, though at
278  * this stage, the original values are still the initial values. With any subsequent
279  * changes to data in a <code>RowSet</code> object, its original values and current
280  * values will still differ, but its original values will be the values that
281  * were previously the current values.
282  * <P>
283  * Keeping track of original values allows the writer to compare the <code>RowSet</code>
284  * object's original value with the value in the database. If the values in
285  * the database differ from the <code>RowSet</code> object's original values, which means that
286  * the values in the database have been changed, there is a conflict.
287  * Whether a writer checks for conflicts, what degree of checking it does, and how
288  * it handles conflicts all depend on how it is implemented.
289  * <P>
290  * <h3>5.0 Registering and Notifying Listeners</h3>
291  * Being JavaBeans components, all rowsets participate in the JavaBeans event
292  * model, inheriting methods for registering listeners and notifying them of
293  * changes from the <code>BaseRowSet</code> class. A listener for a
294  * <code>CachedRowSet</code> object is a component that wants to be notified
295  * whenever there is a change in the rowset. For example, if a
296  * <code>CachedRowSet</code> object contains the results of a query and
297  * those
298  * results are being displayed in, say, a table and a bar graph, the table and
299  * bar graph could be registered as listeners with the rowset so that they can
300  * update themselves to reflect changes. To become listeners, the table and
301  * bar graph classes must implement the <code>RowSetListener</code> interface.
302  * Then they can be added to the <Code>CachedRowSet</code> object's list of
303  * listeners, as is illustrated in the following lines of code.
304  * <PRE>
305  * crs.addRowSetListener(table);
306  * crs.addRowSetListener(barGraph);
307  * </PRE>
308  * Each <code>CachedRowSet</code> method that moves the cursor or changes
309  * data also notifies registered listeners of the changes, so
310  * <code>table</code> and <code>barGraph</code> will be notified when there is
311  * a change in <code>crs</code>.
312  * <P>
313  * <h3>6.0 Passing Data to Thin Clients</h3>
314  * One of the main reasons to use a <code>CachedRowSet</code> object is to
315  * pass data between different components of an application. Because it is
316  * serializable, a <code>CachedRowSet</code> object can be used, for example,
317  * to send the result of a query executed by an enterprise JavaBeans component
318  * running in a server environment over a network to a client running in a
319  * web browser.
320  * <P>
321  * While a <code>CachedRowSet</code> object is disconnected, it can be much
322  * leaner than a <code>ResultSet</code> object with the same data.
323  * As a result, it can be especially suitable for sending data to a thin client
324  * such as a PDA, where it would be inappropriate to use a JDBC driver
325  * due to resource limitations or security considerations.
326  * Thus, a <code>CachedRowSet</code> object provides a means to "get rows in"
327  * without the need to implement the full JDBC API.
328  * <P>
329  * <h3>7.0 Scrolling and Updating</h3>
330  * A second major use for <code>CachedRowSet</code> objects is to provide
331  * scrolling and updating for <code>ResultSet</code> objects that
332  * do not provide these capabilities themselves. In other words, a
333  * <code>CachedRowSet</code> object can be used to augment the
334  * capabilities of a JDBC technology-enabled driver (hereafter called a
335  * "JDBC driver") when the DBMS does not provide full support for scrolling and
336  * updating. To achieve the effect of making a non-scrollble and read-only
337  * <code>ResultSet</code> object scrollable and updatable, a programmer
338  * simply needs to create a <code>CachedRowSet</code> object populated
339  * with that <code>ResultSet</code> object's data. This is demonstrated
340  * in the following code fragment, where <code>stmt</code> is a
341  * <code>Statement</code> object.
342  * <PRE>
343  * ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES");
344  * CachedRowSetImpl crs = new CachedRowSetImpl();
345  * crs.populate(rs);
346  * </PRE>
347  * <P>
348  * The object <code>crs</code> now contains the data from the table
349  * <code>EMPLOYEES</code>, just as the object <code>rs</code> does.
350  * The difference is that the cursor for <code>crs</code> can be moved
351  * forward, backward, or to a particular row even if the cursor for
352  * <code>rs</code> can move only forward. In addition, <code>crs</code> is
353  * updatable even if <code>rs</code> is not because by default, a
354  * <code>CachedRowSet</code> object is both scrollable and updatable.
355  * <P>
356  * In summary, a <code>CachedRowSet</code> object can be thought of as simply
357  * a disconnected set of rows that are being cached outside of a data source.
358  * Being thin and serializable, it can easily be sent across a wire,
359  * and it is well suited to sending data to a thin client. However, a
360  * <code>CachedRowSet</code> object does have a limitation: It is limited in
361  * size by the amount of data it can store in memory at one time.
362  * <P>
363  * <h3>8.0 Getting Universal Data Access</h3>
364  * Another advantage of the <code>CachedRowSet</code> class is that it makes it
365  * possible to retrieve and store data from sources other than a relational
366  * database. The reader for a rowset can be implemented to read and populate
367  * its rowset with data from any tabular data source, including a spreadsheet
368  * or flat file.
369  * Because both a <code>CachedRowSet</code> object and its metadata can be
370  * created from scratch, a component that acts as a factory for rowsets
371  * can use this capability to create a rowset containing data from
372  * non-SQL data sources. Nevertheless, it is expected that most of the time,
373  * <code>CachedRowSet</code> objects will contain data that was fetched
374  * from an SQL database using the JDBC API.
375  * <P>
376  * <h3>9.0 Setting Properties</h3>
377  * All rowsets maintain a set of properties, which will usually be set using
378  * a tool. The number and kinds of properties a rowset has will vary,
379  * depending on what the rowset does and how it gets its data. For example,
380  * rowsets that get their data from a <code>ResultSet</code> object need to
381  * set the properties that are required for making a database connection.
382  * If a rowset uses the <code>DriverManager</code> facility to make a
383  * connection, it needs to set a property for the JDBC URL that identifies
384  * the appropriate driver, and it needs to set the properties that give the
385  * user name and password.
386  * If, on the other hand, the rowset uses a <code>DataSource</code> object
387  * to make the connection, which is the preferred method, it does not need to
388  * set the property for the JDBC URL. Instead, it needs to set
389  * properties for the logical name of the data source, for the user name,
390  * and for the password.
391  * <P>
392  * NOTE: In order to use a <code>DataSource</code> object for making a
393  * connection, the <code>DataSource</code> object must have been registered
394  * with a naming service that uses the Java Naming and Directory
395  * Interface<sup><font size=-2>TM</font></sup> (JNDI) API. This registration
396  * is usually done by a person acting in the capacity of a system
397  * administrator.
398  * <P>
399  * In order to be able to populate itself with data from a database, a rowset
400  * needs to set a command property. This property is a query that is a
401  * <code>PreparedStatement</code> object, which allows the query to have
402  * parameter placeholders that are set at run time, as opposed to design time.
403  * To set these placeholder parameters with values, a rowset provides
404  * setter methods for setting values of each data type,
405  * similar to the setter methods provided by the <code>PreparedStatement</code>
406  * interface.
407  * <P>
408  * The following code fragment illustrates how the <code>CachedRowSet</code>
409  * object <code>crs</code> might have its command property set. Note that if a
410  * tool is used to set properties, this is the code that the tool would use.
411  * <PRE>
412  * crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS " +
413  * "WHERE CREDIT_LIMIT > ? AND REGION = ?");
414  * </PRE>
415  * <P>
416  * The values that will be used to set the command's placeholder parameters are
417  * contained in the <code>RowSet</code> object's <code>params</code> field, which is a
418  * <code>Vector</code> object.
419  * The <code>CachedRowSet</code> class provides a set of setter
420  * methods for setting the elements in its <code>params</code> field. The
421  * following code fragment demonstrates setting the two parameters in the
422  * query from the previous example.
423  * <PRE>
424  * crs.setInt(1, 5000);
425  * crs.setString(2, "West");
426  * </PRE>
427  * <P>
428  * The <code>params</code> field now contains two elements, each of which is
429  * an array two elements long. The first element is the parameter number;
430  * the second is the value to be set.
431  * In this case, the first element of <code>params</code> is
432  * <code>1</code>, <code>5000</code>, and the second element is <code>2</code>,
433  * <code>"West"</code>. When an application calls the method
434  * <code>execute</code>, it will in turn call on this <code>RowSet</code> object's reader,
435  * which will in turn invoke its <code>readData</code> method. As part of
436  * its implementation, <code>readData</code> will get the values in
437  * <code>params</code> and use them to set the command's placeholder
438  * parameters.
439  * The following code fragment gives an idea of how the reader
440  * does this, after obtaining the <code>Connection</code> object
441  * <code>con</code>.
442  * <PRE>
443  * PreparedStatement pstmt = con.prepareStatement(crs.getCommand());
444  * reader.decodeParams();
445  * // decodeParams figures out which setter methods to use and does something
446  * // like the following:
447  * // for (i = 0; i < params.length; i++) {
448  * // pstmt.setObject(i + 1, params[i]);
449  * // }
450  * </PRE>
451  * <P>
452  * At this point, the command for <code>crs</code> is the query <code>"SELECT
453  * FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS WHERE CREDIT_LIMIT > 5000
454  * AND REGION = "West"</code>. After the <code>readData</code> method executes
455  * this command with the following line of code, it will have the data from
456  * <code>rs</code> with which to populate <code>crs</code>.
457  * <PRE>
458  * ResultSet rs = pstmt.executeQuery();
459  * </PRE>
460  * <P>
461  * The preceding code fragments give an idea of what goes on behind the
462  * scenes; they would not appear in an application, which would not invoke
463  * methods like <code>readData</code> and <code>decodeParams</code>.
464  * In contrast, the following code fragment shows what an application might do.
465  * It sets the rowset's command, sets the command's parameters, and executes
466  * the command. Simply by calling the <code>execute</code> method,
467  * <code>crs</code> populates itself with the requested data from the
468  * table <code>CUSTOMERS</code>.
469  * <PRE>
470  * crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS" +
471  * "WHERE CREDIT_LIMIT > ? AND REGION = ?");
472  * crs.setInt(1, 5000);
473  * crs.setString(2, "West");
474  * crs.execute();
475  * </PRE>
476  *
477  * <h3>10.0 Paging Data</h3>
478  * Because a <code>CachedRowSet</code> object stores data in memory,
479  * the amount of data that it can contain at any one
480  * time is determined by the amount of memory available. To get around this limitation,
481  * a <code>CachedRowSet</code> object can retrieve data from a <code>ResultSet</code>
482  * object in chunks of data, called <i>pages</i>. To take advantage of this mechanism,
483  * an application sets the number of rows to be included in a page using the method
484  * <code>setPageSize</code>. In other words, if the page size is set to five, a chunk
485  * of five rows of
486  * data will be fetched from the data source at one time. An application can also
487  * optionally set the maximum number of rows that may be fetched at one time. If the
488  * maximum number of rows is set to zero, or no maximum number of rows is set, there is
489  * no limit to the number of rows that may be fetched at a time.
490  * <P>
491  * After properties have been set,
492  * the <code>CachedRowSet</code> object must be populated with data
493  * using either the method <code>populate</code> or the method <code>execute</code>.
494  * The following lines of code demonstrate using the method <code>populate</code>.
495  * Note that this version of the method takes two parameters, a <code>ResultSet</code>
496  * handle and the row in the <code>ResultSet</code> object from which to start
497  * retrieving rows.
498  * <PRE>
499  * CachedRowSet crs = new CachedRowSetImpl();
500  * crs.setMaxRows(20);
501  * crs.setPageSize(4);
502  * crs.populate(rsHandle, 10);
503  * </PRE>
504  * When this code runs, <i>crs</i> will be populated with four rows from
505  * <i>rsHandle</i> starting with the tenth row.
506  * <P>
507  * The next code fragment shows populating a <code>CachedRowSet</code> object using the
508  * method <code>execute</code>, which may or may not take a <code>Connection</code>
509  * object as a parameter. This code passes <code>execute</code> the <code>Connection</code>
510  * object <i>conHandle</i>.
511  * <P>
512  * Note that there are two differences between the following code
513  * fragment and the previous one. First, the method <code>setMaxRows</code> is not
514  * called, so there is no limit set for the number of rows that <i>crs</i> may contain.
515  * (Remember that <i>crs</i> always has the overriding limit of how much data it can
516  * store in memory.) The second difference is that the you cannot pass the method
517  * <code>execute</code> the number of the row in the <code>ResultSet</code> object
518  * from which to start retrieving rows. This method always starts with the first row.
519  * <PRE>
520  * CachedRowSet crs = new CachedRowSetImpl();
521  * crs.setPageSize(5);
522  * crs.execute(conHandle);
523  * </PRE>
524  * After this code has run, <i>crs</i> will contain five rows of data from the
525  * <code>ResultSet</code> object produced by the command for <i>crs</i>. The writer
526  * for <i>crs</i> will use <i>conHandle</i> to connect to the data source and
527  * execute the command for <i>crs</i>. An application is then able to operate on the
528  * data in <i>crs</i> in the same way that it would operate on data in any other
529  * <code>CachedRowSet</code> object.
530  * <P>
531  * To access the next page (chunk of data), an application calls the method
532  * <code>nextPage</code>. This method creates a new <code>CachedRowSet</code> object
533  * and fills it with the next page of data. For example, assume that the
534  * <code>CachedRowSet</code> object's command returns a <code>ResultSet</code> object
535  * <i>rs</i> with 1000 rows of data. If the page size has been set to 100, the first
536  * call to the method <code>nextPage</code> will create a <code>CachedRowSet</code> object
537  * containing the first 100 rows of <i>rs</i>. After doing what it needs to do with the
538  * data in these first 100 rows, the application can again call the method
539  * <code>nextPage</code> to create another <code>CachedRowSet</code> object
540  * with the second 100 rows from <i>rs</i>. The data from the first <code>CachedRowSet</code>
541  * object will no longer be in memory because it is replaced with the data from the
542  * second <code>CachedRowSet</code> object. After the tenth call to the method <code>nextPage</code>,
543  * the tenth <code>CachedRowSet</code> object will contain the last 100 rows of data from
544  * <i>rs</i>, which are stored in memory. At any given time, the data from only one
545  * <code>CachedRowSet</code> object is stored in memory.
546  * <P>
547  * The method <code>nextPage</code> returns <code>true</code> as long as the current
548  * page is not the last page of rows and <code>false</code> when there are no more pages.
549  * It can therefore be used in a <code>while</code> loop to retrieve all of the pages,
550  * as is demonstrated in the following lines of code.
551  * <PRE>
552  * CachedRowSet crs = CachedRowSetImpl();
553  * crs.setPageSize(100);
554  * crs.execute(conHandle);
555  *
556  * while(crs.next() {
557  * . . . // operate on first chunk of 100 rows in crs, row by row
558  * }
559  *
560  * while(crs.nextPage()) {
561  * while(crs.next()) {
562  * . . . // operate on the subsequent chunks (of 100 rows each) in crs,
563  * // row by row
564  * }
565  * }
566  * </PRE>
567  * After this code fragment has been run, the application will have traversed all
568  * 1000 rows, but it will have had no more than 100 rows in memory at a time.
569  * <P>
570  * The <code>CachedRowSet</code> interface also defines the method <code>previousPage</code>.
571  * Just as the method <code>nextPage</code> is analogous to the <code>ResultSet</code>
572  * method <code>next</code>, the method <code>previousPage</code> is analogous to
573  * the <code>ResultSet</code> method <code>previous</code>. Similar to the method
574  * <code>nextPage</code>, <code>previousPage</code> creates a <code>CachedRowSet</code>
575  * object containing the number of rows set as the page size. So, for instance, the
576  * method <code>previousPage</code> could be used in a <code>while</code> loop at
577  * the end of the preceding code fragment to navigate back through the pages from the last
578  * page to the first page.
579  * The method <code>previousPage</code> is also similar to <code>nextPage</code>
580  * in that it can be used in a <code>while</code>
581  * loop, except that it returns <code>true</code> as long as there is another page
582  * preceding it and <code>false</code> when there are no more pages ahead of it.
583  * <P>
584  * By positioning the cursor after the last row for each page,
585  * as is done in the following code fragment, the method <code>previous</code>
586  * navigates from the last row to the first row in each page.
587  * The code could also have left the cursor before the first row on each page and then
588  * used the method <code>next</code> in a <code>while</code> loop to navigate each page
589  * from the first row to the last row.
590  * <P>
591  * The following code fragment assumes a continuation from the previous code fragment,
592  * meaning that the cursor for the tenth <code>CachedRowSet</code> object is on the
593  * last row. The code moves the cursor to after the last row so that the first
594  * call to the method <code>previous</code> will put the cursor back on the last row.
595  * After going through all of the rows in the last page (the <code>CachedRowSet</code>
596  * object <i>crs</i>), the code then enters
597  * the <code>while</code> loop to get to the ninth page, go through the rows backwards,
598  * go to the eighth page, go through the rows backwards, and so on to the first row
599  * of the first page.
600  *
601  * <PRE>
602  * crs.afterLast();
603  * while(crs.previous()) {
604  * . . . // navigate through the rows, last to first
605  * {
606  * while(crs.previousPage()) {
607  * crs.afterLast();
608  * while(crs.previous()) {
609  * . . . // go from the last row to the first row of each page
610  * }
611  * }
612  * </PRE>
613  *
614  * @author Jonathan Bruce
615  */

616
617 public interface CachedRowSet extends RowSet, Joinable JavaDoc {
618
619    /**
620     * Populates this <code>CachedRowSet</code> object with data from
621     * the given <code>ResultSet</code> object.
622     * <P>
623     * This method can be used as an alternative to the <code>execute</code> method when an
624     * application has a connection to an open <code>ResultSet</code> object.
625     * Using the method <code>populate</code> can be more efficient than using
626     * the version of the <code>execute</code> method that takes no parameters
627     * because it does not open a new connection and re-execute this
628     * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
629     * method is more a matter of convenience when compared to using the version
630     * of <code>execute</code> that takes a <code>ResultSet</code> object.
631     *
632     * @param data the <code>ResultSet</code> object containing the data
633     * to be read into this <code>CachedRowSet</code> object
634     * @throws SQLException if a null <code>ResultSet</code> object is supplied
635     * or this <code>CachedRowSet</code> object cannot
636     * retrieve the associated <code>ResultSetMetaData</code> object
637     * @see #execute
638     * @see java.sql.ResultSet
639     * @see java.sql.ResultSetMetaData
640     */

641     public void populate(ResultSet data) throws SQLException;
642
643    /**
644     * Populates this <code>CachedRowSet</code> object with data, using the
645     * given connection to produce the result set from which the data will be read.
646     * This method should close any database connections that it creates to
647     * ensure that this <code>CachedRowSet</code> object is disconnected except when
648     * it is reading data from its data source or writing data to its data source.
649     * <P>
650     * The reader for this <code>CachedRowSet</code> object
651     * will use <i>conn</i> to establish a connection to the data source
652     * so that it can execute the rowset's command and read data from the
653     * the resulting <code>ResultSet</code> object into this
654     * <code>CachedRowSet</code> object. This method also closes <i>conn</i>
655     * after it has populated this <code>CachedRowSet</code> object.
656     * <P>
657     * If this method is called when an implementation has already been
658     * populated, the contents and the metadata are (re)set. Also, if this method is
659     * called before the method <code>acceptChanges</code> has been called
660     * to commit outstanding updates, those updates are lost.
661     *
662     * @param conn a standard JDBC <code>Connection</code> object with valid
663     * properties
664     * @throws SQLException if an invalid <code>Connection</code> object is supplied
665     * or an error occurs in establishing the connection to the
666     * data source
667     * @see #populate
668     * @see java.sql.Connection
669     */

670     public void execute(Connection conn) throws SQLException;
671
672    /**
673     * Propagates row update, insert and delete changes made to this
674     * <code>CachedRowSet</code> object to the underlying data source.
675     * <P>
676     * This method calls on this <code>CachedRowSet</code> object's writer
677     * to do the work behind the scenes.
678     * Standard <code>CachedRowSet</code> implementations should use the
679     * <code>SyncFactory</code> singleton
680     * to obtain a <code>SyncProvider</code> instance providing a
681     * <code>RowSetWriter</code> object (writer). The writer will attempt
682     * to propagate changes made in this <code>CachedRowSet</code> object
683     * back to the data source.
684     * <P>
685     * When the method <code>acceptChanges</code> executes successfully, in
686     * addition to writing changes to the data source, it
687     * makes the values in the current row be the values in the original row.
688     * <P>
689     * Depending on the synchronization level of the <code>SyncProvider</code>
690     * implementation being used, the writer will compare the original values
691     * with those in the data source to check for conflicts. When there is a conflict,
692     * the <code>RIOptimisticProvider</code> implementation, for example, throws a
693     * <code>SyncProviderException</code> and does not write anything to the
694     * data source.
695     * <P>
696     * An application may choose to catch the <code>SyncProviderException</code>
697     * object and retrieve the <code>SyncResolver</code> object it contains.
698     * The <code>SyncResolver</code> object lists the conflicts row by row and
699     * sets a lock on the data source to avoid further conflicts while the
700     * current conflicts are being resolved.
701     * Further, for each conflict, it provides methods for examining the conflict
702     * and setting the value that should be persisted in the data source.
703     * After all conflicts have been resolved, an application must call the
704     * <code>acceptChanges</code> method again to write resolved values to the
705     * data source. If all of the values in the data source are already the
706     * values to be persisted, the method <code>acceptChanges</code> does nothing.
707     * <P>
708     * Some provider implementations may use locks to ensure that there are no
709     * conflicts. In such cases, it is guaranteed that the writer will succeed in
710     * writing changes to the data source when the method <code>acceptChanges</code>
711     * is called. This method may be called immediately after the methods
712     * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
713     * have been called, but it is more efficient to call it only once after
714     * all changes have been made so that only one connection needs to be
715     * established.
716     * <P>
717     * Note: The <code>acceptChanges()</code> method will determine if the
718     * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
719     * to true, all updates in the synchronization are committed to the data
720     * source. Otherwise, the application <b>must</b> explicity call the
721     * <code>commit()</code> or <code>rollback()</code> methods as appropriate.
722     *
723     * @throws SQLException if the cursor is on the insert row
724     * @throws SyncProviderException if the underlying
725     * synchronization provider's writer fails to write the updates
726     * back to the data source
727     * @see #acceptChanges(java.sql.Connection)
728     * @see javax.sql.RowSetWriter
729     * @see javax.sql.rowset.spi.SyncFactory
730     * @see javax.sql.rowset.spi.SyncProvider
731     * @see javax.sql.rowset.spi.SyncProviderException
732     * @see javax.sql.rowset.spi.SyncResolver
733     */

734     public void acceptChanges() throws SyncProviderException;
735
736    /**
737     * Propagates all row update, insert and delete changes to the
738     * data source backing this <code>CachedRowSet</code> object
739     * using the specified <code>Connection</code> object to establish a
740     * connection to the data source.
741     * <P>
742     * The other version of the <code>acceptChanges</code> method is not passed
743     * a connection because it uses
744     * the <code>Connection</code> object already defined within the <code>RowSet</code>
745     * object, which is the connection used for populating it initially.
746     * <P>
747     * This form of the method <code>acceptChanges</code> is similar to the
748     * form that takes no arguments; however, unlike the other form, this form
749     * can be used only when the underlying data source is a JDBC data source.
750     * The updated <code>Connection</code> properties must be used by the
751     * <code>SyncProvider</code> to reset the <code>RowSetWriter</code>
752     * configuration to ensure that the contents of the <code>CachedRowSet</code>
753     * object are synchronized correctly.
754     * <P>
755     * When the method <code>acceptChanges</code> executes successfully, in
756     * addition to writing changes to the data source, it
757     * makes the values in the current row be the values in the original row.
758     * <P>
759     * Depending on the synchronization level of the <code>SyncProvider</code>
760     * implementation being used, the writer will compare the original values
761     * with those in the data source to check for conflicts. When there is a conflict,
762     * the <code>RIOptimisticProvider</code> implementation, for example, throws a
763     * <code>SyncProviderException</code> and does not write anything to the
764     * data source.
765     * <P>
766     * An application may choose to catch the <code>SyncProviderException</code>
767     * object and retrieve the <code>SyncResolver</code> object it contains.
768     * The <code>SyncResolver</code> object lists the conflicts row by row and
769     * sets a lock on the data source to avoid further conflicts while the
770     * current conflicts are being resolved.
771     * Further, for each conflict, it provides methods for examining the conflict
772     * and setting the value that should be persisted in the data source.
773     * After all conflicts have been resolved, an application must call the
774     * <code>acceptChanges</code> method again to write resolved values to the
775     * data source. If all of the values in the data source are already the
776     * values to be persisted, the method <code>acceptChanges</code> does nothing.
777     * <P>
778     * Some provider implementations may use locks to ensure that there are no
779     * conflicts. In such cases, it is guaranteed that the writer will succeed in
780     * writing changes to the data source when the method <code>acceptChanges</code>
781     * is called. This method may be called immediately after the methods
782     * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
783     * have been called, but it is more efficient to call it only once after
784     * all changes have been made so that only one connection needs to be
785     * established.
786     * <P>
787     * Note: The <code>acceptChanges()</code> method will determine if the
788     * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
789     * to true, all updates in the synchronization are committed to the data
790     * source. Otherwise, the application <b>must</b> explicity call the
791     * <code>commit</code> or <code>rollback</code> methods as appropriate.
792     *
793     * @param con a standard JDBC <code>Connection</code> object
794     * @throws SQLException if the cursor is on the insert row
795     * @throws SyncProviderException if the underlying
796     * synchronization provider's writer fails to write the updates
797     * back to the data source
798     * @see #acceptChanges()
799     * @see javax.sql.RowSetWriter
800     * @see javax.sql.rowset.spi.SyncFactory
801     * @see javax.sql.rowset.spi.SyncProvider
802     * @see javax.sql.rowset.spi.SyncProviderException
803     * @see javax.sql.rowset.spi.SyncResolver
804     */

805     public void acceptChanges(Connection con) throws SyncProviderException;
806
807    /**
808     * Restores this <code>CachedRowSet</code> object to its original
809     * value, that is, its value before the last set of changes. If there
810     * have been no changes to the rowset or only one set of changes,
811     * the original value is the value with which this <code>CachedRowSet</code> object
812     * was populated; otherwise, the original value is
813     * the value it had immediately before its current value.
814     * <P>
815     * When this method is called, a <code>CachedRowSet</code> implementation
816     * must ensure that all updates, inserts, and deletes to the current
817     * rowset instance are replaced by the previous values. In addition,
818     * the cursor should be
819     * reset to the first row and a <code>rowSetChanged</code> event
820     * should be fired to notify all registered listeners.
821     *
822     * @throws SQLException if an error occurs rolling back the current value of
823     * this <code>CachedRowSet</code> object to its previous value
824     * @see javax.sql.RowSetListener#rowSetChanged
825     */

826     public void restoreOriginal() throws SQLException;
827
828    /**
829     * Releases the current contents of this <code>CachedRowSet</code>
830     * object and sends a <code>rowSetChanged</code> event to all
831     * registered listeners. Any outstanding updates are discarded and
832     * the rowset contains no rows after this method is called. There
833     * are no interactions with the underlying data source, and any rowset
834     * content, metadata, and content updates should be non-recoverable.
835     * <P>
836     * This <code>CachedRowSet</code> object should lock until its contents and
837     * associated updates are fully cleared, thus preventing 'dirty' reads by
838     * other components that hold a reference to this <code>RowSet</code> object.
839     * In addition, the contents cannot be released
840     * until all all components reading this <code>CachedRowSet</code> object
841     * have completed their reads. This <code>CachedRowSet</code> object
842     * should be returned to normal behavior after firing the
843     * <code>rowSetChanged</code> event.
844     * <P>
845     * The metadata, including JDBC properties and Synchronization SPI
846     * properties, are maintained for future use. It is important that
847     * properties such as the <code>command</code> property be
848     * relevant to the originating data source from which this <code>CachedRowSet</code>
849     * object was originally established.
850     * <P>
851     * This method empties a rowset, as opposed to the <code>close</code> method,
852     * which marks the entire rowset as recoverable to allow the garbage collector
853     * the rowset's Java VM resources.
854     *
855     * @throws SQLException if an error occurs flushing the contents of this
856     * <code>CachedRowSet</code> object
857     * @see javax.sql.RowSetListener#rowSetChanged
858     * @see java.sql.ResultSet#close
859     */

860     public void release() throws SQLException;
861
862    /**
863     * Cancels the deletion of the current row and notifies listeners that
864     * a row has changed. After this method is called, the current row is
865     * no longer marked for deletion. This method can be called at any
866     * time during the lifetime of the rowset.
867     * <P>
868     * In addition, multiple cancellations of row deletions can be made
869     * by adjusting the position of the cursor using any of the cursor
870     * position control methods such as:
871     * <ul>
872     * <li><code>CachedRowSet.absolute</code>
873     * <li><code>CachedRowSet.first</code>
874     * <li><code>CachedRowSet.last</code>
875     * </ul>
876     *
877     * @throws SQLException if (1) the current row has not been deleted or
878     * (2) the cursor is on the insert row, before the first row, or
879     * after the last row
880     * @see javax.sql.rowset.CachedRowSet#undoInsert
881     * @see java.sql.ResultSet#cancelRowUpdates
882     */

883     public void undoDelete() throws SQLException;
884
885    /**
886     * Immediately removes the current row from this <code>CachedRowSet</code>
887     * object if the row has been inserted, and also notifies listeners that a
888     * row has changed. This method can be called at any time during the
889     * lifetime of a rowset and assuming the current row is within
890     * the exception limitations (see below), it cancels the row insertion
891     * of the current row.
892     * <P>
893     * In addition, multiple cancellations of row insertions can be made
894     * by adjusting the position of the cursor using any of the cursor
895     * position control methods such as:
896     * <ul>
897     * <li><code>CachedRowSet.absolute</code>
898     * <li><code>CachedRowSet.first</code>
899     * <li><code>CachedRowSet.last</code>
900     * </ul>
901     *
902     * @throws SQLException if (1) the current row has not been inserted or (2)
903     * the cursor is before the first row, after the last row, or on the
904     * insert row
905     * @see javax.sql.rowset.CachedRowSet#undoDelete
906     * @see java.sql.ResultSet#cancelRowUpdates
907     */

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

929     public void undoUpdate() throws SQLException;
930
931    /**
932     * Indicates whether the designated column in the current row of this
933     * <code>CachedRowSet</code> object has been updated.
934     *
935     * @param idx an <code>int</code> identifying the column to be checked for updates
936     * @return <code>true</code> if the designated column has been visibly updated;
937     * <code>false</code> otherwise
938     * @throws SQLException if the cursor is on the insert row, before the first row,
939     * or after the last row
940     * @see java.sql.DatabaseMetaData#updatesAreDetected
941     */

942     public boolean columnUpdated(int idx) throws SQLException;
943     
944
945    /**
946     * Indicates whether the designated column in the current row of this
947     * <code>CachedRowSet</code> object has been updated.
948     *
949     * @param columnName a <code>String</code> object giving the name of the
950     * column to be checked for updates
951     * @return <code>true</code> if the column has been visibly updated;
952     * <code>false</code> otherwise
953     * @throws SQLException if the cursor is on the insert row, before the first row,
954     * or after the last row
955     * @see java.sql.DatabaseMetaData#updatesAreDetected
956     */

957     public boolean columnUpdated(String JavaDoc columnName) throws SQLException;
958
959    /**
960     * Converts this <code>CachedRowSet</code> object to a <code>Collection</code>
961     * object that contains all of this <code>CachedRowSet</code> object's data.
962     * Implementations have some latitude in
963     * how they can represent this <code>Collection</code> object because of the
964     * abstract nature of the <code>Collection</code> framework.
965     * Each row must be fully represented in either a
966     * general purpose <code>Collection</code> implementation or a specialized
967     * <code>Collection</code> implementation, such as a <code>TreeMap</code>
968     * object or a <code>Vector</code> object.
969     * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
970     * in the Java programming language.
971     * <P>
972     * The standard reference implementation for the <code>CachedRowSet</code>
973     * interface uses a <code>TreeMap</code> object for the rowset, with the
974     * values in each row being contained in <code>Vector</code> objects. It is
975     * expected that most implementations will do the same.
976     * <P>
977     * The <code>TreeMap</code> type of collection guarantees that the map will be in
978     * ascending key order, sorted according to the natural order for the
979     * key's class.
980     * Each key references a <code>Vector</code> object that corresponds to one
981     * row of a <code>RowSet</code> object. Therefore, the size of each
982     * <code>Vector</code> object must be exactly equal to the number of
983     * columns in the <code>RowSet</code> object.
984     * The key used by the <code>TreeMap</code> collection is determined by the
985     * implementation, which may choose to leverage a set key that is
986     * available within the internal <code>RowSet</code> tabular structure by
987     * virtue of a key already set either on the <code>RowSet</code> object
988     * itself or on the underlying SQL data.
989     * <P>
990     *
991     * @return a <code>Collection</code> object that contains the values in
992     * each row in this <code>CachedRowSet</code> object
993     * @throws SQLException if an error occurs generating the collection
994     * @see #toCollection(int)
995     * @see #toCollection(String)
996     */

997     public Collection<?> toCollection() throws SQLException;
998
999    /**
1000    * Converts the designated column in this <code>CachedRowSet</code> object
1001    * to a <code>Collection</code> object. Implementations have some latitude in
1002    * how they can represent this <code>Collection</code> object because of the
1003    * abstract nature of the <code>Collection</code> framework.
1004    * Each column value should be fully represented in either a
1005    * general purpose <code>Collection</code> implementation or a specialized
1006    * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1007    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1008    * in the Java programming language.
1009    * <P>
1010    * The standard reference implementation uses a <code>Vector</code> object
1011    * to contain the column values, and it is expected
1012    * that most implementations will do the same. If a <code>Vector</code> object
1013    * is used, it size must be exactly equal to the number of rows
1014    * in this <code>CachedRowSet</code> object.
1015    *
1016    * @param column an <code>int</code> indicating the column whose values
1017    * are to be represented in a <code>Collection</code> object
1018    * @return a <code>Collection</code> object that contains the values
1019    * stored in the specified column of this <code>CachedRowSet</code>
1020    * object
1021    * @throws SQLException if an error occurs generating the collection or
1022    * an invalid column id is provided
1023    * @see #toCollection
1024    * @see #toCollection(String)
1025    */

1026    public Collection<?> toCollection(int column) throws SQLException;
1027   
1028   /**
1029    * Converts the designated column in this <code>CachedRowSet</code> object
1030    * to a <code>Collection</code> object. Implementations have some latitude in
1031    * how they can represent this <code>Collection</code> object because of the
1032    * abstract nature of the <code>Collection</code> framework.
1033    * Each column value should be fully represented in either a
1034    * general purpose <code>Collection</code> implementation or a specialized
1035    * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1036    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1037    * in the Java programming language.
1038    * <P>
1039    * The standard reference implementation uses a <code>Vector</code> object
1040    * to contain the column values, and it is expected
1041    * that most implementations will do the same. If a <code>Vector</code> object
1042    * is used, it size must be exactly equal to the number of rows
1043    * in this <code>CachedRowSet</code> object.
1044    *
1045    * @param column a <code>String</code> object giving the name of the
1046    * column whose values are to be represented in a collection
1047    * @return a <code>Collection</code> object that contains the values
1048    * stored in the specified column of this <code>CachedRowSet</code>
1049    * object
1050    * @throws SQLException if an error occurs generating the collection or
1051    * an invalid column id is provided
1052    * @see #toCollection
1053    * @see #toCollection(int)
1054    */

1055    public Collection<?> toCollection(String JavaDoc column) throws SQLException;
1056
1057   /**
1058    * Retrieves the <code>SyncProvider</code> implementation for this
1059    * <code>CachedRowSet</code> object. Internally, this method is used by a rowset
1060    * to trigger read or write actions between the rowset
1061    * and the data source. For example, a rowset may need to get a handle
1062    * on the the rowset reader (<code>RowSetReader</code> object) from the
1063    * <code>SyncProvider</code> to allow the rowset to be populated.
1064    * <pre>
1065    * RowSetReader rowsetReader = null;
1066    * SyncProv