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