001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * 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,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.crosstabs.fill.calculation;
029:
030: import net.sf.jasperreports.engine.JRException;
031: import net.sf.jasperreports.engine.JRVariable;
032: import net.sf.jasperreports.engine.fill.AbstractValueProvider;
033: import net.sf.jasperreports.engine.fill.JRCalculable;
034: import net.sf.jasperreports.engine.fill.JRDistinctCountExtendedIncrementerFactory;
035: import net.sf.jasperreports.engine.fill.JRExtendedIncrementer;
036: import net.sf.jasperreports.engine.fill.JRExtendedIncrementerFactory;
037:
038: /**
039: * Crosstab measure definition.
040: *
041: * @author Lucian Chirita (lucianc@users.sourceforge.net)
042: * @version $Id: MeasureDefinition.java 1311 2006-06-23 09:19:26Z teodord $
043: */
044: public class MeasureDefinition {
045: protected final byte calculation;
046: protected final JRExtendedIncrementerFactory incrementerFactory;
047: protected final Class valueClass;
048: protected final boolean isSystemDefined;
049:
050: /**
051: * Create a measure definition.
052: *
053: * @param valueClass the value class
054: * @param calculation the calculation type
055: * @param incrementerFactory the incrementer factory
056: */
057: public MeasureDefinition(Class valueClass, byte calculation,
058: JRExtendedIncrementerFactory incrementerFactory) {
059: this (valueClass, calculation, incrementerFactory, false);
060: }
061:
062: protected MeasureDefinition(Class valueClass, byte calculation,
063: JRExtendedIncrementerFactory incrementerFactory,
064: boolean isSystemDefined) {
065: this .valueClass = valueClass;
066: this .calculation = calculation;
067: this .incrementerFactory = incrementerFactory;
068: this .isSystemDefined = isSystemDefined;
069: }
070:
071: /**
072: * Creates a helper measure for a specific calculation.
073: *
074: * @param measure the measure
075: * @param helperCalculation the calculation
076: * @return the helper measure having the specified calculation
077: */
078: public static MeasureDefinition createHelperMeasure(
079: MeasureDefinition measure, byte helperCalculation) {
080: return new MeasureDefinition(measure.valueClass,
081: helperCalculation, measure.incrementerFactory, true);
082: }
083:
084: /**
085: * Creates a helper measure for a distinct count calculation.
086: *
087: * @param measure the measure
088: * @return the helper measure having the specified calculation
089: */
090: public static MeasureDefinition createDistinctCountHelperMeasure(
091: MeasureDefinition measure) {
092: return new MeasureDefinition(
093: measure.valueClass,
094: JRVariable.CALCULATION_NOTHING,
095: JRDistinctCountExtendedIncrementerFactory.getInstance(),
096: true);
097: }
098:
099: /**
100: * Returns the calculation type.
101: *
102: * @return the calculation type
103: */
104: public byte getCalculation() {
105: return calculation;
106: }
107:
108: /**
109: * Returns the incrementer factory.
110: *
111: * @return the incrementer factory
112: */
113: public JRExtendedIncrementerFactory getIncrementerFactory() {
114: return incrementerFactory;
115: }
116:
117: /**
118: * Returns the incrementer used for this measure.
119: *
120: * @return the incrementer used for this measure
121: */
122: public JRExtendedIncrementer getIncrementer() {
123: return incrementerFactory.getExtendedIncrementer(calculation);
124: }
125:
126: protected boolean isSystemDefined() {
127: return isSystemDefined;
128: }
129:
130: /**
131: * Returns the measure value class.
132: *
133: * @return the measure value class
134: */
135: public Class getValueClass() {
136: return valueClass;
137: }
138:
139: /**
140: * Measure value provider.
141: */
142: protected static final AbstractValueProvider VALUE_PROVIDER = new AbstractValueProvider() {
143: public Object getValue(JRCalculable calculable) {
144: return calculable.getValue();
145: }
146: };
147:
148: /**
149: * An accumulated value of a crosstab measure.
150: *
151: * @author Lucian Chirita (lucianc@users.sourceforge.net)
152: */
153: public class MeasureValue implements JRCalculable {
154: private Object value;
155: private MeasureValue[] helpers;
156: private boolean initialized;
157: private JRExtendedIncrementer incrementer;
158:
159: /**
160: * Initializes the value.
161: */
162: public MeasureValue() {
163: this .value = null;
164: this .helpers = new MeasureValue[HELPER_SIZE];
165: incrementer = getIncrementer();
166:
167: init();
168: }
169:
170: protected void init() {
171: this .value = incrementer.initialValue();
172: setInitialized(true);
173: }
174:
175: /**
176: * Accumulates a value.
177: *
178: * @param addValue the value
179: * @throws JRException
180: */
181: public void addValue(Object addValue) throws JRException {
182: this .value = incrementer.increment(this , addValue,
183: VALUE_PROVIDER);
184: setInitialized(false);
185: }
186:
187: /**
188: * Accumulates another measure value.
189: * <p>
190: * This is used for total calculations, when two accumulated values are combined into a total.
191: *
192: * @param measureValue the measure value
193: * @throws JRException
194: */
195: public void addValue(MeasureValue measureValue)
196: throws JRException {
197: if (!measureValue.isInitialized()) {
198: this .value = incrementer.combine(this , measureValue,
199: VALUE_PROVIDER);
200: setInitialized(false);
201: }
202: }
203:
204: public Object getValue() {
205: return value;
206: }
207:
208: public String toString() {
209: return String.valueOf(getValue());
210: }
211:
212: /**
213: * Sets a helper variable.
214: *
215: * @param helperVariable the helper variable
216: * @param type the helper type
217: * @return the previous helper variable for the type
218: */
219: public MeasureValue setHelper(MeasureValue helperVariable,
220: byte type) {
221: MeasureValue old = helpers[type];
222: helpers[type] = helperVariable;
223: return old;
224: }
225:
226: public boolean isInitialized() {
227: return initialized;
228: }
229:
230: public Object getIncrementedValue() {
231: return value;
232: }
233:
234: public JRCalculable getHelperVariable(byte helperType) {
235: return helpers[helperType];
236: }
237:
238: public void setInitialized(boolean isInitialized) {
239: this.initialized = isInitialized;
240: }
241: }
242: }
|