View Javadoc
1   /*
2    * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package com.sun.rowset.internal;
27  
28  import com.sun.rowset.JdbcRowSetResourceBundle;
29  import java.sql.*;
30  import javax.sql.*;
31  import java.io.*;
32  import java.util.*;
33  
34  /**
35   * A class used internally to manage a <code>CachedRowSet</code> object's
36   * insert row.  This class keeps track of the number of columns in the
37   * insert row and which columns have had a value inserted.  It provides
38   * methods for retrieving a column value, setting a column value, and finding
39   * out whether the insert row is complete.
40   */
41  public class InsertRow extends BaseRow implements Serializable, Cloneable {
42  
43  /**
44   * An internal <code>BitSet</code> object used to keep track of the
45   * columns in this <code>InsertRow</code> object that have had a value
46   * inserted.
47   */
48      private BitSet colsInserted;
49  
50  /**
51   * The number of columns in this <code>InsertRow</code> object.
52   */
53      private int cols;
54  
55      private JdbcRowSetResourceBundle resBundle;
56  
57  /**
58   * Creates an <code>InsertRow</code> object initialized with the
59   * given number of columns, an array for keeping track of the
60   * original values in this insert row, and a
61   * <code>BitSet</code> object with the same number of bits as
62   * there are columns.
63   *
64   * @param numCols an <code>int</code> indicating the number of columns
65   *                in this <code>InsertRow</code> object
66   */
67      public InsertRow(int numCols) {
68          origVals = new Object[numCols];
69          colsInserted = new BitSet(numCols);
70          cols = numCols;
71          try {
72             resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
73          } catch(IOException ioe) {
74              throw new RuntimeException(ioe);
75          }
76      }
77  
78  /**
79   * Sets the bit in this <code>InsertRow</code> object's internal
80   * <code>BitSet</code> object that corresponds to the specified column
81   * in this <code>InsertRow</code> object. Setting a bit indicates
82   * that a value has been set.
83   *
84   * @param col the number of the column to be marked as inserted;
85   *            the first column is <code>1</code>
86   */
87      protected void markColInserted(int col) {
88          colsInserted.set(col);
89      }
90  
91  /**
92   * Indicates whether this <code>InsertRow</code> object has a value
93   * for every column that cannot be null.
94   * @param RowSetMD the <code>RowSetMetaData</code> object for the
95   *                 <code>CachedRowSet</code> object that maintains this
96   *                 <code>InsertRow</code> object
97   * @return <code>true</code> if this <code>InsertRow</code> object is
98   *         complete; <code>false</code> otherwise
99   * @throws SQLException if there is an error accessing data
100  */
101     public boolean isCompleteRow(RowSetMetaData RowSetMD) throws SQLException {
102         for (int i = 0; i < cols; i++) {
103             if (colsInserted.get(i) == false &&
104                 RowSetMD.isNullable(i + 1) ==
105                 ResultSetMetaData.columnNoNulls) {
106                 return false;
107             }
108 
109         }
110         return true;
111     }
112 
113 /**
114  * Clears all the bits in the internal <code>BitSet</code> object
115  * maintained by this <code>InsertRow</code> object.  Clearing all the bits
116  * indicates that none of the columns have had a value inserted.
117  */
118     public void initInsertRow() {
119         for (int i = 0; i < cols; i++) {
120             colsInserted.clear(i);
121         }
122     }
123 
124 /**
125  * Retrieves the value of the designated column in this
126  * <code>InsertRow</code> object.  If no value has been inserted
127  * into the designated column, this method throws an
128  * <code>SQLException</code>.
129  *
130  * @param idx the column number of the value to be retrieved;
131  *            the first column is <code>1</code>
132  * @throws SQLException if no value has been inserted into
133  *                                   the designated column
134  */
135     public Object getColumnObject(int idx) throws SQLException {
136         if (colsInserted.get(idx - 1) == false) {
137             throw new SQLException(resBundle.handleGetObject("insertrow.novalue").toString());
138         }
139         return (origVals[idx - 1]);
140     }
141 
142 /**
143  * Sets the element in this <code>InsertRow</code> object's
144  * internal array of original values that corresponds to the
145  * designated column with the given value.  If the third
146  * argument is <code>true</code>,
147  * which means that the cursor is on the insert row, this
148  * <code>InsertRow</code> object's internal <code>BitSet</code> object
149  * is set so that the bit corresponding to the column being set is
150  * turned on.
151  *
152  * @param idx the number of the column in the insert row to be set;
153  *              the first column is <code>1</code>
154  * @param val the value to be set
155  */
156     public void setColumnObject(int idx, Object val) {
157         origVals[idx - 1] = val;
158         markColInserted(idx - 1);
159     }
160 
161     /**
162      * This method re populates the resBundle
163      * during the deserialization process
164      *
165      */
166     private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
167         // Default state initialization happens here
168         ois.defaultReadObject();
169         // Initialization of transient Res Bundle happens here .
170         try {
171            resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
172         } catch(IOException ioe) {
173             throw new RuntimeException(ioe);
174         }
175 
176     }
177 
178     static final long serialVersionUID = 1066099658102869344L;
179 }