001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * ItemSumFunction.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.function;
030:
031: import java.math.BigDecimal;
032:
033: import org.jfree.report.event.ReportEvent;
034: import org.jfree.util.Log;
035:
036: /**
037: * A report function that calculates the sum of one field (column) from the data-row. This function produces a running
038: * total, no global total. For a global sum, use the TotalGroupSumFunction function. The function can be used in two
039: * ways: <ul> <li>to calculate a sum for the entire report;</li> <li>to calculate a sum within a particular group;</li>
040: * </ul> This function expects its input values to be either java.lang.Number instances or Strings that can be parsed to
041: * java.lang.Number instances using a java.text.DecimalFormat.
042: * <p/>
043: * The function undestands two parameters, the <code>field</code> parameter is required and denotes the name of an
044: * ItemBand-field which gets summed up.
045: * <p/>
046: * The parameter <code>group</code> denotes the name of a group. When this group is started, the counter gets reseted to
047: * null.
048: *
049: * @author Thomas Morgner
050: */
051: public class ItemSumFunction extends AbstractFunction {
052: /**
053: * A useful constant representing zero.
054: */
055: protected static final BigDecimal ZERO = new BigDecimal(0.0);
056:
057: /**
058: * The item sum.
059: */
060: private transient BigDecimal sum;
061: /**
062: * The name of the group on which to reset the count. This can be set to null to compute the sum for the whole
063: * report.
064: */
065: private String group;
066: /**
067: * The name of the field from where to read the values.
068: */
069: private String field;
070:
071: /**
072: * Constructs an unnamed function. Make sure to set a Name or function initialisation will fail.
073: */
074: public ItemSumFunction() {
075: sum = ZERO;
076: }
077:
078: /**
079: * Constructs a named function. <P> The field must be defined before using the function.
080: *
081: * @param name The function name.
082: */
083: public ItemSumFunction(final String name) {
084: this ();
085: setName(name);
086: }
087:
088: /**
089: * Receives notification that a new report is about to start. <P> Does nothing.
090: *
091: * @param event Information about the event.
092: */
093: public void reportInitialized(final ReportEvent event) {
094: this .sum = ZERO;
095: }
096:
097: /**
098: * Receives notification that a new group is about to start. If this is the group defined for the function, then the
099: * running total is reset to zero.
100: *
101: * @param event Information about the event.
102: */
103: public void groupStarted(final ReportEvent event) {
104: if (FunctionUtilities.isDefinedGroup(getGroup(), event)) {
105: this .sum = ZERO;
106: }
107: }
108:
109: /**
110: * Returns the group name.
111: *
112: * @return The group name.
113: */
114: public String getGroup() {
115: return group;
116: }
117:
118: /**
119: * Sets the group name. <P> If a group is defined, the running total is reset to zero at the start of every instance
120: * of this group.
121: *
122: * @param name the group name (null permitted).
123: */
124: public void setGroup(final String name) {
125: this .group = name;
126: }
127:
128: /**
129: * Returns the field used by the function. The field name corresponds to a column name in the report's data-row.
130: *
131: * @return The field name.
132: */
133: public String getField() {
134: return field;
135: }
136:
137: /**
138: * Sets the field name for the function. The field name corresponds to a column name in the report's data-row.
139: *
140: * @param field the field name.
141: */
142: public void setField(final String field) {
143: this .field = field;
144: }
145:
146: /**
147: * Receives notification that a row of data is being processed. Reads the data from the field defined for this
148: * function and adds it to the running total. <P> This function assumes that it will find an instance of the Number
149: * class in the column of the data-row specified by the field name.
150: *
151: * @param event Information about the event.
152: */
153: public void itemsAdvanced(final ReportEvent event) {
154: final Object fieldValue = getDataRow().get(getField());
155: if (fieldValue == null) {
156: return;
157: }
158: if (fieldValue instanceof Number == false) {
159: Log
160: .error("ItemSumFunction.advanceItems(): problem adding number.");
161: return;
162: }
163:
164: final Number n = (Number) fieldValue;
165: sum = sum.add(new BigDecimal(n.toString()));
166: }
167:
168: /**
169: * Returns the function value, in this case the running total of a specific column in the report's data-row.
170: *
171: * @return The function value.
172: */
173: public Object getValue() {
174: return sum;
175: }
176:
177: /**
178: * Returns the current sum.
179: *
180: * @return the current sum.
181: */
182: protected BigDecimal getSum() {
183: return sum;
184: }
185:
186: /**
187: * Defines the current sum.
188: *
189: * @param sum the current sum.
190: */
191: protected void setSum(final BigDecimal sum) {
192: if (sum == null) {
193: throw new NullPointerException("Sum must not be null");
194: }
195: this .sum = sum;
196: }
197:
198: /**
199: * Return a completly separated copy of this function. The copy does no longer share any changeable objects with the
200: * original function.
201: *
202: * @return a copy of this function.
203: */
204: public Expression getInstance() {
205: final ItemSumFunction function = (ItemSumFunction) super
206: .getInstance();
207: function.sum = ZERO;
208: return function;
209: }
210:
211: }
|