1 /**
2 * Licensed under the Artistic License; you may not use this file
3 * except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://displaytag.sourceforge.net/license.html
7 *
8 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 */
12 package org.displaytag.export;
13
14 import java.io.IOException;
15 import java.io.Writer;
16 import java.util.Iterator;
17
18 import javax.servlet.jsp.JspException;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.displaytag.model.Column;
24 import org.displaytag.model.ColumnIterator;
25 import org.displaytag.model.HeaderCell;
26 import org.displaytag.model.Row;
27 import org.displaytag.model.RowIterator;
28 import org.displaytag.model.TableModel;
29
30
31 /**
32 * <p>
33 * Base abstract class for simple export views.
34 * </p>
35 * <p>
36 * A class that extends BaseExportView simply need to provide delimiters for rows and columns.
37 * </p>
38 * @author Fabrizio Giustina
39 * @version $Revision: 1081 $ ($Author: fgiust $)
40 */
41 public abstract class BaseExportView implements TextExportView
42 {
43
44 /**
45 * logger.
46 */
47 private static Log log = LogFactory.getLog(BaseExportView.class);
48
49 /**
50 * TableModel to render.
51 */
52 private TableModel model;
53
54 /**
55 * export full list?
56 */
57 private boolean exportFull;
58
59 /**
60 * include header in export?
61 */
62 private boolean header;
63
64 /**
65 * decorate export?
66 */
67 private boolean decorated;
68
69 /**
70 * @see org.displaytag.export.ExportView#setParameters(org.displaytag.model.TableModel, boolean, boolean, boolean)
71 */
72 public void setParameters(TableModel tableModel, boolean exportFullList, boolean includeHeader,
73 boolean decorateValues)
74 {
75 this.model = tableModel;
76 this.exportFull = exportFullList;
77 this.header = includeHeader;
78 this.decorated = decorateValues;
79 }
80
81 /**
82 * String to add before a row.
83 * @return String
84 */
85 protected String getRowStart()
86 {
87 return null;
88 }
89
90 /**
91 * String to add after a row.
92 * @return String
93 */
94 protected String getRowEnd()
95 {
96 return null;
97 }
98
99 /**
100 * String to add before a cell.
101 * @return String
102 */
103 protected String getCellStart()
104 {
105 return null;
106 }
107
108 /**
109 * String to add after a cell.
110 * @return String
111 */
112 protected abstract String getCellEnd();
113
114 /**
115 * String to add to the top of document.
116 * @return String
117 */
118 protected String getDocumentStart()
119 {
120 return null;
121 }
122
123 /**
124 * String to add to the end of document.
125 * @return String
126 */
127 protected String getDocumentEnd()
128 {
129 return null;
130 }
131
132 /**
133 * always append cell end string?
134 * @return boolean
135 */
136 protected abstract boolean getAlwaysAppendCellEnd();
137
138 /**
139 * always append row end string?
140 * @return boolean
141 */
142 protected abstract boolean getAlwaysAppendRowEnd();
143
144 /**
145 * can be implemented to escape values for different output.
146 * @param value original column value
147 * @return escaped column value
148 */
149 protected abstract String escapeColumnValue(Object value);
150
151 /**
152 * Write table header.
153 * @return String rendered header
154 */
155 protected String doHeaders()
156 {
157
158 final String ROW_START = getRowStart();
159 final String ROW_END = getRowEnd();
160 final String CELL_START = getCellStart();
161 final String CELL_END = getCellEnd();
162 final boolean ALWAYS_APPEND_CELL_END = getAlwaysAppendCellEnd();
163
164 StringBuffer buffer = new StringBuffer(1000);
165
166 Iterator iterator = this.model.getHeaderCellList().iterator();
167
168 // start row
169 if (ROW_START != null)
170 {
171 buffer.append(ROW_START);
172 }
173
174 while (iterator.hasNext())
175 {
176 HeaderCell headerCell = (HeaderCell) iterator.next();
177
178 String columnHeader = headerCell.getTitle();
179
180 if (columnHeader == null)
181 {
182 columnHeader = StringUtils.capitalize(headerCell.getBeanPropertyName());
183 }
184
185 columnHeader = escapeColumnValue(columnHeader);
186
187 if (CELL_START != null)
188 {
189 buffer.append(CELL_START);
190 }
191
192 if (columnHeader != null)
193 {
194 buffer.append(columnHeader);
195 }
196
197 if (CELL_END != null && (ALWAYS_APPEND_CELL_END || iterator.hasNext()))
198 {
199 buffer.append(CELL_END);
200 }
201 }
202
203 // end row
204 if (ROW_END != null)
205 {
206 buffer.append(ROW_END);
207 }
208
209 return buffer.toString();
210
211 }
212
213 /**
214 * @see org.displaytag.export.TextExportView#doExport(java.io.Writer)
215 */
216 public void doExport(Writer out) throws IOException, JspException
217 {
218 if (log.isDebugEnabled())
219 {
220 log.debug(getClass().getName());
221 }
222
223 final String DOCUMENT_START = getDocumentStart();
224 final String DOCUMENT_END = getDocumentEnd();
225 final String ROW_START = getRowStart();
226 final String ROW_END = getRowEnd();
227 final String CELL_START = getCellStart();
228 final String CELL_END = getCellEnd();
229 final boolean ALWAYS_APPEND_CELL_END = getAlwaysAppendCellEnd();
230 final boolean ALWAYS_APPEND_ROW_END = getAlwaysAppendRowEnd();
231
232 // document start
233 write(out, DOCUMENT_START);
234
235 if (this.header)
236 {
237 write(out, doHeaders());
238 }
239
240 // get the correct iterator (full or partial list according to the exportFull field)
241 RowIterator rowIterator = this.model.getRowIterator(this.exportFull);
242
243 // iterator on rows
244 while (rowIterator.hasNext())
245 {
246 Row row = rowIterator.next();
247
248 if (this.model.getTableDecorator() != null)
249 {
250
251 String stringStartRow = this.model.getTableDecorator().startRow();
252 write(out, stringStartRow);
253 }
254
255 // iterator on columns
256 ColumnIterator columnIterator = row.getColumnIterator(this.model.getHeaderCellList());
257
258 write(out, ROW_START);
259
260 while (columnIterator.hasNext())
261 {
262 Column column = columnIterator.nextColumn();
263
264 // Get the value to be displayed for the column
265 String value = escapeColumnValue(column.getValue(this.decorated));
266
267 write(out, CELL_START);
268
269 write(out, value);
270
271 if (ALWAYS_APPEND_CELL_END || columnIterator.hasNext())
272 {
273 write(out, CELL_END);
274 }
275
276 }
277 if (ALWAYS_APPEND_ROW_END || rowIterator.hasNext())
278 {
279 write(out, ROW_END);
280 }
281 }
282
283 // document end
284 write(out, DOCUMENT_END);
285
286 }
287
288 /**
289 * Write a String, checking for nulls value.
290 * @param out output writer
291 * @param string String to be written
292 * @throws IOException thrown by out.write
293 */
294 private void write(Writer out, String string) throws IOException
295 {
296 if (string != null)
297 {
298 out.write(string);
299 }
300 }
301
302 /**
303 * @see org.displaytag.export.TextExportView#outputPage()
304 */
305 public boolean outputPage()
306 {
307 return false;
308 }
309 }