001 /**
002 * ========================================
003 * JFreeReport : a free Java report library
004 * ========================================
005 *
006 * Project Info: http://reporting.pentaho.org/
007 *
008 * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009 *
010 * This library is free software; you can redistribute it and/or modify it under the terms
011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
012 * either version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License along with this
019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020 * Boston, MA 02111-1307, USA.
021 *
022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023 * in the United States and other countries.]
024 *
025 * ------------
026 * $Id: SQLReportData.java,v 1.7 2007/06/10 15:54:22 taqua Exp $
027 * ------------
028 * (C) Copyright 2000-2005, by Object Refinery Limited.
029 * (C) Copyright 2005-2007, by Pentaho Corporation.
030 */
031 package org.jfree.report.modules.data.sql;
032
033 import java.sql.ResultSet;
034 import java.sql.ResultSetMetaData;
035 import java.sql.SQLException;
036
037 import org.jfree.report.DataSourceException;
038 import org.jfree.report.ReportData;
039
040 /**
041 * Creation-Date: 19.02.2006, 17:37:42
042 *
043 * @author Thomas Morgner
044 */
045 public class SQLReportData implements ReportData
046 {
047 private ResultSet resultSet;
048 private int rowCount;
049 private int columnCount;
050 private int cursor;
051 private String[] columnNames;
052 private boolean labelMapping;
053
054 public SQLReportData(final ResultSet resultSet,
055 final boolean labelMapping)
056 throws SQLException, DataSourceException
057 {
058 if (resultSet == null)
059 {
060 throw new NullPointerException();
061 }
062 if (resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY)
063 {
064 throw new IllegalArgumentException();
065 }
066 this.resultSet = resultSet;
067 this.labelMapping = labelMapping;
068
069 if (resultSet.last())
070 {
071 rowCount = resultSet.getRow();
072 }
073 else
074 {
075 rowCount = 0;
076 }
077
078 final ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
079 columnCount = resultSetMetaData.getColumnCount();
080 columnNames = new String[columnCount];
081 for (int i = 1; i <= columnCount; i++)
082 {
083 if (labelMapping)
084 {
085 columnNames[i - 1] = resultSetMetaData.getColumnLabel(i);
086 }
087 else
088 {
089 columnNames[i - 1] = resultSetMetaData.getColumnName(i);
090 }
091 }
092
093 if (resultSet.first() == false)
094 {
095 throw new DataSourceException("Unable to reset the dataset.");
096 }
097 cursor = 0;
098 }
099
100 public boolean isLabelMapping()
101 {
102 return labelMapping;
103 }
104
105 public int getRowCount() throws DataSourceException
106 {
107 return rowCount;
108 }
109
110 /**
111 * This operation checks, whether a call to next will be likely to succeed. If
112 * there is a next data row, this should return true.
113 *
114 * @return
115 * @throws org.jfree.report.DataSourceException
116 *
117 */
118 public boolean isAdvanceable() throws DataSourceException
119 {
120 return cursor < rowCount;
121 }
122
123 public int getColumnCount() throws DataSourceException
124 {
125 return columnCount;
126 }
127
128 public boolean setCursorPosition(final int row) throws DataSourceException
129 {
130 if (row < 0)
131 {
132 throw new DataSourceException("Negative row number is not valid");
133 }
134 if (row > rowCount)
135 {
136 return false;
137 // throw new DataSourceException("OutOfBounds:");
138 }
139
140 try
141 {
142 if (cursor == 0)
143 {
144 resultSet.beforeFirst();
145 return true;
146 }
147
148 if (resultSet.absolute(row))
149 {
150 cursor = row;
151 return true;
152 }
153 return false;
154 //throw new DataSourceException("Unable to scroll the resultset.");
155 }
156 catch (SQLException e)
157 {
158 throw new DataSourceException("Failed to move the cursor: ", e);
159 }
160 }
161
162 public boolean next() throws DataSourceException
163 {
164 try
165 {
166 if (resultSet.next())
167 {
168 cursor += 1;
169 return true;
170 }
171 else
172 {
173 return false;
174 }
175 }
176 catch (SQLException e)
177 {
178 throw new DataSourceException("Failed to move the cursor: ", e);
179 }
180 }
181
182 public void close() throws DataSourceException
183 {
184 try
185 {
186 resultSet.close();
187 }
188 catch (SQLException e)
189 {
190 throw new DataSourceException("Failed to close the resultset: ", e);
191 }
192 }
193
194 public String getColumnName(final int column) throws DataSourceException
195 {
196 return columnNames[column];
197 }
198
199 public Object get(final int column) throws DataSourceException
200 {
201 if (isReadable() == false)
202 {
203 throw new DataSourceException("Cannot read from this datasource");
204 }
205
206 try
207 {
208 final Object retval = resultSet.getObject(column + 1);
209 if (resultSet.wasNull())
210 {
211 return null;
212 }
213 return retval;
214 }
215 catch (SQLException e)
216 {
217 throw new DataSourceException("Failed to query data", e);
218 }
219 }
220
221 public int getCursorPosition() throws DataSourceException
222 {
223 return cursor;
224 }
225
226 public boolean isReadable() throws DataSourceException
227 {
228 return cursor > 0 && rowCount > 0;
229 }
230 }