Clover Coverage Report - Commons BeanUtils 1.8.3-kuali-SNAPSHOT
Coverage timestamp: Thu Jun 9 2011 11:19:33 MST
../../../../img/srcFileCovDistChart9.png 27% of files have more coverage
22   315   14   2.44
6   57   0.64   9
9     1.56  
1    
 
  RowSetDynaClass       Line # 69 22 0% 14 4 89.2% 0.8918919
 
  (5)
 
1    /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10    *
11    * Unless required by applicable law or agreed to in writing, software
12    * distributed under the License is distributed on an "AS IS" BASIS,
13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    * See the License for the specific language governing permissions and
15    * limitations under the License.
16    */
17   
18   
19    package org.apache.commons.beanutils;
20   
21   
22    import java.io.Serializable;
23    import java.sql.ResultSet;
24    import java.sql.SQLException;
25    import java.util.ArrayList;
26    import java.util.List;
27   
28   
29    /**
30    * <p>Implementation of {@link DynaClass} that creates an in-memory collection
31    * of {@link DynaBean}s representing the results of an SQL query. Once the
32    * {@link DynaClass} instance has been created, the JDBC <code>ResultSet</code>
33    * and <code>Statement</code> on which it is based can be closed, and the
34    * underlying <code>Connection</code> can be returned to its connection pool
35    * (if you are using one).</p>
36    *
37    * <p>The normal usage pattern is something like:</p>
38    * <pre>
39    * Connection conn = ...; // Acquire connection from pool
40    * Statement stmt = conn.createStatement();
41    * ResultSet rs = stmt.executeQuery("SELECT ...");
42    * RowSetDynaClass rsdc = new RowSetDynaClass(rs);
43    * rs.close();
44    * stmt.close();
45    * ...; // Return connection to pool
46    * List rows = rsdc.getRows();
47    * ...; // Process the rows as desired
48    * </pre>
49    *
50    * <p>Each column in the result set will be represented as a {@link DynaBean}
51    * property of the corresponding name (optionally forced to lower case
52    * for portability). There will be one {@link DynaBean} in the
53    * <code>List</code> returned by <code>getRows()</code> for each
54    * row in the original <code>ResultSet</code>.</p>
55    *
56    * <p>In general, instances of {@link RowSetDynaClass} can be serialized
57    * and deserialized, which will automatically include the list of
58    * {@link DynaBean}s representing the data content. The only exception
59    * to this rule would be when the underlying property values that were
60    * copied from the <code>ResultSet</code> originally cannot themselves
61    * be serialized. Therefore, a {@link RowSetDynaClass} makes a very
62    * convenient mechanism for transporting data sets to remote Java-based
63    * application components.</p>
64    *
65    * @author Craig R. McClanahan
66    * @version $Revision: 926685 $ $Date: 2010-03-23 13:59:08 -0400 (Tue, 23 Mar 2010) $
67    */
68   
 
69    public class RowSetDynaClass extends JDBCDynaClass implements DynaClass, Serializable {
70   
71   
72    // ----------------------------------------------------- Instance variables
73   
74    /**
75    * <p>Limits the size of the returned list. The call to
76    * <code>getRows()</code> will return at most limit number of rows.
77    * If less than or equal to 0, does not limit the size of the result.
78    */
79    protected int limit = -1;
80   
81    /**
82    * <p>The list of {@link DynaBean}s representing the contents of
83    * the original <code>ResultSet</code> on which this
84    * {@link RowSetDynaClass} was based.</p>
85    */
86    protected List rows = new ArrayList();
87   
88    // ----------------------------------------------------------- Constructors
89   
90   
91    /**
92    * <p>Construct a new {@link RowSetDynaClass} for the specified
93    * <code>ResultSet</code>. The property names corresponding
94    * to column names in the result set will be lower cased.</p>
95    *
96    * @param resultSet The result set to be wrapped
97    *
98    * @exception NullPointerException if <code>resultSet</code>
99    * is <code>null</code>
100    * @exception SQLException if the metadata for this result set
101    * cannot be introspected
102    */
 
103  10 toggle public RowSetDynaClass(ResultSet resultSet) throws SQLException {
104   
105  10 this(resultSet, true, -1);
106   
107    }
108   
109    /**
110    * <p>Construct a new {@link RowSetDynaClass} for the specified
111    * <code>ResultSet</code>. The property names corresponding
112    * to column names in the result set will be lower cased.</p>
113    *
114    * If <code>limit</code> is not less than 0, max <code>limit</code>
115    * number of rows will be copied into the list.
116    *
117    * @param resultSet The result set to be wrapped
118    * @param limit The maximum for the size of the result.
119    *
120    * @exception NullPointerException if <code>resultSet</code>
121    * is <code>null</code>
122    * @exception SQLException if the metadata for this result set
123    * cannot be introspected
124    */
 
125  1 toggle public RowSetDynaClass(ResultSet resultSet, int limit) throws SQLException {
126   
127  1 this(resultSet, true, limit);
128   
129    }
130   
131   
132    /**
133    * <p>Construct a new {@link RowSetDynaClass} for the specified
134    * <code>ResultSet</code>. The property names corresponding
135    * to the column names in the result set will be lower cased or not,
136    * depending on the specified <code>lowerCase</code> value.</p>
137    *
138    * If <code>limit</code> is not less than 0, max <code>limit</code>
139    * number of rows will be copied into the resultset.
140    *
141    *
142    * @param resultSet The result set to be wrapped
143    * @param lowerCase Should property names be lower cased?
144    *
145    * @exception NullPointerException if <code>resultSet</code>
146    * is <code>null</code>
147    * @exception SQLException if the metadata for this result set
148    * cannot be introspected
149    */
 
150  1 toggle public RowSetDynaClass(ResultSet resultSet, boolean lowerCase)
151    throws SQLException {
152  1 this(resultSet, lowerCase, -1);
153   
154    }
155   
156    /**
157    * <p>Construct a new {@link RowSetDynaClass} for the specified
158    * <code>ResultSet</code>. The property names corresponding
159    * to the column names in the result set will be lower cased or not,
160    * depending on the specified <code>lowerCase</code> value.</p>
161    *
162    * <p><strong>WARNING</strong> - If you specify <code>false</code>
163    * for <code>lowerCase</code>, the returned property names will
164    * exactly match the column names returned by your JDBC driver.
165    * Because different drivers might return column names in different
166    * cases, the property names seen by your application will vary
167    * depending on which JDBC driver you are using.</p>
168    *
169    * @param resultSet The result set to be wrapped
170    * @param lowerCase Should property names be lower cased?
171    * @param limit Maximum limit for the <code>List</code> of {@link DynaBean}
172    *
173    * @exception NullPointerException if <code>resultSet</code>
174    * is <code>null</code>
175    * @exception SQLException if the metadata for this result set
176    * cannot be introspected
177    */
 
178  12 toggle public RowSetDynaClass(ResultSet resultSet, boolean lowerCase, int limit)
179    throws SQLException {
180   
181  12 this(resultSet, lowerCase, limit, false);
182   
183    }
184   
185    /**
186    * <p>Construct a new {@link RowSetDynaClass} for the specified
187    * <code>ResultSet</code>. The property names corresponding
188    * to the column names in the result set will be lower cased or not,
189    * depending on the specified <code>lowerCase</code> value.</p>
190    *
191    * <p><strong>WARNING</strong> - If you specify <code>false</code>
192    * for <code>lowerCase</code>, the returned property names will
193    * exactly match the column names returned by your JDBC driver.
194    * Because different drivers might return column names in different
195    * cases, the property names seen by your application will vary
196    * depending on which JDBC driver you are using.</p>
197    *
198    * @param resultSet The result set to be wrapped
199    * @param lowerCase Should property names be lower cased?
200    * @param useColumnLabel true if the column label should be used, otherwise false
201    *
202    * @exception NullPointerException if <code>resultSet</code>
203    * is <code>null</code>
204    * @exception SQLException if the metadata for this result set
205    * cannot be introspected
206    * @since 1.8.3
207    */
 
208  0 toggle public RowSetDynaClass(ResultSet resultSet, boolean lowerCase, boolean useColumnLabel)
209    throws SQLException {
210  0 this(resultSet, lowerCase, -1, useColumnLabel);
211   
212    }
213   
214    /**
215    * <p>Construct a new {@link RowSetDynaClass} for the specified
216    * <code>ResultSet</code>. The property names corresponding
217    * to the column names in the result set will be lower cased or not,
218    * depending on the specified <code>lowerCase</code> value.</p>
219    *
220    * <p><strong>WARNING</strong> - If you specify <code>false</code>
221    * for <code>lowerCase</code>, the returned property names will
222    * exactly match the column names returned by your JDBC driver.
223    * Because different drivers might return column names in different
224    * cases, the property names seen by your application will vary
225    * depending on which JDBC driver you are using.</p>
226    *
227    * @param resultSet The result set to be wrapped
228    * @param lowerCase Should property names be lower cased?
229    * @param limit Maximum limit for the <code>List</code> of {@link DynaBean}
230    * @param useColumnLabel true if the column label should be used, otherwise false
231    *
232    * @exception NullPointerException if <code>resultSet</code>
233    * is <code>null</code>
234    * @exception SQLException if the metadata for this result set
235    * cannot be introspected
236    * @since 1.8.3
237    */
 
238  12 toggle public RowSetDynaClass(ResultSet resultSet, boolean lowerCase, int limit, boolean useColumnLabel)
239    throws SQLException {
240   
241  12 if (resultSet == null) {
242  0 throw new NullPointerException();
243    }
244  12 this.lowerCase = lowerCase;
245  12 this.limit = limit;
246  12 setUseColumnLabel(useColumnLabel);
247  12 introspect(resultSet);
248  12 copy(resultSet);
249   
250    }
251   
252    /**
253    * <p>Return a <code>List</code> containing the {@link DynaBean}s that
254    * represent the contents of each <code>Row</code> from the
255    * <code>ResultSet</code> that was the basis of this
256    * {@link RowSetDynaClass} instance. These {@link DynaBean}s are
257    * disconnected from the database itself, so there is no problem with
258    * modifying the contents of the list, or the values of the properties
259    * of these {@link DynaBean}s. However, it is the application's
260    * responsibility to persist any such changes back to the database,
261    * if it so desires.</p>
262    *
263    * @return A <code>List</code> of {@link DynaBean} instances
264    */
 
265  5 toggle public List getRows() {
266   
267  5 return (this.rows);
268   
269    }
270   
271   
272    // ------------------------------------------------------ Protected Methods
273   
274   
275    /**
276    * <p>Copy the column values for each row in the specified
277    * <code>ResultSet</code> into a newly created {@link DynaBean}, and add
278    * this bean to the list of {@link DynaBean}s that will later by
279    * returned by a call to <code>getRows()</code>.</p>
280    *
281    * @param resultSet The <code>ResultSet</code> whose data is to be
282    * copied
283    *
284    * @exception SQLException if an error is encountered copying the data
285    */
 
286  12 toggle protected void copy(ResultSet resultSet) throws SQLException {
287   
288  12 int cnt = 0;
289  70 while (resultSet.next() && (limit < 0 || cnt++ < limit) ) {
290  58 DynaBean bean = createDynaBean();
291  812 for (int i = 0; i < properties.length; i++) {
292  754 String name = properties[i].getName();
293  754 Object value = getObject(resultSet, name);
294  754 bean.set(name, value);
295    }
296  58 rows.add(bean);
297    }
298   
299    }
300   
301   
302    /**
303    * <p>Create and return a new {@link DynaBean} instance to be used for
304    * representing a row in the underlying result set.</p>
305    *
306    * @return A new <code>DynaBean</code> instance
307    */
 
308  58 toggle protected DynaBean createDynaBean() {
309   
310  58 return (new BasicDynaBean(this));
311   
312    }
313   
314   
315    }