Source for org.jfree.report.expressions.FormulaExpression

   1: /**
   2:  * ========================================
   3:  * JFreeReport : a free Java report library
   4:  * ========================================
   5:  *
   6:  * Project Info:  http://reporting.pentaho.org/
   7:  *
   8:  * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
   9:  *
  10:  * This library is free software; you can redistribute it and/or modify it under the terms
  11:  * of the GNU Lesser General Public License as published by the Free Software Foundation;
  12:  * either version 2.1 of the License, or (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  15:  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16:  * See the GNU Lesser General Public License for more details.
  17:  *
  18:  * You should have received a copy of the GNU Lesser General Public License along with this
  19:  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20:  * Boston, MA 02111-1307, USA.
  21:  *
  22:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  23:  * in the United States and other countries.]
  24:  *
  25:  * ------------
  26:  * $Id: FormulaExpression.java 2725 2007-04-01 18:49:29Z taqua $
  27:  * ------------
  28:  * (C) Copyright 2000-2005, by Object Refinery Limited.
  29:  * (C) Copyright 2005-2007, by Pentaho Corporation.
  30:  */
  31: 
  32: package org.jfree.report.expressions;
  33: 
  34: import org.jfree.formula.Formula;
  35: import org.jfree.formula.FormulaContext;
  36: import org.jfree.formula.parser.ParseException;
  37: import org.jfree.report.DataSourceException;
  38: import org.jfree.report.flow.ReportContext;
  39: import org.jfree.util.Log;
  40: 
  41: /**
  42:  * Creation-Date: 04.11.2006, 19:24:04
  43:  *
  44:  * @author Thomas Morgner
  45:  */
  46: public class FormulaExpression extends AbstractExpression
  47: {
  48:   private transient Formula compiledFormula;
  49:   private String formulaNamespace;
  50:   private String formulaExpression;
  51:   private String formula;
  52: 
  53:   public FormulaExpression()
  54:   {
  55:   }
  56: 
  57:   private synchronized FormulaContext getFormulaContext()
  58:   {
  59:     final ReportContext globalContext = getRuntime().getReportContext();
  60:     return globalContext.getFormulaContext();
  61:   }
  62: 
  63:   public String getFormula()
  64:   {
  65:     return formula;
  66:   }
  67: 
  68:   public String getFormulaNamespace()
  69:   {
  70:     return formulaNamespace;
  71:   }
  72: 
  73:   public String getFormulaExpression()
  74:   {
  75:     return formulaExpression;
  76:   }
  77: 
  78:   public void setFormula(final String formula)
  79:   {
  80:     this.formula = formula;
  81:     if (formula == null)
  82:     {
  83:       formulaNamespace = null;
  84:       formulaExpression = null;
  85:     }
  86:     else
  87:     {
  88:       final int separator = formula.indexOf(':');
  89:       if (separator <= 0 || ((separator + 1) == formula.length()))
  90:       {
  91:         if (formula.startsWith("="))
  92:         {
  93:           formulaNamespace = "report";
  94:           formulaExpression = formula.substring(1);
  95:         }
  96:         else
  97:         {
  98:           // error: invalid formula.
  99:           formulaNamespace = null;
 100:           formulaExpression = null;
 101:         }
 102:       }
 103:       else
 104:       {
 105:         formulaNamespace = formula.substring(0, separator);
 106:         formulaExpression = formula.substring(separator + 1);
 107:       }
 108:     }
 109:     this.compiledFormula = null;
 110:   }
 111: 
 112:   private Object computeRegularValue()
 113:   {
 114:     try
 115:     {
 116:       if (compiledFormula == null)
 117:       {
 118:         compiledFormula = new Formula(formulaExpression);
 119:       }
 120: 
 121:       final ReportFormulaContext context =
 122:           new ReportFormulaContext(getFormulaContext(), getDataRow());
 123:       try
 124:       {
 125:         compiledFormula.initialize(context);
 126:         return compiledFormula.evaluate();
 127:       }
 128:       finally
 129:       {
 130:         context.setDataRow(null);
 131:       }
 132:     }
 133:     catch (Exception e)
 134:     {
 135:       Log.debug("Failed to compute the regular value.", e);
 136:       return null;
 137:     }
 138:   }
 139: 
 140:   /**
 141:    * Returns the compiled formula. The formula is not connected to a formula
 142:    * context.
 143:    *
 144:    * @return the formula.
 145:    * @throws ParseException if the formula contains syntax errors.
 146:    */
 147:   public Formula getCompiledFormula()
 148:       throws ParseException
 149:   {
 150:     if (compiledFormula == null)
 151:     {
 152:       compiledFormula = new Formula(formulaExpression);
 153:     }
 154:     return compiledFormula;
 155:   }
 156: 
 157:   /**
 158:    * Return the current expression value. <P> The value depends (obviously) on
 159:    * the expression implementation.
 160:    *
 161:    * @return the value of the function.
 162:    */
 163:   public Object computeValue() throws DataSourceException
 164:   {
 165:     try
 166:     {
 167:       return computeRegularValue();
 168:     }
 169:     catch (Exception e)
 170:     {
 171:       return null;
 172:     }
 173:   }
 174: 
 175:   /**
 176:    * Clones the expression, expression should be reinitialized after the
 177:    * cloning. <P> Expression maintain no state, cloning is done at the beginning
 178:    * of the report processing to disconnect the used expression from any other
 179:    * object space.
 180:    *
 181:    * @return A clone of this expression.
 182:    * @throws CloneNotSupportedException this should never happen.
 183:    */
 184:   public Object clone() throws CloneNotSupportedException
 185:   {
 186:     final FormulaExpression o = (FormulaExpression) super.clone();
 187:     if (compiledFormula != null)
 188:     {
 189:       o.compiledFormula = (Formula) compiledFormula.clone();
 190:     }
 191:     return o;
 192:   }
 193: }