View Javadoc
1 /* 2 * The Apache Software License, Version 1.1 3 * 4 * Copyright (c) 1999 The Apache Software Foundation. All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. The end-user documentation included with the redistribution, if 20 * any, must include the following acknowlegement: 21 * "This product includes software developed by the 22 * Apache Software Foundation (http://www.apache.org/)." 23 * Alternately, this acknowlegement may appear in the software itself, 24 * if and wherever such third-party acknowlegements normally appear. 25 * 26 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software 27 * Foundation" must not be used to endorse or promote products derived 28 * from this software without prior written permission. For written 29 * permission, please contact apache@apache.org. 30 * 31 * 5. Products derived from this software may not be called "Apache" 32 * nor may "Apache" appear in their names without prior written 33 * permission of the Apache Group. 34 * 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This software consists of voluntary contributions made by many 50 * individuals on behalf of the Apache Software Foundation. For more 51 * information on the Apache Software Foundation, please see 52 * <http://www.apache.org/>;. 53 * 54 */ 55 56 package org.apache.commons.jelly.tags.sql; 57 58 import java.sql.*; 59 import java.util.*; 60 import javax.servlet.jsp.jstl.sql.Result; 61 62 /*** 63 * <p>This class creates a cached version of a <tt>ResultSet</tt>. 64 * It's represented as a <tt>Result</tt> implementation, capable of 65 * returing an array of <tt>Row</tt> objects containing a <tt>Column</tt> 66 * instance for each column in the row.</p> 67 * 68 * <p>Note -- this is a private copy for the RI to avoid making the 69 * corresponding class in javax.servlet.* public.</p> 70 * 71 * @author Hans Bergsten 72 * @author Justyna Horwat 73 */ 74 75 public class ResultImpl implements Result { 76 private List rowMap; 77 private List rowByIndex; 78 private String[] columnNames; 79 private boolean isLimited; 80 81 /*** 82 * This constructor reads the ResultSet and saves a cached 83 * copy. 84 * 85 * @param rs an open <tt>ResultSet</tt>, positioned before the first 86 * row 87 * @param startRow, beginning row to be cached 88 * @param maxRows, query maximum rows limit 89 * @exception if a database error occurs 90 */ 91 public ResultImpl(ResultSet rs, int startRow, int maxRows) 92 throws SQLException { 93 94 rowMap = new ArrayList(); 95 rowByIndex = new ArrayList(); 96 97 ResultSetMetaData rsmd = rs.getMetaData(); 98 int noOfColumns = rsmd.getColumnCount(); 99 100 // Create the column name array 101 columnNames = new String[noOfColumns]; 102 for (int i = 1; i <= noOfColumns; i++) { 103 columnNames[i-1] = rsmd.getColumnName(i); 104 } 105 106 // Throw away all rows upto startRow 107 for (int i = 0; i < startRow; i++) { 108 rs.next(); 109 } 110 111 // Process the remaining rows upto maxRows 112 int processedRows = 0; 113 while (rs.next()) { 114 if ((maxRows != -1) && (processedRows == maxRows)) { 115 isLimited = true; 116 break; 117 } 118 Object[] columns = new Object[noOfColumns]; 119 SortedMap columnMap = 120 new TreeMap(String.CASE_INSENSITIVE_ORDER); 121 122 // JDBC uses 1 as the lowest index! 123 for (int i = 1; i <= noOfColumns; i++) { 124 Object value = rs.getObject(i); 125 if (rs.wasNull()) { 126 value = null; 127 } 128 columns[i-1] = value; 129 columnMap.put(columnNames[i-1], value); 130 } 131 rowMap.add(columnMap); 132 rowByIndex.add(columns); 133 processedRows++; 134 } 135 } 136 137 /*** 138 * This constructor is given a List of Maps where each Map represents a Row of data. 139 * This constructor is typically used to create a Mock Object representing a result set. 140 * 141 * @param listOfMaps is a list of Maps where a Map represents a Row keyed by the column name 142 */ 143 public ResultImpl(List listOfMaps) { 144 145 rowMap = new ArrayList(); 146 rowByIndex = new ArrayList(); 147 isLimited = false; 148 149 // lets build up a Set of all the unique column names 150 HashSet keySet = new HashSet(); 151 for (Iterator iter = listOfMaps.iterator(); iter.hasNext(); ) { 152 Map row = (Map) iter.next(); 153 keySet.addAll( row.keySet() ); 154 } 155 156 // Create the column name array 157 int noOfColumns = keySet.size(); 158 columnNames = new String[noOfColumns]; 159 int i = 0; 160 for (Iterator iter = keySet.iterator(); iter.hasNext(); i++ ) { 161 columnNames[i] = (String) iter.next(); 162 } 163 164 // Now add each row to the result set 165 for (Iterator iter = listOfMaps.iterator(); iter.hasNext(); ) { 166 Map row = (Map) iter.next(); 167 168 Object[] columns = new Object[noOfColumns]; 169 SortedMap columnMap = 170 new TreeMap(String.CASE_INSENSITIVE_ORDER); 171 172 for (i = 0; i < noOfColumns; i++) { 173 String columnName = columnNames[i]; 174 Object value = row.get(columnName); 175 columns[i] = value; 176 columnMap.put(columnName, value); 177 } 178 rowMap.add(columnMap); 179 rowByIndex.add(columns); 180 } 181 } 182 183 /*** 184 * Returns an array of SortedMap objects. The SortedMap 185 * object key is the ColumnName and the value is the ColumnValue. 186 * SortedMap was created using the CASE_INSENSITIVE_ORDER 187 * Comparator so the key is the case insensitive representation 188 * of the ColumnName. 189 * 190 * @return an array of Map, or null if there are no rows 191 */ 192 public SortedMap[] getRows() { 193 if (rowMap == null) { 194 return null; 195 } 196 197 //should just be able to return SortedMap[] object 198 return (SortedMap []) rowMap.toArray(new SortedMap[0]); 199 } 200 201 202 /*** 203 * Returns an array of Object[] objects. The first index 204 * designates the Row, the second the Column. The array 205 * stores the value at the specified row and column. 206 * 207 * @return an array of Object[], or null if there are no rows 208 */ 209 public Object[][] getRowsByIndex() { 210 if (rowByIndex == null) { 211 return null; 212 } 213 214 //should just be able to return Object[][] object 215 return (Object [][])rowByIndex.toArray(new Object[0][0]); 216 } 217 218 /*** 219 * Returns an array of String objects. The array represents 220 * the names of the columns arranged in the same order as in 221 * the getRowsByIndex() method. 222 * 223 * @return an array of String[] 224 */ 225 public String[] getColumnNames() { 226 return columnNames; 227 } 228 229 /*** 230 * Returns the number of rows in the cached ResultSet 231 * 232 * @return the number of cached rows, or -1 if the Result could 233 * not be initialized due to SQLExceptions 234 */ 235 public int getRowCount() { 236 if (rowMap == null) { 237 return -1; 238 } 239 return rowMap.size(); 240 } 241 242 /*** 243 * Returns true of the query was limited by a maximum row setting 244 * 245 * @return true if the query was limited by a MaxRows attribute 246 */ 247 public boolean isLimitedByMaxRows() { 248 return isLimited; 249 } 250 251 }

This page was automatically generated by Maven