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 }