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: * TotalGroupSumQuotientFunction.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:
035: /**
036: * A report function that calculates the quotient of two summed fields (columns) from the report's data row. This
037: * function produces a global total. The total sum of the group is known when the group processing starts and the report
038: * is not performing a prepare-run. The sum is calculated in the prepare run and recalled in the printing run.
039: * <p/>
040: * The function can be used in two ways: <ul> <li>to calculate a quotient for the entire report;</li> <li>to calculate a
041: * quotient within a particular group;</li> </ul> This function expects its input values to be either java.lang.Number
042: * instances or Strings that can be parsed to java.lang.Number instances using a java.text.DecimalFormat.
043: * <p/>
044: * The function undestands tree parameters. The <code>dividend</code> parameter is required and denotes the name of an
045: * ItemBand-field which gets summed up as dividend. The <code>divisor</code> parameter is required and denotes the name
046: * of an ItemBand-field which gets summed up as divisor.
047: * <p/>
048: * The parameter <code>group</code> denotes the name of a group. When this group is started, the counter gets reseted to
049: * null. This parameter is optional.
050: *
051: * @author Thomas Morgner
052: */
053: public class TotalGroupSumQuotientFunction extends AbstractFunction {
054: /**
055: * Internal function to compute the dividend.
056: */
057: private TotalGroupSumFunction dividendFunction;
058: /**
059: * Internal function to compute the divisor.
060: */
061: private TotalGroupSumFunction divisorFunction;
062: /**
063: * The scale-property defines the precission of the divide-operation.
064: */
065: private int scale;
066: /**
067: * The rounding-property defines the precission of the divide-operation.
068: */
069: private int roundingMode;
070:
071: /**
072: * Constructs a new function.
073: * <p/>
074: * Initially the function has no name...be sure to assign one before using the function.
075: */
076: public TotalGroupSumQuotientFunction() {
077: scale = 14;
078: roundingMode = BigDecimal.ROUND_HALF_UP;
079: dividendFunction = new TotalGroupSumFunction();
080: divisorFunction = new TotalGroupSumFunction();
081: }
082:
083: /**
084: * Receives notification that the report has started.
085: *
086: * @param event the event.
087: */
088: public void reportInitialized(final ReportEvent event) {
089: dividendFunction.reportInitialized(event);
090: divisorFunction.reportInitialized(event);
091: }
092:
093: /**
094: * Receives notification that a group has started.
095: *
096: * @param event the event.
097: */
098: public void groupStarted(final ReportEvent event) {
099: dividendFunction.groupStarted(event);
100: divisorFunction.groupStarted(event);
101: }
102:
103: /**
104: * Receives notification that a row of data is being processed.
105: *
106: * @param event the event.
107: */
108: public void itemsAdvanced(final ReportEvent event) {
109: dividendFunction.itemsAdvanced(event);
110: divisorFunction.itemsAdvanced(event);
111: }
112:
113: /**
114: * Returns the name of the group to be totalled.
115: *
116: * @return the group name.
117: */
118: public String getGroup() {
119: return divisorFunction.getGroup();
120: }
121:
122: /**
123: * Defines the name of the group to be totalled. If the name is null, all groups are totalled.
124: *
125: * @param group the group name.
126: */
127: public void setGroup(final String group) {
128: this .divisorFunction.setGroup(group);
129: this .dividendFunction.setGroup(group);
130: }
131:
132: /**
133: * Return the current function value. <P> The value depends (obviously) on the function implementation. For example,
134: * a page counting function will return the current page number.
135: *
136: * @return The value of the function.
137: */
138: public Object getValue() {
139: final BigDecimal dividend = (BigDecimal) dividendFunction
140: .getValue();
141: final BigDecimal divisor = (BigDecimal) divisorFunction
142: .getValue();
143: if (divisor == null || dividend == null
144: || divisor.doubleValue() == 0) {
145: return null;
146: }
147: return dividend.divide(divisor, scale, roundingMode);
148: }
149:
150: /**
151: * Returns the field used as dividend by the function. <P> The field name corresponds to a column name in the report's
152: * data-row.
153: *
154: * @return The field name.
155: */
156: public String getDividend() {
157: return this .dividendFunction.getField();
158: }
159:
160: /**
161: * Returns the field used as divisor by the function. <P> The field name corresponds to a column name in the report's
162: * data row.
163: *
164: * @return The field name.
165: */
166: public String getDivisor() {
167: return this .divisorFunction.getField();
168: }
169:
170: /**
171: * Sets the field name to be used as dividend for the function. <P> The field name corresponds to a column name in the
172: * report's data-row.
173: *
174: * @param dividend the field name (null not permitted).
175: */
176: public void setDividend(final String dividend) {
177: this .dividendFunction.setField(dividend);
178: }
179:
180: /**
181: * Sets the field name to be used as divisor for the function. <P> The field name corresponds to a column name in the
182: * report's data-row.
183: *
184: * @param divisor the field name (null not permitted).
185: */
186: public void setDivisor(final String divisor) {
187: this .divisorFunction.setField(divisor);
188: }
189:
190: /**
191: * Returns the defined rounding mode. This influences the precision of the divide-operation.
192: *
193: * @return the rounding mode.
194: * @see java.math.BigDecimal#divide(java.math.BigDecimal,int)
195: */
196: public int getRoundingMode() {
197: return roundingMode;
198: }
199:
200: /**
201: * Defines the rounding mode. This influences the precision of the divide-operation.
202: *
203: * @param roundingMode the rounding mode.
204: * @see java.math.BigDecimal#divide(java.math.BigDecimal,int)
205: */
206: public void setRoundingMode(final int roundingMode) {
207: this .roundingMode = roundingMode;
208: }
209:
210: /**
211: * Returns the scale for the divide-operation. The scale influences the precision of the division.
212: *
213: * @return the scale.
214: */
215: public int getScale() {
216: return scale;
217: }
218:
219: /**
220: * Defines the scale for the divide-operation. The scale influences the precision of the division.
221: *
222: * @param scale the scale.
223: */
224: public void setScale(final int scale) {
225: this .scale = scale;
226: }
227:
228: /**
229: * Defines the function's dependency level. This method forwards all calls to the interal functions.
230: *
231: * @param level the dependency level.
232: * @see Expression#getDependencyLevel()
233: */
234: public void setDependencyLevel(final int level) {
235: super .setDependencyLevel(level);
236: dividendFunction.setDependencyLevel(level);
237: divisorFunction.setDependencyLevel(level);
238: }
239:
240: /**
241: * Defines the ExpressionRune used in this expression. The ExpressionRuntime is set before the expression receives
242: * events or gets evaluated and is unset afterwards. Do not hold references on the runtime or you will create
243: * memory-leaks.
244: *
245: * @param runtime the runtime information for the expression
246: */
247: public void setRuntime(final ExpressionRuntime runtime) {
248: super.setRuntime(runtime);
249: dividendFunction.setRuntime(runtime);
250: divisorFunction.setRuntime(runtime);
251: }
252:
253: }
|