KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > displaytag > decorator > TotalTableDecorator


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 java.text.MessageFormat JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import javax.servlet.jsp.PageContext JavaDoc;
21
22 import org.apache.commons.lang.ObjectUtils;
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.displaytag.exception.DecoratorException;
27 import org.displaytag.model.HeaderCell;
28 import org.displaytag.model.TableModel;
29
30
31 /**
32  * A table decorator which adds rows with totals (for column with the "total" attribute set) and subtotals (grouping by
33  * the column with a group="1" attribute).
34  * @author Fabrizio Giustina
35  * @version $Id$
36  */

37 public class TotalTableDecorator extends TableDecorator
38 {
39
40     /**
41      * Logger.
42      */

43     private static Log log = LogFactory.getLog(TotalTableDecorator.class);
44
45     /**
46      * total amount.
47      */

48     private Map JavaDoc grandTotals = new HashMap JavaDoc();
49
50     /**
51      * total amount for current group.
52      */

53     private Map JavaDoc subTotals = new HashMap JavaDoc();
54
55     /**
56      * Previous values needed for grouping.
57      */

58     private Map JavaDoc previousValues = new HashMap JavaDoc();
59
60     /**
61      * Name of the property used for grouping.
62      */

63     private String JavaDoc groupPropertyName;
64
65     /**
66      * Label used for subtotals. Default: "{0} total".
67      */

68     private String JavaDoc subtotalLabel = "{0} subtotal";
69
70     /**
71      * Label used for totals. Default: "Total".
72      */

73     private String JavaDoc totalLabel = "Total";
74
75     /**
76      * Setter for <code>subtotalLabel</code>.
77      * @param subtotalLabel The subtotalLabel to set.
78      */

79     public void setSubtotalLabel(String JavaDoc subtotalLabel)
80     {
81         this.subtotalLabel = subtotalLabel;
82     }
83
84     /**
85      * Setter for <code>totalLabel</code>.
86      * @param totalLabel The totalLabel to set.
87      */

88     public void setTotalLabel(String JavaDoc totalLabel)
89     {
90         this.totalLabel = totalLabel;
91     }
92
93     /**
94      * @see org.displaytag.decorator.Decorator#init(PageContext, Object, TableModel)
95      */

96     public void init(PageContext JavaDoc context, Object JavaDoc decorated, TableModel tableModel)
97     {
98         super.init(context, decorated, tableModel);
99
100         // reset
101
groupPropertyName = null;
102         grandTotals.clear();
103         subTotals.clear();
104         previousValues.clear();
105
106         for (Iterator JavaDoc it = tableModel.getHeaderCellList().iterator(); it.hasNext();)
107         {
108             HeaderCell cell = (HeaderCell) it.next();
109             if (cell.getGroup() == 1)
110             {
111                 groupPropertyName = cell.getBeanPropertyName();
112             }
113         }
114     }
115
116     public String JavaDoc startRow()
117     {
118         String JavaDoc subtotalRow = null;
119
120         if (groupPropertyName != null)
121         {
122             Object JavaDoc groupedPropertyValue = evaluate(groupPropertyName);
123             Object JavaDoc previousGroupedPropertyValue = previousValues.get(groupPropertyName);
124             // subtotals
125
if (previousGroupedPropertyValue != null
126                 && !ObjectUtils.equals(previousGroupedPropertyValue, groupedPropertyValue))
127             {
128                 subtotalRow = createTotalRow(false);
129             }
130             previousValues.put(groupPropertyName, groupedPropertyValue);
131         }
132
133         for (Iterator JavaDoc it = tableModel.getHeaderCellList().iterator(); it.hasNext();)
134         {
135             HeaderCell cell = (HeaderCell) it.next();
136             if (cell.isTotaled())
137             {
138                 String JavaDoc totalPropertyName = cell.getBeanPropertyName();
139                 Number JavaDoc amount = (Number JavaDoc) evaluate(totalPropertyName);
140
141                 Number JavaDoc previousSubTotal = (Number JavaDoc) subTotals.get(totalPropertyName);
142                 Number JavaDoc previousGrandTotals = (Number JavaDoc) grandTotals.get(totalPropertyName);
143
144                 subTotals.put(totalPropertyName, new Double JavaDoc((previousSubTotal != null
145                     ? previousSubTotal.doubleValue()
146                     : 0)
147                     + (amount != null ? amount.doubleValue() : 0)));
148
149                 grandTotals.put(totalPropertyName, new Double JavaDoc((previousGrandTotals != null ? previousGrandTotals
150                     .doubleValue() : 0)
151                     + (amount != null ? amount.doubleValue() : 0)));
152             }
153         }
154
155         return subtotalRow;
156     }
157
158     /**
159      * After every row completes we evaluate to see if we should be drawing a new total line and summing the results
160      * from the previous group.
161      * @return String
162      */

163     public final String JavaDoc finishRow()
164     {
165         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(1000);
166
167         // Grand totals...
168
if (getViewIndex() == ((List JavaDoc) getDecoratedObject()).size() - 1)
169         {
170             if (groupPropertyName != null)
171             {
172                 buffer.append(createTotalRow(false));
173             }
174             buffer.append(createTotalRow(true));
175         }
176         return buffer.toString();
177
178     }
179
180     protected String JavaDoc createTotalRow(boolean grandTotal)
181     {
182         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(1000);
183         buffer.append("\n<tr class=\"total\">"); //$NON-NLS-1$
184

185         List JavaDoc headerCells = tableModel.getHeaderCellList();
186
187         for (Iterator JavaDoc it = headerCells.iterator(); it.hasNext();)
188         {
189             HeaderCell cell = (HeaderCell) it.next();
190             String JavaDoc cssClass = ObjectUtils.toString(cell.getHtmlAttributes().get("class"));
191
192             buffer.append("<td"); //$NON-NLS-1$
193
if (StringUtils.isNotEmpty(cssClass))
194             {
195                 buffer.append(" class=\""); //$NON-NLS-1$
196
buffer.append(cssClass);
197                 buffer.append("\""); //$NON-NLS-1$
198
}
199             buffer.append(">"); //$NON-NLS-1$
200

201             if (cell.isTotaled())
202             {
203                 String JavaDoc totalPropertyName = cell.getBeanPropertyName();
204                 Object JavaDoc total = grandTotal ? grandTotals.get(totalPropertyName) : subTotals.get(totalPropertyName);
205
206                 DisplaytagColumnDecorator[] decorators = cell.getColumnDecorators();
207                 for (int j = 0; j < decorators.length; j++)
208                 {
209                     try
210                     {
211                         total = decorators[j].decorate(total, this.getPageContext(), tableModel.getMedia());
212                     }
213                     catch (DecoratorException e)
214                     {
215                         log.warn(e.getMessage(), e);
216                         // ignore, use undecorated value for totals
217
}
218                 }
219                 buffer.append(total);
220             }
221             else if (groupPropertyName != null && groupPropertyName.equals(cell.getBeanPropertyName()))
222             {
223                 buffer.append(grandTotal ? totalLabel : MessageFormat.format(subtotalLabel, new Object JavaDoc[]{previousValues
224                     .get(groupPropertyName)}));
225             }
226
227             buffer.append("</td>"); //$NON-NLS-1$
228

229         }
230
231         buffer.append("</tr>"); //$NON-NLS-1$
232

233         // reset subtotal
234
this.subTotals.clear();
235
236         return buffer.toString();
237     }
238
239 }
240
Popular Tags