001: /**
002: * ========================================
003: * JFreeReport : a free Java report library
004: * ========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2000-2007, by Object Refinery Limited, 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: * $Id: FormulaExpression.java 3048 2007-07-28 18:02:42Z tmorgner $
027: * ------------
028: * (C) Copyright 2000-2005, by Object Refinery Limited.
029: * (C) Copyright 2005-2007, by Pentaho Corporation.
030: */package org.jfree.report.expressions;
031:
032: import org.jfree.formula.Formula;
033: import org.jfree.formula.FormulaContext;
034: import org.jfree.formula.parser.ParseException;
035: import org.jfree.report.DataSourceException;
036: import org.jfree.report.flow.ReportContext;
037: import org.jfree.util.Log;
038:
039: /**
040: * Creation-Date: 04.11.2006, 19:24:04
041: *
042: * @author Thomas Morgner
043: */
044: public class FormulaExpression extends AbstractExpression {
045: private transient Formula compiledFormula;
046: private String formulaNamespace;
047: private String formulaExpression;
048: private String formula;
049:
050: public FormulaExpression() {
051: }
052:
053: private synchronized FormulaContext getFormulaContext() {
054: final ReportContext globalContext = getRuntime()
055: .getReportContext();
056: return globalContext.getFormulaContext();
057: }
058:
059: public String getFormula() {
060: return formula;
061: }
062:
063: public String getFormulaNamespace() {
064: return formulaNamespace;
065: }
066:
067: public String getFormulaExpression() {
068: return formulaExpression;
069: }
070:
071: public void setFormula(final String formula) {
072: this .formula = formula;
073: if (formula == null) {
074: formulaNamespace = null;
075: formulaExpression = null;
076: } else {
077: final int separator = formula.indexOf(':');
078: if (separator <= 0 || ((separator + 1) == formula.length())) {
079: if (formula.startsWith("=")) {
080: formulaNamespace = "report";
081: formulaExpression = formula.substring(1);
082: } else {
083: // error: invalid formula.
084: formulaNamespace = null;
085: formulaExpression = null;
086: }
087: } else {
088: formulaNamespace = formula.substring(0, separator);
089: formulaExpression = formula.substring(separator + 1);
090: }
091: }
092: this .compiledFormula = null;
093: }
094:
095: private Object computeRegularValue() {
096: try {
097: if (compiledFormula == null) {
098: compiledFormula = new Formula(formulaExpression);
099: }
100:
101: final ReportFormulaContext context = new ReportFormulaContext(
102: getFormulaContext(), getDataRow());
103: try {
104: compiledFormula.initialize(context);
105: return compiledFormula.evaluate();
106: } finally {
107: context.setDataRow(null);
108: }
109: } catch (Exception e) {
110: Log.debug("Failed to compute the regular value.", e);
111: return null;
112: }
113: }
114:
115: /**
116: * Returns the compiled formula. The formula is not connected to a formula
117: * context.
118: *
119: * @return the formula.
120: * @throws ParseException if the formula contains syntax errors.
121: */
122: public Formula getCompiledFormula() throws ParseException {
123: if (compiledFormula == null) {
124: compiledFormula = new Formula(formulaExpression);
125: }
126: return compiledFormula;
127: }
128:
129: /**
130: * Return the current expression value. <P> The value depends (obviously) on
131: * the expression implementation.
132: *
133: * @return the value of the function.
134: */
135: public Object computeValue() throws DataSourceException {
136: try {
137: return computeRegularValue();
138: } catch (Exception e) {
139: return null;
140: }
141: }
142:
143: /**
144: * Clones the expression, expression should be reinitialized after the
145: * cloning. <P> Expression maintain no state, cloning is done at the beginning
146: * of the report processing to disconnect the used expression from any other
147: * object space.
148: *
149: * @return A clone of this expression.
150: * @throws CloneNotSupportedException this should never happen.
151: */
152: public Object clone() throws CloneNotSupportedException {
153: final FormulaExpression o = (FormulaExpression) super .clone();
154: if (compiledFormula != null) {
155: o.compiledFormula = (Formula) compiledFormula.clone();
156: }
157: return o;
158: }
159: }
|