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:
029: /*
030: * Contributors:
031: * Peter Severin - peter_p_s@users.sourceforge.net
032: */
033: package net.sf.jasperreports.engine.fill;
034:
035: import java.util.Map;
036:
037: import net.sf.jasperreports.engine.JRException;
038: import net.sf.jasperreports.engine.JRExpression;
039: import net.sf.jasperreports.engine.JRVariable;
040:
041: /**
042: * @author Teodor Danciu (teodord@users.sourceforge.net)
043: * @version $Id: JRCalculator.java 1470 2006-11-08 16:07:35Z teodord $
044: */
045: public class JRCalculator implements JRFillExpressionEvaluator {
046:
047: /**
048: *
049: */
050: protected Map parsm = null;
051: protected Map fldsm = null;
052: protected Map varsm = null;
053: protected JRFillVariable[] variables = null;
054: protected JRFillGroup[] groups = null;
055: protected JRFillElementDataset[] datasets = null;
056:
057: private JRFillVariable pageNumber = null;
058: private JRFillVariable columnNumber = null;
059:
060: /**
061: * The expression evaluator
062: */
063: private final JREvaluator evaluator;
064:
065: /**
066: * Creates a calculator using an expression evaluator.
067: *
068: * @param evaluator the expression evaluator
069: */
070: protected JRCalculator(JREvaluator evaluator) {
071: this .evaluator = evaluator;
072: }
073:
074: /**
075: * Initializes the calculator.
076: *
077: * @param dataset the dataset this calculator is used for
078: * @throws JRException
079: */
080: protected void init(JRFillDataset dataset) throws JRException {
081: parsm = dataset.parametersMap;
082: fldsm = dataset.fieldsMap;
083: varsm = dataset.variablesMap;
084: variables = dataset.variables;
085: groups = dataset.groups;
086: datasets = dataset.elementDatasets;
087:
088: pageNumber = (JRFillVariable) varsm.get(JRVariable.PAGE_NUMBER);
089: columnNumber = (JRFillVariable) varsm
090: .get(JRVariable.COLUMN_NUMBER);
091:
092: byte whenResourceMissingType = dataset
093: .getWhenResourceMissingType();
094: evaluator.init(parsm, fldsm, varsm, whenResourceMissingType);
095: }
096:
097: /**
098: *
099: */
100: public JRFillVariable getPageNumber() {
101: return pageNumber;
102: }
103:
104: /**
105: *
106: */
107: public JRFillVariable getColumnNumber() {
108: return columnNumber;
109: }
110:
111: /**
112: *
113: */
114: public void calculateVariables() throws JRException {
115: if (variables != null && variables.length > 0) {
116: for (int i = 0; i < variables.length; i++) {
117: JRFillVariable variable = variables[i];
118: Object expressionValue = evaluate(variable
119: .getExpression());
120: Object newValue = variable.getIncrementer()
121: .increment(
122: variable,
123: expressionValue,
124: AbstractValueProvider
125: .getCurrentValueProvider());
126: variable.setValue(newValue);
127: variable.setInitialized(false);
128:
129: if (variable.getIncrementType() == JRVariable.RESET_TYPE_NONE) {
130: variable.setIncrementedValue(variable.getValue());
131: }
132: }
133: }
134:
135: if (datasets != null && datasets.length > 0) {
136: for (int i = 0; i < datasets.length; i++) {
137: JRFillElementDataset elementDataset = datasets[i];
138: elementDataset.evaluate(this );
139:
140: if (elementDataset.getIncrementType() == JRVariable.RESET_TYPE_NONE) {
141: elementDataset.increment();
142: }
143: }
144: }
145: }
146:
147: /**
148: *
149: */
150: public void estimateVariables() throws JRException {
151: if (variables != null && variables.length > 0) {
152: JRFillVariable variable = null;
153: Object expressionValue = null;
154: Object newValue = null;
155:
156: for (int i = 0; i < variables.length; i++) {
157: variable = variables[i];
158: expressionValue = evaluateEstimated(variable
159: .getExpression());
160: newValue = variable.getIncrementer().increment(
161: variable,
162: expressionValue,
163: AbstractValueProvider
164: .getEstimatedValueProvider());
165: variable.setEstimatedValue(newValue);
166: //variable.setInitialized(false);
167: }
168: }
169: }
170:
171: /**
172: * Determines group breaks based on estimated report values.
173: * <p>
174: * {@link #estimateVariables() estimateVariables()} needs to be called prior to this method.
175: * </p>
176: *
177: * @throws JRException
178: */
179: public void estimateGroupRuptures() throws JRException {
180: JRFillGroup group = null;
181: Object oldValue = null;
182: Object estimatedValue = null;
183: boolean groupHasChanged = false;
184: boolean isTopLevelChange = false;
185: if (groups != null && groups.length > 0) {
186: for (int i = 0; i < groups.length; i++) {
187: group = groups[i];
188:
189: isTopLevelChange = false;
190:
191: if (!groupHasChanged) {
192: oldValue = evaluateOld(group.getExpression());
193: estimatedValue = evaluateEstimated(group
194: .getExpression());
195:
196: if ((oldValue == null && estimatedValue != null)
197: || (oldValue != null && !oldValue
198: .equals(estimatedValue))) {
199: groupHasChanged = true;
200: isTopLevelChange = true;
201: }
202: }
203:
204: group.setHasChanged(groupHasChanged);
205: group.setTopLevelChange(isTopLevelChange);
206: }
207: }
208: }
209:
210: /**
211: *
212: */
213: public void initializeVariables(byte resetType) throws JRException {
214: if (variables != null && variables.length > 0) {
215: for (int i = 0; i < variables.length; i++) {
216: incrementVariable(variables[i], resetType);
217: initializeVariable(variables[i], resetType);
218: }
219: }
220:
221: if (datasets != null && datasets.length > 0) {
222: for (int i = 0; i < datasets.length; i++) {
223: incrementDataset(datasets[i], resetType);
224: initializeDataset(datasets[i], resetType);
225: }
226: }
227: }
228:
229: /**
230: *
231: */
232: private void incrementVariable(JRFillVariable variable,
233: byte incrementType) {
234: if (variable.getIncrementType() != JRVariable.RESET_TYPE_NONE) {
235: boolean toIncrement = false;
236: switch (incrementType) {
237: case JRVariable.RESET_TYPE_REPORT: {
238: toIncrement = true;
239: break;
240: }
241: case JRVariable.RESET_TYPE_PAGE: {
242: toIncrement = (variable.getIncrementType() == JRVariable.RESET_TYPE_PAGE || variable
243: .getIncrementType() == JRVariable.RESET_TYPE_COLUMN);
244: break;
245: }
246: case JRVariable.RESET_TYPE_COLUMN: {
247: toIncrement = (variable.getIncrementType() == JRVariable.RESET_TYPE_COLUMN);
248: break;
249: }
250: case JRVariable.RESET_TYPE_GROUP: {
251: if (variable.getIncrementType() == JRVariable.RESET_TYPE_GROUP) {
252: JRFillGroup group = (JRFillGroup) variable
253: .getIncrementGroup();
254: toIncrement = group.hasChanged();
255: }
256: break;
257: }
258: case JRVariable.RESET_TYPE_NONE:
259: default: {
260: }
261: }
262:
263: if (toIncrement) {
264: variable.setIncrementedValue(variable.getValue());
265: // variable.setValue(
266: // evaluate(variable.getInitialValueExpression())
267: // );
268: // variable.setInitialized(true);
269: }
270: } else {
271: variable.setIncrementedValue(variable.getValue());
272: // variable.setValue(
273: // evaluate(variable.getExpression())
274: // );
275: }
276: }
277:
278: /**
279: *
280: */
281: private void incrementDataset(JRFillElementDataset elementDataset,
282: byte incrementType) {
283: if (elementDataset.getIncrementType() != JRVariable.RESET_TYPE_NONE) {
284: boolean toIncrement = false;
285: switch (incrementType) {
286: case JRVariable.RESET_TYPE_REPORT: {
287: toIncrement = true;
288: break;
289: }
290: case JRVariable.RESET_TYPE_PAGE: {
291: toIncrement = (elementDataset.getIncrementType() == JRVariable.RESET_TYPE_PAGE || elementDataset
292: .getIncrementType() == JRVariable.RESET_TYPE_COLUMN);
293: break;
294: }
295: case JRVariable.RESET_TYPE_COLUMN: {
296: toIncrement = (elementDataset.getIncrementType() == JRVariable.RESET_TYPE_COLUMN);
297: break;
298: }
299: case JRVariable.RESET_TYPE_GROUP: {
300: if (elementDataset.getIncrementType() == JRVariable.RESET_TYPE_GROUP) {
301: JRFillGroup group = (JRFillGroup) elementDataset
302: .getIncrementGroup();
303: toIncrement = group.hasChanged();
304: }
305: break;
306: }
307: case JRVariable.RESET_TYPE_NONE:
308: default: {
309: }
310: }
311:
312: if (toIncrement) {
313: elementDataset.increment();
314: }
315: }
316: }
317:
318: /**
319: *
320: */
321: private void initializeVariable(JRFillVariable variable,
322: byte resetType) throws JRException {
323: //if (jrVariable.getCalculation() != JRVariable.CALCULATION_NOTHING)
324: if (variable.getResetType() != JRVariable.RESET_TYPE_NONE) {
325: boolean toInitialize = false;
326: switch (resetType) {
327: case JRVariable.RESET_TYPE_REPORT: {
328: toInitialize = true;
329: break;
330: }
331: case JRVariable.RESET_TYPE_PAGE: {
332: toInitialize = (variable.getResetType() == JRVariable.RESET_TYPE_PAGE || variable
333: .getResetType() == JRVariable.RESET_TYPE_COLUMN);
334: break;
335: }
336: case JRVariable.RESET_TYPE_COLUMN: {
337: toInitialize = (variable.getResetType() == JRVariable.RESET_TYPE_COLUMN);
338: break;
339: }
340: case JRVariable.RESET_TYPE_GROUP: {
341: if (variable.getResetType() == JRVariable.RESET_TYPE_GROUP) {
342: JRFillGroup group = (JRFillGroup) variable
343: .getResetGroup();
344: toInitialize = group.hasChanged();
345: }
346: break;
347: }
348: case JRVariable.RESET_TYPE_NONE:
349: default: {
350: }
351: }
352:
353: if (toInitialize) {
354: variable.setValue(evaluate(variable
355: .getInitialValueExpression()));
356: variable.setInitialized(true);
357: variable.setIncrementedValue(null);
358: }
359: } else {
360: variable.setValue(evaluate(variable.getExpression()));
361: variable.setIncrementedValue(variable.getValue());
362: }
363: }
364:
365: /**
366: *
367: */
368: private void initializeDataset(JRFillElementDataset elementDataset,
369: byte resetType) {
370: boolean toInitialize = false;
371: switch (resetType) {
372: case JRVariable.RESET_TYPE_REPORT: {
373: toInitialize = true;
374: break;
375: }
376: case JRVariable.RESET_TYPE_PAGE: {
377: toInitialize = (elementDataset.getResetType() == JRVariable.RESET_TYPE_PAGE || elementDataset
378: .getResetType() == JRVariable.RESET_TYPE_COLUMN);
379: break;
380: }
381: case JRVariable.RESET_TYPE_COLUMN: {
382: toInitialize = (elementDataset.getResetType() == JRVariable.RESET_TYPE_COLUMN);
383: break;
384: }
385: case JRVariable.RESET_TYPE_GROUP: {
386: if (elementDataset.getResetType() == JRVariable.RESET_TYPE_GROUP) {
387: JRFillGroup group = (JRFillGroup) elementDataset
388: .getResetGroup();
389: toInitialize = group.hasChanged();
390: }
391: break;
392: }
393: case JRVariable.RESET_TYPE_NONE:
394: default: {
395: }
396: }
397:
398: if (toInitialize) {
399: elementDataset.initialize();
400: }
401: }
402:
403: /**
404: *
405: */
406: public Object evaluate(JRExpression expression, byte evaluationType)
407: throws JRException {
408: Object value = null;
409:
410: switch (evaluationType) {
411: case JRExpression.EVALUATION_OLD: {
412: value = evaluateOld(expression);
413: break;
414: }
415: case JRExpression.EVALUATION_ESTIMATED: {
416: value = evaluateEstimated(expression);
417: break;
418: }
419: case JRExpression.EVALUATION_DEFAULT:
420: default: {
421: value = evaluate(expression);
422: break;
423: }
424: }
425:
426: return value;
427: }
428:
429: /**
430: *
431: */
432: public Object evaluateOld(JRExpression expression)
433: throws JRExpressionEvalException {
434: return evaluator.evaluateOld(expression);
435: }
436:
437: /**
438: *
439: */
440: public Object evaluateEstimated(JRExpression expression)
441: throws JRExpressionEvalException {
442: return evaluator.evaluateEstimated(expression);
443: }
444:
445: /**
446: *
447: */
448: public Object evaluate(JRExpression expression)
449: throws JRExpressionEvalException {
450: return evaluator.evaluate(expression);
451: }
452: }
|