1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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 }