1 12 package org.displaytag.render; 13 14 import java.text.MessageFormat ; 15 import java.util.ArrayList ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.Map ; 19 20 import javax.servlet.jsp.JspException ; 21 22 import org.apache.commons.lang.ObjectUtils; 23 import org.apache.commons.logging.Log; 24 import org.apache.commons.logging.LogFactory; 25 import org.displaytag.decorator.TableDecorator; 26 import org.displaytag.model.Column; 27 import org.displaytag.model.ColumnIterator; 28 import org.displaytag.model.HeaderCell; 29 import org.displaytag.model.Row; 30 import org.displaytag.model.RowIterator; 31 import org.displaytag.model.TableModel; 32 import org.displaytag.properties.TableProperties; 33 import org.displaytag.util.TagConstants; 34 35 36 48 public abstract class TableWriterTemplate 49 { 50 51 public static final short GROUP_START = -2; 52 53 public static final short GROUP_END = 5; 54 55 public static final short GROUP_START_AND_END = 3; 56 57 public static final short GROUP_NO_CHANGE = 0; 58 59 62 private static Log log = LogFactory.getLog(TableWriterTemplate.class); 63 64 67 private String id; 68 69 79 public void writeTable(TableModel model, String id) throws JspException 80 { 81 try 82 { 83 this.id = id; 85 86 TableProperties properties = model.getProperties(); 87 88 if (log.isDebugEnabled()) 89 { 90 log.debug("[" + this.id + "] writeTable called for table [" + this.id + "]"); 91 } 92 93 boolean noItems = model.getRowListPage().size() == 0; 95 if (noItems && !properties.getEmptyListShowTable()) 96 { 97 writeEmptyListMessage(properties.getEmptyListMessage()); 98 return; 99 } 100 101 if (properties.getAddPagingBannerTop()) 103 { 104 writeTopBanner(model); 106 } 107 108 writeTableOpener(model); 110 111 if (model.getCaption() != null) 113 { 114 writeCaption(model); 115 } 116 117 if (model.getProperties().getShowHeader()) 119 { 120 writeTableHeader(model); 121 } 122 123 if (model.getFooter() != null) 125 { 126 writePreBodyFooter(model); 127 } 128 129 writeTableBodyOpener(model); 131 132 writeTableBody(model); 134 135 writeTableBodyCloser(model); 137 138 if (model.getFooter() != null) 140 { 141 writePostBodyFooter(model); 142 } 143 144 writeTableCloser(model); 146 147 if (model.getTableDecorator() != null) 148 { 149 writeDecoratedTableFinish(model); 150 } 151 152 writeBottomBanner(model); 153 154 if (log.isDebugEnabled()) 155 { 156 log.debug("[" + this.id + "] writeTable end"); 157 } 158 } 159 catch (Exception e) 160 { 161 throw new JspException (e); 162 } 163 } 164 165 170 protected abstract void writeEmptyListMessage(String emptyListMessage) throws Exception ; 171 172 178 protected abstract void writeTopBanner(TableModel model) throws Exception ; 179 180 185 protected abstract void writeTableOpener(TableModel model) throws Exception ; 186 187 192 protected abstract void writeCaption(TableModel model) throws Exception ; 193 194 199 protected abstract void writeTableHeader(TableModel model) throws Exception ; 200 201 206 protected abstract void writePreBodyFooter(TableModel model) throws Exception ; 207 208 213 protected abstract void writeTableBodyOpener(TableModel model) throws Exception ; 214 215 217 222 protected abstract void writeTableBodyCloser(TableModel model) throws Exception ; 223 224 229 protected abstract void writePostBodyFooter(TableModel model) throws Exception ; 230 231 236 protected abstract void writeTableCloser(TableModel model) throws Exception ; 237 238 243 protected abstract void writeDecoratedTableFinish(TableModel model) throws Exception ; 244 245 250 protected abstract void writeBottomBanner(TableModel model) throws Exception ; 251 252 259 private void writeTableBody(TableModel model) throws Exception 260 { 261 RowIterator rowIterator = model.getRowIterator(false); 263 264 TableDecorator tableDecorator = model.getTableDecorator(); 266 Row previousRow = null; 267 Row currentRow = null; 268 Row nextRow = null; 269 Map previousRowValues = new HashMap (10); 270 Map currentRowValues = new HashMap (10); 271 Map nextRowValues = new HashMap (10); 272 273 while (nextRow != null || rowIterator.hasNext()) 274 { 275 if (currentRow == null) 277 { 278 currentRow = rowIterator.next(); 279 } 280 else 281 { 282 previousRow = currentRow; 283 currentRow = nextRow; 284 } 285 286 if (previousRow != null) 287 { 288 previousRowValues.putAll(currentRowValues); 289 } 290 if (!nextRowValues.isEmpty()) 291 { 292 currentRowValues.putAll(nextRowValues); 293 } 294 else 296 { 297 ColumnIterator columnIterator = currentRow.getColumnIterator(model.getHeaderCellList()); 298 if (log.isDebugEnabled()) 300 { 301 log.debug(" creating ColumnIterator on " + model.getHeaderCellList()); 302 } 303 while (columnIterator.hasNext()) 304 { 305 Column column = columnIterator.nextColumn(); 306 307 column.initialize(); 309 CellStruct struct = new CellStruct(column, column.getChoppedAndLinkedValue()); 310 currentRowValues.put(new Integer (column.getHeaderCell().getColumnNumber()), struct); 311 } 312 } 313 314 nextRowValues.clear(); 315 nextRow = rowIterator.hasNext() ? rowIterator.next() : null; 317 if (nextRow != null) 318 { 319 ColumnIterator columnIterator = nextRow.getColumnIterator(model.getHeaderCellList()); 320 if (log.isDebugEnabled()) 322 { 323 log.debug(" creating ColumnIterator on " + model.getHeaderCellList()); 324 } 325 while (columnIterator.hasNext()) 326 { 327 Column column = columnIterator.nextColumn(); 328 column.initialize(); 329 CellStruct struct = new CellStruct(column, column.getChoppedAndLinkedValue()); 331 nextRowValues.put(new Integer (column.getHeaderCell().getColumnNumber()), struct); 332 } 333 } 334 if (tableDecorator != null) 336 { 337 tableDecorator.initRow(currentRow.getObject(), currentRow.getRowNumber(), currentRow.getRowNumber() 338 + rowIterator.getPageOffset()); 339 } 340 341 if (tableDecorator != null) 342 { 343 writeDecoratedRowStart(model); 344 } 345 writeRowOpener(currentRow); 347 348 Iterator headerCellsIter = model.getHeaderCellList().iterator(); 349 boolean hasReachedGroupEnd = false; 350 ArrayList structsForRow = new ArrayList (model.getHeaderCellList().size()); 351 while (headerCellsIter.hasNext()) 352 { 353 HeaderCell header = (HeaderCell) headerCellsIter.next(); 354 355 CellStruct struct = (CellStruct) currentRowValues.get(new Integer (header.getColumnNumber())); 357 struct.decoratedValue = struct.bodyValue; 358 if (header.getGroup() != -1) 360 { 361 CellStruct prior = (CellStruct) previousRowValues.get(new Integer (header.getColumnNumber())); 362 CellStruct next = (CellStruct) nextRowValues.get(new Integer (header.getColumnNumber())); 363 String priorBodyValue = prior != null ? prior.bodyValue : null; 365 String nextBodyValue = next != null ? next.bodyValue : null; 366 short groupingValue = groupColumns(struct.bodyValue, priorBodyValue, nextBodyValue); 367 hasReachedGroupEnd = hasReachedGroupEnd 368 || groupingValue == GROUP_END 369 || groupingValue == GROUP_NO_CHANGE; 370 371 if (tableDecorator != null) 372 { 373 switch (groupingValue) 374 { 375 case GROUP_START : 376 tableDecorator.startOfGroup(struct.bodyValue, header.getGroup()); 377 break; 378 case GROUP_END : 379 tableDecorator.endOfGroup(struct.bodyValue, header.getGroup()); 380 break; 381 case GROUP_START_AND_END : 382 tableDecorator.startOfGroup(struct.bodyValue, header.getGroup()); 383 tableDecorator.endOfGroup(struct.bodyValue, header.getGroup()); 384 break; 385 default : 386 break; 387 } 388 } 389 if (tableDecorator != null) 390 { 391 struct.decoratedValue = tableDecorator.displayGroupedValue(struct.bodyValue, groupingValue); 392 } 393 else if (groupingValue == GROUP_END || groupingValue == GROUP_NO_CHANGE) 394 { 395 struct.decoratedValue = TagConstants.EMPTY_STRING; 396 } 397 } 398 structsForRow.add(struct); 399 } 400 401 for (Iterator iterator = structsForRow.iterator(); iterator.hasNext();) 402 { 403 CellStruct struct = (CellStruct) iterator.next(); 404 writeColumnOpener(struct.column); 405 writeColumnValue(struct.decoratedValue, struct.column); 406 writeColumnCloser(struct.column); 407 } 408 409 if (model.isEmpty()) 410 { 411 if (log.isDebugEnabled()) 412 { 413 log.debug("[" + this.id + "] table has no columns"); 414 } 415 writeRowWithNoColumns(currentRow.getObject().toString()); 417 } 418 419 writeRowCloser(currentRow); 421 if (model.getTableDecorator() != null) 423 { 424 writeDecoratedRowFinish(model); 425 } 426 } 427 428 if (model.getRowListPage().size() == 0) 430 { 431 writeEmptyListRowMessage(MessageFormat.format( 432 model.getProperties().getEmptyListRowMessage(), 433 new Object []{new Integer (model.getNumberOfColumns())})); 434 } 435 } 436 437 440 441 446 protected abstract void writeDecoratedRowStart(TableModel model) throws Exception ; 447 448 453 protected abstract void writeRowOpener(Row row) throws Exception ; 454 455 460 protected abstract void writeColumnOpener(Column column) throws Exception ; 461 462 468 protected abstract void writeColumnValue(Object value, Column column) throws Exception ; 469 470 475 protected abstract void writeColumnCloser(Column column) throws Exception ; 476 477 482 protected abstract void writeRowWithNoColumns(String value) throws Exception ; 483 484 489 protected abstract void writeRowCloser(Row row) throws Exception ; 490 491 496 protected abstract void writeDecoratedRowFinish(TableModel model) throws Exception ; 497 498 503 protected abstract void writeEmptyListRowMessage(String message) throws Exception ; 504 505 511 private short groupColumns(String value, String previous, String next) 512 { 513 short groupingKey = GROUP_NO_CHANGE; 514 if (next == null || !ObjectUtils.equals(value, next)) 515 { 516 groupingKey += GROUP_END; 518 } 519 520 if (previous == null || !ObjectUtils.equals(value, previous)) 521 { 522 groupingKey += GROUP_START; 524 } 525 return groupingKey; 526 } 527 528 static class CellStruct 529 { 530 531 Column column; 532 533 String bodyValue; 534 535 String decoratedValue; 536 537 public CellStruct(Column theColumn, String bodyValueParam) 538 { 539 this.column = theColumn; 540 this.bodyValue = bodyValueParam; 541 } 542 } 543 } 544 | Popular Tags |