View Javadoc

1   /*
2    * $Id: WebTable.java 497654 2007-01-19 00:21:57Z rgielen $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts2.components.table;
22  
23  import java.io.Writer;
24  import java.util.ArrayList;
25  import java.util.Iterator;
26  import java.util.NoSuchElementException;
27  
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  import javax.swing.table.TableModel;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.struts2.views.annotations.StrutsTag;
35  import org.apache.struts2.views.annotations.StrutsTagAttribute;
36  import org.apache.struts2.StrutsException;
37  import org.apache.struts2.components.GenericUIBean;
38  import org.apache.struts2.components.table.renderer.CellRenderer;
39  
40  import com.opensymphony.xwork2.util.ValueStack;
41  
42  @StrutsTag(name="table", tldTagClass="org.apache.struts2.views.jsp.ui.table.WebTableTag", description="Instantiate a JavaBean and place it in the context")
43  public class WebTable extends GenericUIBean {
44      private static final Log LOG = LogFactory.getLog(WebTable.class);
45  
46      final public static String TEMPLATE = "table";
47  
48      protected String sortOrder = SortableTableModel.NONE;
49      protected String modelName = null;
50      protected TableModel model = null;
51      protected WebTableColumn[] columns = null;
52      protected boolean sortableAttr = false;
53      protected int sortColumn = -1;
54      protected int curRow = 0;
55  
56      public WebTable(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
57          super(stack, request, response);
58      }
59  
60      protected String getDefaultTemplate() {
61          return TEMPLATE;
62      }
63  
64      public boolean end(Writer writer, String body) {
65          if (sortableAttr && model instanceof SortableTableModel) {
66              LOG.debug("we are looking for " + getSortColumnLinkName());
67  
68              String sortColumn = request.getParameter(getSortColumnLinkName());
69              String sortOrder = request.getParameter(getSortOrderLinkName());
70  
71              try {
72                  if ((sortColumn != null) || (sortOrder != null)) {
73                      if (sortColumn != null) {
74                          try {
75                              this.sortColumn = Integer.parseInt(sortColumn);
76                          } catch (Exception ex) {
77                              if (LOG.isDebugEnabled()) {
78                                  LOG.debug("coudn't convert column, take default");
79                              }
80                          }
81                      }
82  
83                      if (sortOrder != null) {
84                          this.sortOrder = sortOrder;
85                      }
86                  } else {
87                      LOG.debug("no sorting info in the request");
88                  }
89  
90                  if (this.sortColumn >= 0) {
91                      LOG.debug("we have the sortColumn " + Integer.toString(this.sortColumn));
92                      LOG.debug("we have the sortOrder " + this.sortOrder);
93  
94                      try {
95                          ((SortableTableModel) model).sort(this.sortColumn, this.sortOrder);
96                      } catch (Exception ex) {
97                          if (LOG.isDebugEnabled()) {
98                              LOG.debug("couldn't sort the data");
99                          }
100                     }
101 
102                     LOG.debug("we just sorted the data");
103                 }
104             } catch (Exception e) {
105                 throw new StrutsException("Error with WebTable: " + toString(e), e);
106             }
107         }
108 
109         return super.end(writer, body);
110     }
111 
112     public WebTableColumn getColumn(int index) {
113         try {
114             return (columns[index]);
115         } catch (Exception E) {
116             //blank
117         }
118 
119         return null;
120     }
121 
122     protected void evaluateExtraParams() {
123         if (modelName != null) {
124             modelName = findString(modelName);
125 
126             Object obj = stack.findValue(this.modelName);
127 
128             if (obj instanceof TableModel) {
129                 setModel((TableModel) obj);
130             }
131         }
132 
133         super.evaluateExtraParams();
134     }
135 
136     protected int getNumberOfVisibleColumns() {
137         int count = 0;
138 
139         for (int i = 0; i < columns.length; ++i) {
140             if (!columns[i].isHidden()) {
141                 ++count;
142             }
143         }
144 
145         return count;
146     }
147 
148     public int getColumnCount() {
149         return (columns.length);
150     }
151 
152     public void setColumnDisplayName(int column, String displayName) {
153         columns[column].setDisplayName(displayName);
154     }
155 
156     public void getColumnDisplayName(int column) {
157         columns[column].getDisplayName();
158     }
159 
160     public void setColumnHidden(int column, boolean hide) {
161         columns[column].setHidden(hide);
162     }
163 
164     public boolean isColumnHidden(int column) {
165         return columns[column].isHidden();
166     }
167 
168     public void setColumnRenderer(int column, CellRenderer renderer) {
169         columns[column].setRenderer(renderer);
170     }
171 
172     public CellRenderer getColumnRenderer(int column) {
173         return columns[column].getRenderer();
174     }
175 
176     public WebTableColumn[] getColumns() {
177         return columns;
178     }
179 
180     public String[] getFormattedRow(int row) {
181         ArrayList data = new ArrayList(getNumberOfVisibleColumns());
182 
183         for (int i = 0; i < getColumnCount(); ++i) {
184             if (columns[i].isVisible()) {
185                 data.add(columns[i].getRenderer().renderCell(this, model.getValueAt(row, i), row, i));
186             }
187         }
188 
189         return (String[]) data.toArray(new String[0]);
190     }
191 
192     public void setModel(TableModel model) {
193         this.model = model;
194         columns = new WebTableColumn[this.model.getColumnCount()];
195 
196         for (int i = 0; i < columns.length; ++i) {
197             columns[i] = new WebTableColumn(this.model.getColumnName(i), i);
198         }
199 
200         if ((sortableAttr) && !(this.model instanceof SortableTableModel)) {
201             this.model = new SortFilterModel(this.model);
202         }
203     }
204 
205     public TableModel getModel() {
206         return (model);
207     }
208 
209     /***
210      * The name of model to use
211      * @s.tagattribute required="true" type="String"
212      */
213     public void setModelName(String modelName) {
214         this.modelName = modelName;
215     }
216 
217     public String getModelName() {
218         return modelName;
219     }
220 
221     public Object getRawData(int row, int column) {
222         return model.getValueAt(row, column);
223     }
224 
225     public Iterator getRawDataRowIterator() {
226         return new WebTableRowIterator(this, WebTableRowIterator.RAW_DATA);
227     }
228 
229     public Object[] getRow(int row) {
230         ArrayList data = new ArrayList(getNumberOfVisibleColumns());
231 
232         for (int i = 0; i < getColumnCount(); ++i) {
233             if (columns[i].isVisible()) {
234                 data.add(model.getValueAt(row, i));
235             }
236         }
237 
238         return data.toArray(new Object[0]);
239     }
240 
241     public int getRowCount() {
242         return model.getRowCount();
243     }
244 
245     public Iterator getRowIterator() {
246         return new WebTableRowIterator(this);
247     }
248 
249     @StrutsTagAttribute(description="Index of column to sort data by", type="Integer")
250     public void setSortColumn(int sortColumn) {
251         this.sortColumn = sortColumn;
252     }
253 
254     public int getSortColumn() {
255         if (model instanceof SortableTableModel) {
256             return ((SortableTableModel) model).getSortedColumnNumber();
257         }
258 
259         return -1;
260     }
261 
262     public String getSortColumnLinkName() {
263         return "WEBTABLE_" + modelName + "_SORT_COLUMN";
264     }
265 
266     @StrutsTagAttribute(description="Set sort order. Allowed values are NONE, ASC and DESC", defaultValue="NONE")
267     public void setSortOrder(String sortOrder) {
268         if (sortOrder.equals(SortableTableModel.NONE)) {
269             this.sortOrder = SortableTableModel.NONE;
270         } else if (sortOrder.equals(SortableTableModel.DESC)) {
271             this.sortOrder = SortableTableModel.DESC;
272         } else if (sortOrder.equals(SortableTableModel.ASC)) {
273             this.sortOrder = SortableTableModel.ASC;
274         } else {
275             this.sortOrder = SortableTableModel.NONE;
276         }
277     }
278 
279     public String getSortOrder() {
280         if ((model instanceof SortableTableModel) && (getSortColumn() >= 0)) {
281             return ((SortableTableModel) model).getSortedDirection(getSortColumn());
282         }
283 
284         return SortableTableModel.NONE;
285     }
286 
287     public String getSortOrderLinkName() {
288         return "WEBTABLE_" + modelName + "_SORT_ORDER";
289     }
290 
291     @StrutsTagAttribute(description="Whether the table should be sortable. Requires that model implements " +
292                 "org.apache.struts2.components.table.SortableTableModel if set to true.", type="Boolean", defaultValue="false")
293     public void setSortable(boolean sortable) {
294         sortableAttr = sortable;
295 
296         if ((sortableAttr) && (model != null) && !(model instanceof SortableTableModel)) {
297             model = new SortFilterModel(model);
298         }
299     }
300 
301     public boolean isSortable() {
302         return sortableAttr;
303     }
304 
305     /***
306      * inner class to iteratoe over a row of the table.
307      * It can return formatted data, using the columnRenderer
308      * for the column or it can return the raw data.
309      */
310     public class WebTableRowIterator implements Iterator {
311         public static final int FORMATTED_DATA = 0;
312         public static final int RAW_DATA = 1;
313         protected WebTable _table;
314         protected int _curRow = 0;
315         protected int _mode = 0;
316 
317         protected WebTableRowIterator(WebTable table) {
318             this(table, FORMATTED_DATA);
319         }
320 
321         protected WebTableRowIterator(WebTable table, int mode) {
322             _table = table;
323             _mode = mode;
324         }
325 
326         public boolean hasNext() {
327             if (_table == null) {
328                 return false;
329             }
330 
331             return (_table.getRowCount() > _curRow);
332         }
333 
334         public Object next() throws NoSuchElementException {
335             if (_table == null) {
336                 throw new NoSuchElementException("WebTable is null");
337             }
338 
339             if (!hasNext()) {
340                 throw new NoSuchElementException("Beyond end of WebTable");
341             }
342 
343             if (_mode == RAW_DATA) {
344                 return _table.getRow(_curRow++);
345             }
346 
347             return _table.getFormattedRow(_curRow++);
348         }
349 
350         public void remove() throws UnsupportedOperationException, IllegalStateException {
351             throw new UnsupportedOperationException("Remove not supported in WebTable");
352         }
353     }
354 }