You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2009/01/22 01:26:28 UTC

svn commit: r736505 - in /poi/trunk/src: java/org/apache/poi/hssf/record/formula/atp/ java/org/apache/poi/hssf/record/formula/eval/ java/org/apache/poi/hssf/record/formula/functions/ java/org/apache/poi/ss/formula/ java/org/apache/poi/ss/formula/eval/ ...

Author: josh
Date: Wed Jan 21 16:26:28 2009
New Revision: 736505

URL: http://svn.apache.org/viewvc?rev=736505&view=rev
Log:
Replaced ErrorEval.FUNCTION_NOT_IMPLEMENTED with new exception NotImplementedException.  Removed test case involving ISREF which was working for the wrong reasons.

Added:
    poi/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java
Modified:
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java
    poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
    poi/trunk/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls
    poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java Wed Jan 21 16:26:28 2009
@@ -20,34 +20,39 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
 import org.apache.poi.ss.formula.EvaluationWorkbook;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 
 public final class AnalysisToolPak {
 
-	private static final FreeRefFunction NotImplemented = new FreeRefFunction() {
+	private static final class NotImplemented implements FreeRefFunction {
+		private final String _functionName;
+
+		public NotImplemented(String functionName) {
+			_functionName = functionName;
+		}
 
 		public ValueEval evaluate(Eval[] args, EvaluationWorkbook workbook, int srcCellSheet,
 				int srcCellRow, int srcCellCol) {
-			return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
+			throw new NotImplementedException(_functionName);
 		}
 	};
 	
-	private static Map _functionsByName = createFunctionsMap();
+	private static Map<String, FreeRefFunction> _functionsByName = createFunctionsMap();
 
 	private AnalysisToolPak() {
 		// no instances of this class
 	}
 
 	public static FreeRefFunction findFunction(String name) {
-		return (FreeRefFunction)_functionsByName.get(name);
+		return _functionsByName.get(name);
 	}
 	
-	private static Map createFunctionsMap() {
-		Map m = new HashMap(100);
+	private static Map<String, FreeRefFunction> createFunctionsMap() {
+		Map<String, FreeRefFunction> m = new HashMap<String, FreeRefFunction>(100);
 
 		r(m, "ACCRINT", null);
 		r(m, "ACCRINTM", null);
@@ -146,8 +151,8 @@
 		return m;
 	}
 
-	private static void r(Map m, String functionName, FreeRefFunction pFunc) {
-		FreeRefFunction func = pFunc == null ? NotImplemented : pFunc;
+	private static void r(Map<String, FreeRefFunction> m, String functionName, FreeRefFunction pFunc) {
+		FreeRefFunction func = pFunc == null ? new NotImplemented(functionName) : pFunc;
 		m.put(functionName, func);
 	}
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java Wed Jan 21 16:26:28 2009
@@ -48,7 +48,6 @@
     private static final int CIRCULAR_REF_ERROR_CODE = 0xFFFFFFC4;
     private static final int FUNCTION_NOT_IMPLEMENTED_CODE = 0xFFFFFFE2;
 
-    public static final ErrorEval FUNCTION_NOT_IMPLEMENTED = new ErrorEval(FUNCTION_NOT_IMPLEMENTED_CODE);
     // Note - Excel does not seem to represent this condition with an error code
     public static final ErrorEval CIRCULAR_REF_ERROR = new ErrorEval(CIRCULAR_REF_ERROR_CODE);
 
@@ -68,7 +67,6 @@
             case HSSFErrorConstants.ERROR_NA:    return NA;
             // non-std errors (conditions modeled as errors by POI)
             case CIRCULAR_REF_ERROR_CODE:        return CIRCULAR_REF_ERROR;
-            case FUNCTION_NOT_IMPLEMENTED_CODE:  return FUNCTION_NOT_IMPLEMENTED;
         }
         throw new RuntimeException("Unexpected error code (" + errorCode + ")");
     }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java Wed Jan 21 16:26:28 2009
@@ -20,6 +20,7 @@
 import org.apache.poi.hssf.record.formula.atp.AnalysisToolPak;
 import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
 import org.apache.poi.ss.formula.EvaluationWorkbook;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 /**
  * 
  * Common entry point for all user-defined (non-built-in) functions (where 
@@ -40,17 +41,13 @@
 		
 		Eval nameArg = args[0];
 		FreeRefFunction targetFunc;
-		try {
-			if (nameArg instanceof NameEval) {
-				targetFunc = findInternalUserDefinedFunction((NameEval) nameArg);
-			} else if (nameArg instanceof NameXEval) {
-				targetFunc = findExternalUserDefinedFunction(workbook, (NameXEval) nameArg);
-			} else {
-				throw new RuntimeException("First argument should be a NameEval, but got ("
-						+ nameArg.getClass().getName() + ")");
-			}
-		} catch (EvaluationException e) {
-			return e.getErrorEval();
+		if (nameArg instanceof NameEval) {
+			targetFunc = findInternalUserDefinedFunction((NameEval) nameArg);
+		} else if (nameArg instanceof NameXEval) {
+			targetFunc = findExternalUserDefinedFunction(workbook, (NameXEval) nameArg);
+		} else {
+			throw new RuntimeException("First argument should be a NameEval, but got ("
+					+ nameArg.getClass().getName() + ")");
 		}
 		int nOutGoingArgs = nIncomingArgs -1;
 		Eval[] outGoingArgs = new Eval[nOutGoingArgs];
@@ -58,8 +55,8 @@
 		return targetFunc.evaluate(outGoingArgs, workbook, srcCellSheet, srcCellRow, srcCellCol);
 	}
 
-	private FreeRefFunction findExternalUserDefinedFunction(EvaluationWorkbook workbook,
-			NameXEval n) throws EvaluationException {
+	private static FreeRefFunction findExternalUserDefinedFunction(EvaluationWorkbook workbook,
+			NameXEval n) {
 		String functionName = workbook.resolveNameXText(n.getPtg());
 
 		if(false) {
@@ -71,10 +68,10 @@
 		if (result != null) {
 			return result;
 		}
-		throw new EvaluationException(ErrorEval.FUNCTION_NOT_IMPLEMENTED);
+		throw new NotImplementedException(functionName);
 	}
 
-	private FreeRefFunction findInternalUserDefinedFunction(NameEval functionNameEval) throws EvaluationException {
+	private static FreeRefFunction findInternalUserDefinedFunction(NameEval functionNameEval) {
 
 		String functionName = functionNameEval.getFunctionName();
 		if(false) {
@@ -82,7 +79,6 @@
 		}
 		// TODO find the implementation for the user defined function
 		
-		throw new EvaluationException(ErrorEval.FUNCTION_NOT_IMPLEMENTED);
+		throw new NotImplementedException(functionName);
 	}
 }
-

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java Wed Jan 21 16:26:28 2009
@@ -19,6 +19,7 @@
 
 import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
 import org.apache.poi.hssf.record.formula.functions.Function;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -26,25 +27,25 @@
  */
 public final class FuncVarEval extends FunctionEval {
 
-    private AbstractFunctionPtg delegate;
+	private AbstractFunctionPtg delegate;
 
-    public FuncVarEval(AbstractFunctionPtg funcPtg) {
-        delegate = funcPtg;
-    }
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        Function f = getFunction();
-        if (f == null) {
-			return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
+	public FuncVarEval(AbstractFunctionPtg funcPtg) {
+		delegate = funcPtg;
+	}
+
+	public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+		Function f = getFunction();
+		if (f == null) {
+			throw new NotImplementedException("FuncIx=" + getFunctionIndex());
 		}
 		return f.evaluate(operands, srcRow, srcCol);
-    }
+	}
 
-    public int getNumberOfOperands() {
-        return delegate.getNumberOfOperands();
-    }
-
-    public short getFunctionIndex() {
-        return delegate.getFunctionIndex();
-    }
+	public int getNumberOfOperands() {
+		return delegate.getNumberOfOperands();
+	}
+
+	public short getFunctionIndex() {
+		return delegate.getFunctionIndex();
+	}
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java Wed Jan 21 16:26:28 2009
@@ -43,17 +43,14 @@
     
     protected static Function[] functions = produceFunctions();
 
-    private static Map freeRefFunctionsByIdMap;
+    private static Map<Integer, FreeRefFunction> freeRefFunctionsByIdMap;
      
     static {
-        Map m = new HashMap();
-        addMapping(m, ID.INDIRECT, new Indirect());
-        addMapping(m, ID.EXTERNAL_FUNC, new ExternalFunction());
+        Map<Integer, FreeRefFunction> m = new HashMap<Integer, FreeRefFunction>();
+        m.put(createFRFKey(ID.INDIRECT), new Indirect());
+        m.put(createFRFKey(ID.EXTERNAL_FUNC), new ExternalFunction());
         freeRefFunctionsByIdMap = m;
     }
-    private static void addMapping(Map m, int offset, FreeRefFunction frf) {
-        m.put(createFRFKey(offset), frf);
-    }
     private static Integer createFRFKey(int functionIndex) {
         return new Integer(functionIndex);
     }
@@ -67,7 +64,7 @@
         return freeRefFunctionsByIdMap.containsKey(createFRFKey(getFunctionIndex()));
     }
     public FreeRefFunction getFreeRefFunction() {
-        return (FreeRefFunction) freeRefFunctionsByIdMap.get(createFRFKey(getFunctionIndex()));
+        return freeRefFunctionsByIdMap.get(createFRFKey(getFunctionIndex()));
     }
 
     public abstract short getFunctionIndex();
@@ -164,11 +161,11 @@
         retval[88] = new Setname(); // SETNAME
         retval[89] = new Caller(); // CALLER
         retval[90] = new Deref(); // DEREF
-        retval[91] = new NotImplementedFunction(); // WINDOWS
+        retval[91] = new NotImplementedFunction("WINDOWS");
         retval[92] = new Series(); // SERIES
-        retval[93] = new NotImplementedFunction(); // DOCUMENTS
+        retval[93] = new NotImplementedFunction("DOCUMENTS");
         retval[94] = new Activecell(); // ACTIVECELL
-        retval[95] = new NotImplementedFunction(); // SELECTION
+        retval[95] = new NotImplementedFunction("SELECTION");
         retval[96] = new Result(); // RESULT
         retval[97] = NumericFunction.ATAN2;
         retval[98] = NumericFunction.ASIN;
@@ -179,8 +176,8 @@
         retval[103] = new Links(); // LINKS
         retval[104] = new Input(); // INPUT
         retval[105] = new Isref(); // ISREF
-        retval[106] = new NotImplementedFunction(); // GETFORMULA
-        retval[107] = new NotImplementedFunction(); // GETNAME
+        retval[106] = new NotImplementedFunction("GETFORMULA");
+        retval[107] = new NotImplementedFunction("GETNAME");
         retval[108] = new Setvalue(); // SETVALUE
         retval[109] = NumericFunction.LOG;
         retval[110] = new Exec(); // EXEC
@@ -196,7 +193,7 @@
         retval[120] = new Substitute(); // SUBSTITUTE
         retval[121] = new Code(); // CODE
         retval[122] = new Names(); // NAMES
-        retval[123] = new NotImplementedFunction(); // DIRECTORY
+        retval[123] = new NotImplementedFunction("DIRECTORY");
         retval[124] = new Find(); // FIND
         retval[125] = new Cell(); // CELL
         retval[126] = new Iserr(); // ISERR
@@ -205,36 +202,36 @@
         retval[129] = new Isblank(); // ISBLANK
         retval[130] = new T(); // T
         retval[131] = new N(); // N
-        retval[132] = new NotImplementedFunction(); // FOPEN
-        retval[133] = new NotImplementedFunction(); // FCLOSE
-        retval[134] = new NotImplementedFunction(); // FSIZE
-        retval[135] = new NotImplementedFunction(); // FREADLN
-        retval[136] = new NotImplementedFunction(); // FREAD
-        retval[137] = new NotImplementedFunction(); // FWRITELN
-        retval[138] = new NotImplementedFunction(); // FWRITE
+        retval[132] = new NotImplementedFunction("FOPEN");
+        retval[133] = new NotImplementedFunction("FCLOSE");
+        retval[134] = new NotImplementedFunction("FSIZE");
+        retval[135] = new NotImplementedFunction("FREADLN");
+        retval[136] = new NotImplementedFunction("FREAD");
+        retval[137] = new NotImplementedFunction("FWRITELN");
+        retval[138] = new NotImplementedFunction("FWRITE");
         retval[139] = new Fpos(); // FPOS
         retval[140] = new Datevalue(); // DATEVALUE
         retval[141] = new Timevalue(); // TIMEVALUE
         retval[142] = new Sln(); // SLN
         retval[143] = new Syd(); // SYD
         retval[144] = new Ddb(); // DDB
-        retval[145] = new NotImplementedFunction(); // GETDEF
+        retval[145] = new NotImplementedFunction("GETDEF");
         retval[146] = new Reftext(); // REFTEXT
         retval[147] = new Textref(); // TEXTREF
         retval[ID.INDIRECT] = null; // Indirect.evaluate has different signature
-        retval[149] = new NotImplementedFunction(); // REGISTER
+        retval[149] = new NotImplementedFunction("REGISTER");
         retval[150] = new Call(); // CALL
-        retval[151] = new NotImplementedFunction(); // ADDBAR
-        retval[152] = new NotImplementedFunction(); // ADDMENU
-        retval[153] = new NotImplementedFunction(); // ADDCOMMAND
-        retval[154] = new NotImplementedFunction(); // ENABLECOMMAND
-        retval[155] = new NotImplementedFunction(); // CHECKCOMMAND
-        retval[156] = new NotImplementedFunction(); // RENAMECOMMAND
-        retval[157] = new NotImplementedFunction(); // SHOWBAR
-        retval[158] = new NotImplementedFunction(); // DELETEMENU
-        retval[159] = new NotImplementedFunction(); // DELETECOMMAND
-        retval[160] = new NotImplementedFunction(); // GETCHARTITEM
-        retval[161] = new NotImplementedFunction(); // DIALOGBOX
+        retval[151] = new NotImplementedFunction("ADDBAR");
+        retval[152] = new NotImplementedFunction("ADDMENU");
+        retval[153] = new NotImplementedFunction("ADDCOMMAND");
+        retval[154] = new NotImplementedFunction("ENABLECOMMAND");
+        retval[155] = new NotImplementedFunction("CHECKCOMMAND");
+        retval[156] = new NotImplementedFunction("RENAMECOMMAND");
+        retval[157] = new NotImplementedFunction("SHOWBAR");
+        retval[158] = new NotImplementedFunction("DELETEMENU");
+        retval[159] = new NotImplementedFunction("DELETECOMMAND");
+        retval[160] = new NotImplementedFunction("GETCHARTITEM");
+        retval[161] = new NotImplementedFunction("DIALOGBOX");
         retval[162] = new Clean(); // CLEAN
         retval[163] = new Mdeterm(); // MDETERM
         retval[164] = new Minverse(); // MINVERSE
@@ -243,24 +240,24 @@
         retval[167] = new Ipmt(); // IPMT
         retval[168] = new Ppmt(); // PPMT
         retval[169] = new Counta(); // COUNTA
-        retval[170] = new NotImplementedFunction(); // CANCELKEY
+        retval[170] = new NotImplementedFunction("CANCELKEY");
         retval[175] = new Initiate(); // INITIATE
         retval[176] = new Request(); // REQUEST
-        retval[177] = new NotImplementedFunction(); // POKE
-        retval[178] = new NotImplementedFunction(); // EXECUTE
-        retval[179] = new NotImplementedFunction(); // TERMINATE
-        retval[180] = new NotImplementedFunction(); // RESTART
+        retval[177] = new NotImplementedFunction("POKE");
+        retval[178] = new NotImplementedFunction("EXECUTE");
+        retval[179] = new NotImplementedFunction("TERMINATE");
+        retval[180] = new NotImplementedFunction("RESTART");
         retval[181] = new Help(); // HELP
-        retval[182] = new NotImplementedFunction(); // GETBAR
+        retval[182] = new NotImplementedFunction("GETBAR");
         retval[183] = AggregateFunction.PRODUCT;
         retval[184] = NumericFunction.FACT;
-        retval[185] = new NotImplementedFunction(); // GETCELL
-        retval[186] = new NotImplementedFunction(); // GETWORKSPACE
-        retval[187] = new NotImplementedFunction(); // GETWINDOW
-        retval[188] = new NotImplementedFunction(); // GETDOCUMENT
+        retval[185] = new NotImplementedFunction("GETCELL");
+        retval[186] = new NotImplementedFunction("GETWORKSPACE");
+        retval[187] = new NotImplementedFunction("GETWINDOW");
+        retval[188] = new NotImplementedFunction("GETDOCUMENT");
         retval[189] = new Dproduct(); // DPRODUCT
         retval[190] = new Isnontext(); // ISNONTEXT
-        retval[191] = new NotImplementedFunction(); // GETNOTE
+        retval[191] = new NotImplementedFunction("GETNOTE");
         retval[192] = new Note(); // NOTE
         retval[193] = new Stdevp(); // STDEVP
         retval[194] = new Varp(); // VARP
@@ -269,8 +266,8 @@
         retval[197] = new Trunc(); // TRUNC
         retval[198] = new Islogical(); // ISLOGICAL
         retval[199] = new Dcounta(); // DCOUNTA
-        retval[200] = new NotImplementedFunction(); // DELETEBAR
-        retval[201] = new NotImplementedFunction(); // UNREGISTER
+        retval[200] = new NotImplementedFunction("DELETEBAR");
+        retval[201] = new NotImplementedFunction("UNREGISTER");
         retval[204] = new Usdollar(); // USDOLLAR
         retval[205] = new Findb(); // FINDB
         retval[206] = new Searchb(); // SEARCHB
@@ -297,37 +294,37 @@
         retval[233] = NumericFunction.ACOSH;
         retval[234] = NumericFunction.ATANH;
         retval[235] = new Dget(); // DGET
-        retval[236] = new NotImplementedFunction(); // CREATEOBJECT
+        retval[236] = new NotImplementedFunction("CREATEOBJECT");
         retval[237] = new Volatile(); // VOLATILE
         retval[238] = new Lasterror(); // LASTERROR
-        retval[239] = new NotImplementedFunction(); // CUSTOMUNDO
+        retval[239] = new NotImplementedFunction("CUSTOMUNDO");
         retval[240] = new Customrepeat(); // CUSTOMREPEAT
         retval[241] = new Formulaconvert(); // FORMULACONVERT
-        retval[242] = new NotImplementedFunction(); // GETLINKINFO
-        retval[243] = new NotImplementedFunction(); // TEXTBOX
+        retval[242] = new NotImplementedFunction("GETLINKINFO");
+        retval[243] = new NotImplementedFunction("TEXTBOX");
         retval[244] = new Info(); // INFO
         retval[245] = new Group(); // GROUP
-        retval[246] = new NotImplementedFunction(); // GETOBJECT
+        retval[246] = new NotImplementedFunction("GETOBJECT");
         retval[247] = new Db(); // DB
-        retval[248] = new NotImplementedFunction(); // PAUSE
-        retval[250] = new NotImplementedFunction(); // RESUME
+        retval[248] = new NotImplementedFunction("PAUSE");
+        retval[250] = new NotImplementedFunction("RESUME");
         retval[252] = new Frequency(); // FREQUENCY
-        retval[253] = new NotImplementedFunction(); // ADDTOOLBAR
-        retval[254] = new NotImplementedFunction(); // DELETETOOLBAR
+        retval[253] = new NotImplementedFunction("ADDTOOLBAR");
+        retval[254] = new NotImplementedFunction("DELETETOOLBAR");
         retval[ID.EXTERNAL_FUNC] = null; // ExternalFunction is a FreeREfFunction
-        retval[256] = new NotImplementedFunction(); // RESETTOOLBAR
+        retval[256] = new NotImplementedFunction("RESETTOOLBAR");
         retval[257] = new Evaluate(); // EVALUATE
-        retval[258] = new NotImplementedFunction(); // GETTOOLBAR
-        retval[259] = new NotImplementedFunction(); // GETTOOL
-        retval[260] = new NotImplementedFunction(); // SPELLINGCHECK
+        retval[258] = new NotImplementedFunction("GETTOOLBAR");
+        retval[259] = new NotImplementedFunction("GETTOOL");
+        retval[260] = new NotImplementedFunction("SPELLINGCHECK");
         retval[261] = new Errortype(); // ERRORTYPE
-        retval[262] = new NotImplementedFunction(); // APPTITLE
-        retval[263] = new NotImplementedFunction(); // WINDOWTITLE
-        retval[264] = new NotImplementedFunction(); // SAVETOOLBAR
-        retval[265] = new NotImplementedFunction(); // ENABLETOOL
-        retval[266] = new NotImplementedFunction(); // PRESSTOOL
-        retval[267] = new NotImplementedFunction(); // REGISTERID
-        retval[268] = new NotImplementedFunction(); // GETWORKBOOK
+        retval[262] = new NotImplementedFunction("APPTITLE");
+        retval[263] = new NotImplementedFunction("WINDOWTITLE");
+        retval[264] = new NotImplementedFunction("SAVETOOLBAR");
+        retval[265] = new NotImplementedFunction("ENABLETOOL");
+        retval[266] = new NotImplementedFunction("PRESSTOOL");
+        retval[267] = new NotImplementedFunction("REGISTERID");
+        retval[268] = new NotImplementedFunction("GETWORKBOOK");
         retval[269] = AggregateFunction.AVEDEV;
         retval[270] = new Betadist(); // BETADIST
         retval[271] = new Gammaln(); // GAMMALN
@@ -392,33 +389,33 @@
         retval[330] = new Mode(); // MODE
         retval[331] = new Trimmean(); // TRIMMEAN
         retval[332] = new Tinv(); // TINV
-        retval[334] = new NotImplementedFunction(); // MOVIECOMMAND
-        retval[335] = new NotImplementedFunction(); // GETMOVIE
+        retval[334] = new NotImplementedFunction("MOVIECOMMAND");
+        retval[335] = new NotImplementedFunction("GETMOVIE");
         retval[336] = TextFunction.CONCATENATE;
         retval[337] = NumericFunction.POWER;
-        retval[338] = new NotImplementedFunction(); // PIVOTADDDATA
-        retval[339] = new NotImplementedFunction(); // GETPIVOTTABLE
-        retval[340] = new NotImplementedFunction(); // GETPIVOTFIELD
-        retval[341] = new NotImplementedFunction(); // GETPIVOTITEM
+        retval[338] = new NotImplementedFunction("PIVOTADDDATA");
+        retval[339] = new NotImplementedFunction("GETPIVOTTABLE");
+        retval[340] = new NotImplementedFunction("GETPIVOTFIELD");
+        retval[341] = new NotImplementedFunction("GETPIVOTITEM");
         retval[342] = NumericFunction.RADIANS;
         retval[343] = NumericFunction.DEGREES;
         retval[344] = new Subtotal(); // SUBTOTAL
         retval[345] = new Sumif(); // SUMIF
         retval[346] = new Countif(); // COUNTIF
         retval[347] = new Countblank(); // COUNTBLANK
-        retval[348] = new NotImplementedFunction(); // SCENARIOGET
-        retval[349] = new NotImplementedFunction(); // OPTIONSLISTSGET
+        retval[348] = new NotImplementedFunction("SCENARIOGET");
+        retval[349] = new NotImplementedFunction("OPTIONSLISTSGET");
         retval[350] = new Ispmt(); // ISPMT
         retval[351] = new Datedif(); // DATEDIF
         retval[352] = new Datestring(); // DATESTRING
         retval[353] = new Numberstring(); // NUMBERSTRING
         retval[354] = new Roman(); // ROMAN
-        retval[355] = new NotImplementedFunction(); // OPENDIALOG
-        retval[356] = new NotImplementedFunction(); // SAVEDIALOG
-        retval[357] = new NotImplementedFunction(); // VIEWGET
-        retval[358] = new NotImplementedFunction(); // GETPIVOTDATA
+        retval[355] = new NotImplementedFunction("OPENDIALOG");
+        retval[356] = new NotImplementedFunction("SAVEDIALOG");
+        retval[357] = new NotImplementedFunction("VIEWGET");
+        retval[358] = new NotImplementedFunction("GETPIVOTDATA");
         retval[359] = new Hyperlink(); // HYPERLINK
-        retval[360] = new NotImplementedFunction(); // PHONETIC
+        retval[360] = new NotImplementedFunction("PHONETIC");
         retval[361] = new Averagea(); // AVERAGEA
         retval[362] = MinaMaxa.MAXA;
         retval[363] = MinaMaxa.MINA;

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java Wed Jan 21 16:26:28 2009
@@ -17,10 +17,10 @@
 
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.EvaluationWorkbook;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 
 /**
  * Implementation for Excel function INDIRECT<p/>
@@ -42,7 +42,6 @@
 
 	public ValueEval evaluate(Eval[] args, EvaluationWorkbook workbook, int srcCellSheet, int srcCellRow, int srcCellCol) {
 		// TODO - implement INDIRECT()
-		return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
+		throw new NotImplementedException("INDIRECT");
 	}
-
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java Wed Jan 21 16:26:28 2009
@@ -1,41 +1,44 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 6, 2005
- *
- */
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 
 /**
  * 
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  * This is the default implementation of a Function class. 
- * The default behaviour is to return a non-standard ErrorEval
- * "ErrorEval.FUNCTION_NOT_IMPLEMENTED". This error should alert 
+ * The default behaviour is to raise a POI internal error 
+ * ({@link NotImplementedException}). This error should alert 
  * the user that the formula contained a function that is not
  * yet implemented.
  */
 public class NotImplementedFunction implements Function {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
-    }
-
+	private final String _functionName;
+	protected NotImplementedFunction() {
+		_functionName = getClass().getName();
+	}
+	public NotImplementedFunction(String name) {
+		_functionName = name;
+	}
+	
+	public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+		throw new NotImplementedException(_functionName);
+	}
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java Wed Jan 21 16:26:28 2009
@@ -63,6 +63,7 @@
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.util.CellReference;
 import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 import org.apache.poi.ss.usermodel.Cell;
 
 /**
@@ -220,6 +221,8 @@
 				}
 
 				tracker.updateCacheResult(result);
+			} catch (NotImplementedException e) {
+				throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
 			} finally {
 				tracker.endEvaluate(cce);
 			}
@@ -236,6 +239,25 @@
 		}
 		return cce.getValue();
 	}
+
+	/**
+	 * Adds the current cell reference to the exception for easier debugging. 
+	 * Would be nice to get the formula text as well, but that seems to require
+	 * too much digging around and casting to get the FormulaRenderingWorkbook. 
+	 */
+	private NotImplementedException addExceptionInfo(NotImplementedException inner, int sheetIndex, int rowIndex, int columnIndex) {
+		
+		try {
+			String sheetName = _workbook.getSheetName(sheetIndex);
+			CellReference cr = new CellReference(sheetName, rowIndex, columnIndex, false, false);
+			String msg =  "Error evaluating cell " + cr.formatAsString();
+			return new NotImplementedException(msg, inner);
+		} catch (Exception e) {
+			// avoid bombing out during exception handling
+			e.printStackTrace();
+			return inner; // preserve original exception
+		}
+	}
 	/**
 	 * Gets the value from a non-formula cell.
 	 * @param cell may be <code>null</code>

Added: poi/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java?rev=736505&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java (added)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java Wed Jan 21 16:26:28 2009
@@ -0,0 +1,36 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.eval;
+
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
+
+/**
+ * An exception thrown by implementors of {@link FormulaEvaluator} when attempting to evaluate
+ * a formula which requires features that POI does not (yet) support.
+ * 
+ * @author Josh Micich
+ */
+public final class NotImplementedException extends RuntimeException {
+
+	public NotImplementedException(String message) {
+		super(message);
+	}
+	public NotImplementedException(String message, NotImplementedException cause) {
+		super(message, cause);
+	}
+}

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
Binary files - no diff available.

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java Wed Jan 21 16:26:28 2009
@@ -28,6 +28,7 @@
 import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 import org.apache.poi.ss.usermodel.CellValue;
 /**
  * 
@@ -66,11 +67,16 @@
 		assertEquals("myFunc()", actualFormula);
 		
 		HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
-		CellValue evalResult = fe.evaluate(cell);
-		
-		// Check the return value from ExternalFunction.evaluate()
+		// Check out what ExternalFunction.evaluate() does:
+		CellValue evalResult;
+		try {
+			evalResult = fe.evaluate(cell);
+		} catch (NotImplementedException e) {
+			assertEquals("Error evaluating cell Sheet1!B1", e.getMessage());
+			assertEquals("myFunc", e.getCause().getMessage());
+			return;
+		}
 		// TODO - make this test assert something more interesting as soon as ExternalFunction works a bit better
-		assertEquals(HSSFCell.CELL_TYPE_ERROR, evalResult.getCellType());
-		assertEquals(ErrorEval.FUNCTION_NOT_IMPLEMENTED.getErrorCode(), evalResult.getErrorValue());
+		assertNotNull(evalResult);
 	}
 }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java?rev=736505&r1=736504&r2=736505&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java Wed Jan 21 16:26:28 2009
@@ -24,6 +24,7 @@
 import org.apache.poi.hssf.record.formula.eval.Eval;
 import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
 import org.apache.poi.hssf.record.formula.eval.OperationEval;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
 
 /**
  * Test helper class for invoking functions with numeric results.
@@ -83,12 +84,16 @@
 				throws NumericEvalEx {
 		Eval evalResult;
 		// TODO - make OperationEval extend Function
-		if (target instanceof Function) {
-			Function ff = (Function) target;
-			evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol);
-		} else {
-			OperationEval ff = (OperationEval) target;
-			evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol);
+		try {
+			if (target instanceof Function) {
+				Function ff = (Function) target;
+				evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol);
+			} else {
+				OperationEval ff = (OperationEval) target;
+				evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol);
+			}
+		} catch (NotImplementedException e) {
+			throw new NumericEvalEx("Not implemented:" + e.getMessage());
 		}
 		
 		if(evalResult == null) {
@@ -108,9 +113,6 @@
 		return result.getNumberValue();
 	}
 	private static String formatErrorMessage(ErrorEval ee) {
-		if(errorCodesAreEqual(ee, ErrorEval.FUNCTION_NOT_IMPLEMENTED)) {
-			return "Function not implemented";
-		}
 		if(errorCodesAreEqual(ee, ErrorEval.VALUE_INVALID)) {
 			return "Error code: #VALUE! (invalid value)";
 		}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org