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.decorator; 13 14 import org.displaytag.exception.ObjectLookupException; 15 import org.displaytag.render.TableWriterTemplate; 16 import org.displaytag.util.LookupUtil; 17 import org.displaytag.util.TagConstants; 18 19 20 /** 21 * @author epesh 22 * @author Fabrizio Giustina 23 * @version $Revision: 1084 $ ($Author: fgiust $) 24 */ 25 public abstract class TableDecorator extends Decorator 26 { 27 28 /** 29 * object representing the current row. 30 */ 31 private Object currentRowObject; 32 33 /** 34 * index in displayed list. 35 */ 36 private int viewIndex = -1; 37 38 /** 39 * index in original list. 40 */ 41 private int listIndex = -1; 42 43 /** 44 * Return the index in the displayed list. 45 * @return int index in the displayed list 46 */ 47 public final int getViewIndex() 48 { 49 return this.viewIndex; 50 } 51 52 /** 53 * Return the index in the full list (view index + offset). Note that the index returned if from the <strong>sorted</strong> 54 * list, and not from the original one. 55 * @return int index in the full list 56 */ 57 public final int getListIndex() 58 { 59 return this.listIndex; 60 } 61 62 /** 63 * Get the object representing the current row. 64 * @return Object 65 */ 66 public final Object getCurrentRowObject() 67 { 68 return this.currentRowObject; 69 } 70 71 /** 72 * Initialize the current row. Note this method is also called when sorting a table using a property supplied by the 73 * table decorator, so the method could be called multiple times during rendering. When used to initialize sorting 74 * the method is always called with 0, 0 as currentViewIndex and currentListIndex. 75 * @param rowObject object representing the current row 76 * @param currentViewIndex int index in the displayed list 77 * @param currentListIndex int index in the original list 78 */ 79 public final void initRow(Object rowObject, int currentViewIndex, int currentListIndex) 80 { 81 this.currentRowObject = rowObject; 82 this.viewIndex = currentViewIndex; 83 this.listIndex = currentListIndex; 84 } 85 86 /** 87 * Called at the beginning of a row. Can be subclassed to provide specific data at the beginning of a row 88 * @return null in the default implementation 89 */ 90 public String startRow() 91 { 92 return null; 93 } 94 95 /** 96 * Called at the end of a row. Can be subclassed to provide specific data at the end of a row 97 * @return null in the default implementation 98 */ 99 public String finishRow() 100 { 101 return null; 102 } 103 104 /** 105 * Called at the end of evaluation. Can be subclassed to eventully clean up data. Always remember to also call 106 * super.finish()! 107 */ 108 public void finish() 109 { 110 this.currentRowObject = null; 111 super.finish(); 112 } 113 114 /** 115 * Call back to add an additional row class to the current row. 116 * @return CSS class attribute value for the current row 117 * @since 1.1 118 */ 119 public String addRowClass() 120 { 121 return null; 122 } 123 124 /** 125 * Call back to allow setting an "id" attribute on a row. 126 * @return HTML id attribute value for the current row 127 * @since 1.1 128 */ 129 public String addRowId() 130 { 131 return null; 132 } 133 134 /** 135 * Indicates that we are begining a new group. 136 * @param value of the current cell 137 * @param group number of the current column 138 */ 139 public void startOfGroup(String value, int group) 140 { 141 } 142 143 /** 144 * Called at the end of a group. Can be subclassed to provide specific data at the end of a row. 145 * @param value of the current cell 146 * @param groupThatHasEnded number of the current column 147 */ 148 public void endOfGroup(String value, int groupThatHasEnded) 149 { 150 } 151 152 /** 153 * What value should I display in this cell? The default value for grouped columns is to not display any value if 154 * the cellValue has not changed on an interior iteration. Only invoked for columns that are grouped. 155 * @param cellValue 156 * @param groupingStatus 157 * @return the value to display 158 */ 159 public String displayGroupedValue(String cellValue, short groupingStatus, int columnNumber) 160 { 161 if (groupingStatus == TableWriterTemplate.GROUP_END || groupingStatus == TableWriterTemplate.GROUP_NO_CHANGE) 162 { 163 return TagConstants.EMPTY_STRING; 164 } 165 else 166 { 167 return cellValue; 168 } 169 } 170 171 public boolean isLastRow() 172 { 173 return getListIndex() == this.tableModel.getRowListPage().size() - 1; 174 } 175 176 /** 177 * Shortcut for evaluating properties in the current row object. Can be useful for implementing anonymous decorators 178 * in jsp pages without having to know/import the decorated object Class. 179 * @param propertyName property to lookup in current row object. Can also be a nested or indexed property. 180 * @since 1.1 181 */ 182 protected Object evaluate(String propertyName) 183 { 184 try 185 { 186 return LookupUtil.getBeanProperty(getCurrentRowObject(), propertyName); 187 } 188 catch (ObjectLookupException e) 189 { 190 return null; 191 } 192 } 193 194 }