001 /** 002 * ========================================= 003 * LibFormula : a free Java formula library 004 * ========================================= 005 * 006 * Project Info: http://reporting.pentaho.org/libformula/ 007 * 008 * (C) Copyright 2006-2007, by 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 * ------------ 027 * $Id: Formula.java 3515 2007-10-16 09:22:24Z tmorgner $ 028 * ------------ 029 * (C) Copyright 2006-2007, by Pentaho Corporation. 030 */ 031 package org.jfree.formula; 032 033 import java.io.Serializable; 034 035 import org.jfree.formula.lvalues.LValue; 036 import org.jfree.formula.lvalues.TypeValuePair; 037 import org.jfree.formula.parser.FormulaParser; 038 import org.jfree.formula.parser.ParseException; 039 import org.jfree.formula.parser.TokenMgrError; 040 import org.jfree.formula.typing.Type; 041 import org.jfree.formula.typing.coretypes.ErrorType; 042 import org.jfree.util.Log; 043 044 /** 045 * Creation-Date: 31.10.2006, 14:43:05 046 * 047 * @author Thomas Morgner 048 */ 049 public class Formula implements Serializable, Cloneable 050 { 051 private LValue rootReference; 052 053 public Formula(final String formulaText) throws ParseException 054 { 055 try 056 { 057 final FormulaParser parser = new FormulaParser(); 058 this.rootReference = parser.parse(formulaText); 059 } 060 catch(TokenMgrError tokenMgrError) 061 { 062 // This is ugly. 063 throw new ParseException(tokenMgrError.getMessage()); 064 } 065 } 066 067 public Formula(final LValue rootReference) 068 { 069 this.rootReference = rootReference; 070 } 071 072 public void initialize (final FormulaContext context) throws EvaluationException 073 { 074 rootReference.initialize(context); 075 } 076 077 /** 078 * Returns the root reference for this formula. This allows external programms 079 * to modify the formula directly. 080 * 081 * @return 082 */ 083 public LValue getRootReference() 084 { 085 return rootReference; 086 } 087 088 public TypeValuePair evaluateTyped () 089 { 090 try 091 { 092 final TypeValuePair typeValuePair = rootReference.evaluate(); 093 if (typeValuePair == null) 094 { 095 // Should no longer happen.. 096 return new TypeValuePair 097 (ErrorType.TYPE, LibFormulaErrorValue.ERROR_NA_VALUE); 098 } 099 if(typeValuePair.getType().isFlagSet(Type.ERROR_TYPE)) 100 { 101 Log.debug ("Error: " + typeValuePair.getValue()); 102 } 103 return typeValuePair; 104 } 105 catch(EvaluationException ee) 106 { 107 return new TypeValuePair(ErrorType.TYPE, ee.getErrorValue()); 108 } 109 catch (Exception e) 110 { 111 Log.warn ("Evaluation failed unexpectedly: ", e); 112 return new TypeValuePair(ErrorType.TYPE, LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE); 113 } 114 } 115 116 public Object evaluate () 117 { 118 return evaluateTyped().getValue(); 119 } 120 121 public Object clone () throws CloneNotSupportedException 122 { 123 final Formula o = (Formula) super.clone(); 124 o.rootReference = (LValue) rootReference.clone(); 125 return o; 126 } 127 }