10133 lines · 431.3 KB · Java
RawDownload
/* * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.rowset; import java.sql.*;import javax.sql.*;import java.io.*;import java.math.*;import java.util.*;import java.text.*; import javax.sql.rowset.*;import javax.sql.rowset.spi.*;import javax.sql.rowset.serial.*;import com.sun.rowset.internal.*;import com.sun.rowset.providers.*; /** * The standard implementation of the <code>CachedRowSet</code> interface. * * See interface defintion for full behaviour and implementation requirements. * This reference implementation has made provision for a one-to-one write back * facility and it is curremtly be possible to change the peristence provider * during the life-time of any CachedRowSetImpl. * * @author Jonathan Bruce, Amit Handa */ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetInternal, Serializable, Cloneable, CachedRowSet {     /**     * The <code>SyncProvider</code> used by the CachedRowSet     */    private SyncProvider provider;     /**     * The <code>RowSetReaderImpl</code> object that is the reader     * for this rowset.  The method <code>execute</code> uses this     * reader as part of its implementation.     * @serial     */    private RowSetReader rowSetReader;     /**     * The <code>RowSetWriterImpl</code> object that is the writer     * for this rowset.  The method <code>acceptChanges</code> uses     * this writer as part of its implementation.     * @serial     */    private RowSetWriter rowSetWriter;     /**     * The <code>Connection</code> object that connects with this     * <code>CachedRowSetImpl</code> object's current underlying data source.     */    private transient Connection conn;     /**     * The <code>ResultSetMetaData</code> object that contains information     * about the columns in the <code>ResultSet</code> object that is the     * current source of data for this <code>CachedRowSetImpl</code> object.     */    private transient ResultSetMetaData RSMD;     /**     * The <code>RowSetMetaData</code> object that contains information about     * the columns in this <code>CachedRowSetImpl</code> object.     * @serial     */    private RowSetMetaDataImpl RowSetMD;     // Properties of this RowSet     /**     * An array containing the columns in this <code>CachedRowSetImpl</code>     * object that form a unique identifier for a row. This array     * is used by the writer.     * @serial     */    private int keyCols[];     /**     * The name of the table in the underlying database to which updates     * should be written.  This name is needed because most drivers     * do not return this information in a <code>ResultSetMetaData</code>     * object.     * @serial     */    private String tableName;     /**     * A <code>Vector</code> object containing the <code>Row</code>     * objects that comprise  this <code>CachedRowSetImpl</code> object.     * @serial     */    private Vector<Object> rvh;     /**     * The current postion of the cursor in this <code>CachedRowSetImpl</code>     * object.     * @serial     */    private int cursorPos;     /**     * The current postion of the cursor in this <code>CachedRowSetImpl</code>     * object not counting rows that have been deleted, if any.     * <P>     * For example, suppose that the cursor is on the last row of a rowset     * that started with five rows and subsequently had the second and third     * rows deleted. The <code>absolutePos</code> would be <code>3</code>,     * whereas the <code>cursorPos</code> would be <code>5</code>.     * @serial     */    private int absolutePos;     /**     * The number of deleted rows currently in this <code>CachedRowSetImpl</code>     * object.     * @serial     */    private int numDeleted;     /**     * The total number of rows currently in this <code>CachedRowSetImpl</code>     * object.     * @serial     */    private int numRows;     /**     * A special row used for constructing a new row. A new     * row is constructed by using <code>ResultSet.updateXXX</code>     * methods to insert column values into the insert row.     * @serial     */    private InsertRow insertRow;     /**     * A <code>boolean</code> indicating whether the cursor is     * currently on the insert row.     * @serial     */    private boolean onInsertRow;     /**     * The field that temporarily holds the last position of the     * cursor before it moved to the insert row, thus preserving     * the number of the current row to which the cursor may return.     * @serial     */    private int currentRow;     /**     * A <code>boolean</code> indicating whether the last value     * returned was an SQL <code>NULL</code>.     * @serial     */    private boolean lastValueNull;     /**     * A <code>SQLWarning</code> which logs on the warnings     */    private SQLWarning sqlwarn;     /**     * Used to track match column for JoinRowSet consumption     */    private String strMatchColumn ="";     /**     * Used to track match column for JoinRowSet consumption     */    private int iMatchColumn = -1;     /**     * A <code>RowSetWarning</code> which logs on the warnings     */    private RowSetWarning rowsetWarning;     /**     * The default SyncProvider for the RI CachedRowSetImpl     */    private String DEFAULT_SYNC_PROVIDER = "com.sun.rowset.providers.RIOptimisticProvider";     /**     * The boolean variable indicating locatorsUpdateValue     */    private boolean dbmslocatorsUpdateCopy;     /**     * The <code>ResultSet</code> object that is used to maintain the data when     * a ResultSet and start position are passed as parameters to the populate function     */    private transient ResultSet resultSet;     /**     * The integer value indicating the end position in the ResultSetwhere the picking     * up of rows for populating a CachedRowSet object was left off.     */    private int endPos;     /**     * The integer value indicating the end position in the ResultSetwhere the picking     * up of rows for populating a CachedRowSet object was left off.     */    private int prevEndPos;     /**     * The integer value indicating the position in the ResultSet, to populate the     * CachedRowSet object.     */    private int startPos;     /**     * The integer value indicating the positon from where the page prior to this     * was populated.     */    private int startPrev;     /**     * The integer value indicating size of the page.     */    private int pageSize;     /**     * The integer value indicating number of rows that have been processed so far.     * Used for checking whether maxRows has been reached or not.     */    private int maxRowsreached;    /**     * The boolean value when true signifies that pages are still to follow and a     * false value indicates that this is the last page.     */    private boolean pagenotend = true;     /**     * The boolean value indicating whether this is the first page or not.     */    private boolean onFirstPage;     /**     * The boolean value indicating whether this is the last page or not.     */    private boolean onLastPage;     /**     * The integer value indicating how many times the populate function has been called.     */    private int populatecallcount;     /**     * The integer value indicating the total number of rows to be processed in the     * ResultSet object passed to the populate function.     */    private int totalRows;     /**     * The boolean value indicating how the CahedRowSet object has been populated for     * paging purpose. True indicates that connection parameter is passed.     */    private boolean callWithCon;     /**     * CachedRowSet reader object to read the data from the ResultSet when a connection     * parameter is passed to populate the CachedRowSet object for paging.     */    private CachedRowSetReader crsReader;     /**     * The Vector holding the Match Columns     */    private Vector<Integer> iMatchColumns;     /**     * The Vector that will hold the Match Column names.     */    private Vector<String> strMatchColumns;     /**     * Trigger that indicates whether the active SyncProvider is exposes the     * additional TransactionalWriter method     */    private boolean tXWriter = false;     /**     * The field object for a transactional RowSet writer     */    private TransactionalWriter tWriter = null;     protected transient JdbcRowSetResourceBundle resBundle;     private boolean updateOnInsert;       /**     * Constructs a new default <code>CachedRowSetImpl</code> object with     * the capacity to hold 100 rows. This new object has no metadata     * and has the following default values:     * <pre>     *     onInsertRow = false     *     insertRow = null     *     cursorPos = 0     *     numRows = 0     *     showDeleted = false     *     queryTimeout = 0     *     maxRows = 0     *     maxFieldSize = 0     *     rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE     *     concurrency = ResultSet.CONCUR_UPDATABLE     *     readOnly = false     *     isolation = Connection.TRANSACTION_READ_COMMITTED     *     escapeProcessing = true     *     onInsertRow = false     *     insertRow = null     *     cursorPos = 0     *     absolutePos = 0     *     numRows = 0     * </pre>     * A <code>CachedRowSetImpl</code> object is configured to use the default     * <code>RIOptimisticProvider</code> implementation to provide connectivity     * and synchronization capabilities to the set data source.     * <P>     * @throws SQLException if an error occurs     */    public CachedRowSetImpl() throws SQLException {         try {           resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();        } catch(IOException ioe) {            throw new RuntimeException(ioe);        }         // set the Reader, this maybe overridden latter        provider =        (SyncProvider)SyncFactory.getInstance(DEFAULT_SYNC_PROVIDER);         if (!(provider instanceof RIOptimisticProvider)) {            throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidp").toString());        }         rowSetReader = (CachedRowSetReader)provider.getRowSetReader();        rowSetWriter = (CachedRowSetWriter)provider.getRowSetWriter();         // allocate the parameters collection        initParams();         initContainer();         // set up some default values        initProperties();         // insert row setup        onInsertRow = false;        insertRow = null;         // set the warninings        sqlwarn = new SQLWarning();        rowsetWarning = new RowSetWarning();     }     /**     * Provides a <code>CachedRowSetImpl</code> instance with the same default properties as     * as the zero parameter constructor.     * <pre>     *     onInsertRow = false     *     insertRow = null     *     cursorPos = 0     *     numRows = 0     *     showDeleted = false     *     queryTimeout = 0     *     maxRows = 0     *     maxFieldSize = 0     *     rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE     *     concurrency = ResultSet.CONCUR_UPDATABLE     *     readOnly = false     *     isolation = Connection.TRANSACTION_READ_COMMITTED     *     escapeProcessing = true     *     onInsertRow = false     *     insertRow = null     *     cursorPos = 0     *     absolutePos = 0     *     numRows = 0     * </pre>     *     * However, applications will have the means to specify at runtime the     * desired <code>SyncProvider</code> object.     * <p>     * For example, creating a <code>CachedRowSetImpl</code> object as follows ensures     * that a it is established with the <code>com.foo.provider.Impl</code> synchronization     * implementation providing the synchronization mechanism for this disconnected     * <code>RowSet</code> object.     * <pre>     *     Hashtable env = new Hashtable();     *     env.put(javax.sql.rowset.spi.SyncFactory.ROWSET_PROVIDER_NAME,     *         "com.foo.provider.Impl");     *     CachedRowSetImpl crs = new CachedRowSet(env);     * </pre>     * <p>     * Calling this constructor with a <code>null</code> parameter will     * cause the <code>SyncFactory</code> to provide the reference     * optimistic provider <code>com.sun.rowset.providers.RIOptimisticProvider</code>.     * <p>     * In addition, the following properties can be associated with the     * provider to assist in determining the choice of the synchronizaton     * provider such as:     * <ul>     * <li><code>ROWSET_SYNC_PROVIDER</code> - the property specifying the the     * <code>SyncProvider</code> class name to be instantiated by the     * <code>SyncFacttory</code>     * <li><code>ROWSET_SYNC_VENDOR</code> - the property specifying the software     * vendor associated with a <code>SyncProvider</code> implementation.     * <li><code>ROWSET_SYNC_PROVIDER_VER</code> - the property specifying the     * version of the <code>SyncProvider</code> implementation provided by the     * software vendor.     * </ul>     * More specific detailes are available in the <code>SyncFactory</code>     * and <code>SyncProvider</code> specificiations later in this document.     * <p>     * @param env a <code>Hashtable</code> object with a list of desired     *        synchronization providers     * @throws SQLException if the requested provider cannot be found by the     * synchonization factory     * @see SyncProvider     */     public CachedRowSetImpl(Hashtable env) throws SQLException {          try {           resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();        } catch(IOException ioe) {            throw new RuntimeException(ioe);        }         if (env == null) {            throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nullhash").toString());        }         String providerName = (String)env.get(        javax.sql.rowset.spi.SyncFactory.ROWSET_SYNC_PROVIDER);         // set the Reader, this maybe overridden latter        provider =        (SyncProvider)SyncFactory.getInstance(providerName);         rowSetReader = provider.getRowSetReader();        rowSetWriter = provider.getRowSetWriter();         initParams(); // allocate the parameters collection        initContainer();        initProperties(); // set up some default values    }     /**     * Sets the <code>rvh</code> field to a new <code>Vector</code>     * object with a capacity of 100 and sets the     * <code>cursorPos</code> and <code>numRows</code> fields to zero.     */    private void initContainer() {         rvh = new Vector<Object>(100);        cursorPos = 0;        absolutePos = 0;        numRows = 0;        numDeleted = 0;    }     /**     * Sets the properties for this <code>CachedRowSetImpl</code> object to     * their default values. This method is called internally by the     * default constructor.     */     private void initProperties() throws SQLException {

Lines 1–500 of 10133.