KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > josql > contrib > JoSQLSwingTableModel


1 /*
2  * Copyright 2004-2005 Gary Bentley
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may
5  * not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */

15 package org.josql.contrib;
16
17 import java.util.List JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.SortedMap JavaDoc;
20
21 import javax.swing.table.TableModel JavaDoc;
22
23 import javax.swing.event.TableModelListener JavaDoc;
24 import javax.swing.event.TableModelEvent JavaDoc;
25
26 import org.josql.QueryExecutionException;
27 import org.josql.QueryParseException;
28 import org.josql.Query;
29 import org.josql.QueryResults;
30
31 import org.josql.internal.Utilities;
32
33 import org.josql.expressions.SelectItemExpression;
34
35 /**
36  * A table model suitable for use with Swing JTable.
37  *
38  * This is basically just an extension to {@link Query} that allows the
39  * results to be iterated over, thereby providing the ability for objects to be reported on
40  * that are held in memory.
41  * <p>
42  * One limitation here is that the SQL query must return columns rather than the objects
43  * since the values need to be mapped by the renderer and editor. For example:
44  * <pre>
45  * SELECT lastModified,
46  * name
47  * FROM java.io.File
48  * WHERE name LIKE '%.html'
49  * </pre>
50  * <p>
51  * This query would work but it should be noted that the select "columns" (since they do not have
52  * aliases assigned) will be labeled 1, 2, X and so on.
53  * You can assign aliases to the "columns" and then use them in the report definition file.
54  * <p>
55  * In terms of events fired,
56  * Last Modified By: $Author$<br />
57  * Last Modified On: $Date$<br />
58  * Current Revision: $Revision$<br />
59  */

60 public class JoSQLSwingTableModel extends Query implements TableModel JavaDoc
61 {
62
63     private QueryResults results = null;
64     private List JavaDoc listeners = new ArrayList JavaDoc ();
65
66     public JoSQLSwingTableModel ()
67     {
68
69
70     }
71
72     /**
73      * Parse the SQL. Note: this will cause a TableModelEvent to be fired to all
74      * registered listeners indicating that the table header has changed.
75      *
76      * @param sql The SQL.
77      * @throws QueryParseException If the sql cannot be parsed or if the query will not return
78      * columns.
79      */

80     public void parse (String JavaDoc sql)
81                    throws QueryParseException
82     {
83
84     this.results = null;
85
86     super.parse (sql);
87
88     if (this.isWantObjects ())
89     {
90
91         throw new QueryParseException ("Only SQL statements that return columns (not the objects passed in) can be used.");
92
93     }
94
95     this.notifyListeners (new TableModelEvent JavaDoc (this,
96                            TableModelEvent.HEADER_ROW));
97
98     }
99
100     private void notifyListeners (TableModelEvent JavaDoc ev)
101     {
102
103     for (int i = 0; i < this.listeners.size (); i++)
104     {
105
106         TableModelListener JavaDoc l = (TableModelListener JavaDoc) this.listeners.get (i);
107
108         l.tableChanged (ev);
109
110     }
111
112     }
113
114     /**
115      * Re-order the columns according to the column indices provided in <b>dirs</b>.
116      *
117      * @param objs The objects to reorder.
118      * @param dirs The columns to order by.
119      * @return The results.
120      * @throws QueryExecutionException If something goes wrong during execution of the
121      * query.
122      * @throws QueryParseException If the column indices are out of range for the statement.
123      * @see Query#reorder(List,SortedMap)
124      */

125     public QueryResults reorder (List JavaDoc objs,
126                  SortedMap JavaDoc dirs)
127                              throws QueryExecutionException,
128                                        QueryParseException
129     {
130
131     // Get the order bys.
132
this.results = super.reorder (objs,
133                       dirs);
134
135     // Notify the listeners that the data has changed.
136
this.notifyListeners (new TableModelEvent JavaDoc (this));
137
138     return this.results;
139
140     }
141
142     /**
143      * Re-order the columns according to the string representation provided by <b>orderBys</b>.
144      *
145      * @param objs The objects to reorder.
146      * @param orderBys The columns to order by.
147      * @return The results.
148      * @throws QueryExecutionException If something goes wrong during execution of the
149      * query.
150      * @throws QueryParseException If the column indices are out of range for the statement.
151      * @see Query#reorder(List,String)
152      */

153     public QueryResults reorder (List JavaDoc objs,
154                  String JavaDoc orderBys)
155                              throws QueryParseException,
156                     QueryExecutionException
157     {
158
159     this.results = super.reorder (objs,
160                       orderBys);
161
162     // Notify the listeners that the data has changed.
163
this.notifyListeners (new TableModelEvent JavaDoc (this));
164
165     return this.results;
166
167     }
168
169     /**
170      * Exectute the query and return the results. A reference to the results is also held to
171      * allow them to be iterated over. Note: this will cause a TableModelEvent to be fired to all
172      * registered listeners indicating that ALL the table data has changed.
173      *
174      * @param l The List of objects to execute the query on.
175      * @return The results.
176      * @throws QueryExecutionException If the query cannot be executed, or if the query
177      * is set to return objects rather than "columns".
178      */

179     public QueryResults execute (List JavaDoc l)
180                              throws QueryExecutionException
181     {
182
183     this.results = super.execute (l);
184
185     // Notify the listeners that the data has changed.
186
this.notifyListeners (new TableModelEvent JavaDoc (this));
187
188     return this.results;
189
190     }
191
192     /**
193      * Get any results, will be null unless {@link #execute(List)} has been called.
194      *
195      * @return The results.
196      */

197     public QueryResults getResults ()
198     {
199
200     return this.results;
201
202     }
203
204     /**
205      * Clear any results.
206      */

207     public void clearResults ()
208     {
209
210     this.results = null;
211
212     }
213
214     /**
215      * Get the name of the column, if the query has not yet been parsed then <code>null</code> is returned,
216      * if the column does not have an alias then "ind + 1" is returned.
217      *
218      * @return The column name.
219      */

220     public String JavaDoc getColumnName (int ind)
221     {
222
223     List JavaDoc cs = this.getColumns ();
224
225     if ((cs == null)
226         ||
227         (ind > (cs.size () - 1))
228        )
229     {
230
231         return null;
232
233     }
234
235     SelectItemExpression s = (SelectItemExpression) cs.get (ind);
236
237     String JavaDoc al = s.getAlias ();
238
239     if (al == null)
240     {
241
242         return (ind + 1) + "";
243
244     }
245
246     return al;
247
248     }
249
250     /**
251      * The expected class of the object at column <b>i</b>.
252      *
253      * @return The class of the column.
254      */

255     public Class JavaDoc getColumnClass (int i)
256     {
257
258     List JavaDoc cs = this.getColumns ();
259
260     if ((cs == null)
261         ||
262         (i > (cs.size () - 1))
263        )
264     {
265
266         return null;
267
268     }
269
270     SelectItemExpression s = (SelectItemExpression) cs.get (i);
271
272     try
273     {
274
275         return Utilities.getObjectClass (s.getExpectedReturnType (this));
276
277     } catch (Exception JavaDoc e) {
278
279         // Painful, but not much we can do.
280
return null;
281
282     }
283
284     }
285
286     /**
287      * Get the object at row <b>r</b>, column <b>c</b>.
288      *
289      * @param r The row.
290      * @param c The column.
291      * @return The object at that location.
292      */

293     public Object JavaDoc getValueAt (int r,
294                   int c)
295     {
296
297     if ((this.results == null)
298         ||
299         (r > (this.results.getResults ().size () - 1))
300        )
301     {
302
303         return null;
304
305     }
306
307     Object JavaDoc o = this.results.getResults ().get (r);
308
309     if (o instanceof List JavaDoc)
310     {
311
312         List JavaDoc l = (List JavaDoc) o;
313
314         if (c > (l.size () - 1))
315         {
316
317         return null;
318
319         }
320
321         return l.get (c);
322
323     }
324
325     if (c > 0)
326     {
327
328         return null;
329
330     }
331
332     return o;
333
334     }
335
336     /**
337      * Not supported, always throws a: {@link UnsupportedOperationException}.
338      *
339      * @param v The object to set at the location.
340      * @param r The row.
341      * @param c The column.
342      * @throws UnsupportedOperationException Not supported.
343      */

344     public void setValueAt (Object JavaDoc v,
345                 int r,
346                 int c)
347                 throws UnsupportedOperationException JavaDoc
348     {
349
350     // Do nothing for now...
351
throw new UnsupportedOperationException JavaDoc ("This method not supported for: " +
352                          this.getClass ().getName ());
353
354     }
355
356     /**
357      * Cells are not editable since we do not store the results separately.
358      *
359      * @param r The row.
360      * @param c The columns.
361      * @return Always returns <code>false</code>.
362      */

363     public boolean isCellEditable (int r,
364                    int c)
365     {
366
367     // Not sure what's best here... for now make them non-editable.
368
return false;
369
370     }
371
372     /**
373      * Number of rows.
374      *
375      * @return The row count.
376      */

377     public int getRowCount ()
378     {
379
380     if (this.results == null)
381     {
382
383         return 0;
384
385     }
386
387     return this.results.getResults ().size ();
388
389     }
390
391     /**
392      * Get the number of columns.
393      *
394      * @return The column count, returns 0 if the query has not yet been parsed.
395      */

396     public int getColumnCount ()
397     {
398
399     // See if we have any columns.
400
if (this.getColumns () == null)
401     {
402
403         return 0;
404
405     }
406
407     return this.getColumns ().size ();
408
409     }
410
411     public void removeTableModelListener (TableModelListener JavaDoc l)
412     {
413
414     this.listeners.remove (l);
415
416     }
417
418     public void addTableModelListener (TableModelListener JavaDoc l)
419     {
420     
421     if (this.listeners.contains (l))
422     {
423
424         return;
425
426     }
427
428     this.listeners.add (l);
429
430     }
431
432 }
433
Popular Tags