001 package com.sptci.rwt.webui;
002
003 import java.util.List;
004
005 import com.sptci.echo2.Dimensions;
006 import com.sptci.echo2.table.ColumnMetaData;
007 import com.sptci.echo2.table.DefaultPageableTableModel;
008
009 import com.sptci.rwt.Column;
010 import com.sptci.rwt.ConnectionManager;
011 import com.sptci.rwt.QueryExecutor;
012 import com.sptci.rwt.QueryException;
013 import com.sptci.rwt.Row;
014 import com.sptci.rwt.Rows;
015
016 /**
017 * A custom table model used to display {@link com.sptci.rwt.Row} objects.
018 *
019 * <p>© Copyright 2007 <a href='http://sptci.com/' target='_new'>Sans Pareil Technologies, Inc.</a></p>
020 * @author Rakesh Vidyadharan 2007-10-04
021 * @version $Id: RowTableModel.java 4123 2008-05-25 21:49:01Z rakesh $
022 */
023 public class RowTableModel extends DefaultPageableTableModel<Row>
024 {
025 /** The SQL statement that is to be executed to fetch the results. */
026 protected final String query;
027
028 /** The maximum number of records to fetch from the database. */
029 protected final int maxRows;
030
031 /**
032 * The maximum number of characters to display in a column.
033 *
034 * @since Version 1.3
035 */
036 protected final int maxColumnLength;
037
038 /** The connection manager to use to fetch database connections. */
039 protected final ConnectionManager manager;
040
041 /**
042 * Default constructor. No special actions required.
043 *
044 * @since Version 1.2
045 */
046 protected RowTableModel()
047 {
048 query = null;
049 manager = null;
050 maxRows = 0;
051 maxColumnLength = 0;
052 }
053
054 /**
055 * Create a new instance of the table model using the specified collection
056 * of {@link com.sptci.rwt.Row} objects.
057 *
058 * @see #fetchData
059 * @see #processColumns
060 * @param query The sql statement that is to be executed to fetch any
061 * additional pages of data.
062 * @param maxRows The maximum number of rows to fetch from the
063 * result set.
064 * @param maxColumnLength The maximum number of characters to display in
065 * a column.
066 * @param manager The manager to use to fetch database connections.
067 * @throws QueryException If errors are encountered while executing
068 * the {@link #query}.
069 */
070 public RowTableModel( final String query, final int maxRows,
071 final int maxColumnLength, final ConnectionManager manager )
072 throws QueryException
073 {
074 super();
075 this.query = query;
076 this.maxRows = maxRows;
077 this.maxColumnLength = maxColumnLength;
078 this.manager = manager;
079 setPageSize( Dimensions.getInt( this, "pageSize" ) );
080 processColumns();
081 }
082
083 /**
084 * Fetch the data from the database by executing {@link #query}.
085 *
086 * @see nextapp.echo2.app.table.AbstractTableModel#fireTableDataChanged
087 * @see com.sptci.rwt.QueryExecutor
088 * @throws QueryException If errors are encountered while executing
089 * the {@link #query}.
090 */
091 protected void fetchData() throws QueryException
092 {
093 try
094 {
095 QueryExecutor executor = new QueryExecutor( manager );
096
097 final Rows rows = executor.execute(
098 getQuery(), maxRows, page, pageSize, maxColumnLength );
099 totalRows = rows.getTotalRows();
100 if ( ( maxRows > 0 ) && ( totalRows > maxRows ) )
101 {
102 totalRows = maxRows;
103 }
104
105 data.clear();
106 data.addAll( rows.getRows() );
107 fireTableDataChanged();
108 }
109 catch ( Throwable t )
110 {
111 throw new QueryException( "Error fetching data for query", t );
112 }
113 }
114
115 /**
116 * Over-ridden to set the proper column meta data using the column
117 * information from the row object.
118 */
119 @Override
120 protected void processColumns()
121 {
122 if ( data.size() == 0 ) return;
123 final Row row = data.get( 0 );
124
125 final List<Column> columns = row.getColumns();
126 if ( columns.size() == 0 ) return;
127
128 for ( Column column : columns )
129 {
130 final ColumnMetaData cmd =
131 new ColumnMetaData( column.getName(), String.class );
132 this.columns.add( cmd );
133 }
134 }
135
136 /**
137 * Return the column name to display at the specified index.
138 *
139 * @param column The column index for which the name is required.
140 * @return The name of the column.
141 */
142 @Override
143 public String getColumnName( final int column )
144 {
145 return columns.get( column ).getName();
146 }
147
148 /**
149 * Return the value to display at the coordinates specified.
150 *
151 * @param column The column index.
152 * @param row The row index.
153 * @return The value for the coordinates.
154 * @throws RuntimeException If the indices are invalid.
155 */
156 @Override
157 public Object getValueAt( final int column, final int row )
158 {
159 if ( column < 0 || column >= getColumnCount() )
160 {
161 throw new IllegalArgumentException( "Illegal column index: " + column );
162 }
163 if ( row < 0 || row >= getRowCount() )
164 {
165 throw new IllegalArgumentException( "Illegal row index: " + row );
166 }
167
168 Row r = data.get( row );
169 Object value = r.getColumns().get( column ).getContent();
170
171 return value;
172 }
173
174 /**
175 * Returns {@link #query}.
176 *
177 * @return The value/reference of/to query.
178 */
179 public String getQuery()
180 {
181 return query;
182 }
183
184 /**
185 * Returns {@link #maxRows}.
186 *
187 * @return The value/reference of/to maxRows.
188 */
189 public int getMaxRows()
190 {
191 return maxRows;
192 }
193 /**
194 * Returns {@link #maxColumnLength}.
195 *
196 * @since Version 1.3
197 * @return The value/reference of/to maxColumnLength.
198 */
199 public int getMaxColumnLength()
200 {
201 return maxColumnLength;
202 }
203
204 /**
205 * Returns {@link #manager}.
206 *
207 * @return The value/reference of/to manager.
208 */
209 public ConnectionManager getManager()
210 {
211 return manager;
212 }
213
214 /**
215 * Returns {@link #totalRows}.
216 *
217 * @return The value/reference of/to totalRows.
218 */
219 public long getTotalRows()
220 {
221 return totalRows;
222 }
223
224 /**
225 * Set {@link #page}.
226 *
227 * @see #fetchData
228 * @param page The value to set.
229 */
230 public void setPage( final int page )
231 {
232 this.page = page;
233 fetchData();
234 }
235
236 /**
237 * Set {@link #pageSize}.
238 *
239 * @see #fetchData
240 * @param pageSize The value to set.
241 */
242 public void setPageSize( final int pageSize )
243 {
244 this.pageSize = pageSize;
245 fetchData();
246 }
247 }