Replaced ErrorEval.FUNCTION_NOT_IMPLEMENTED with new exception NotImplementedException. Removed test case involving ISREF which was working for the wrong reasons.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@736505 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c013d9b7c9
commit
59e334e8a5
@ -20,34 +20,39 @@ package org.apache.poi.hssf.record.formula.atp;
|
||||
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 @@ public final class AnalysisToolPak {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ public final class ErrorEval implements ValueEval {
|
||||
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 @@ public final class ErrorEval implements ValueEval {
|
||||
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 + ")");
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ package org.apache.poi.hssf.record.formula.eval;
|
||||
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,7 +41,6 @@ final class ExternalFunction implements FreeRefFunction {
|
||||
|
||||
Eval nameArg = args[0];
|
||||
FreeRefFunction targetFunc;
|
||||
try {
|
||||
if (nameArg instanceof NameEval) {
|
||||
targetFunc = findInternalUserDefinedFunction((NameEval) nameArg);
|
||||
} else if (nameArg instanceof NameXEval) {
|
||||
@ -49,17 +49,14 @@ final class ExternalFunction implements FreeRefFunction {
|
||||
throw new RuntimeException("First argument should be a NameEval, but got ("
|
||||
+ nameArg.getClass().getName() + ")");
|
||||
}
|
||||
} catch (EvaluationException e) {
|
||||
return e.getErrorEval();
|
||||
}
|
||||
int nOutGoingArgs = nIncomingArgs -1;
|
||||
Eval[] outGoingArgs = new Eval[nOutGoingArgs];
|
||||
System.arraycopy(args, 1, outGoingArgs, 0, nOutGoingArgs);
|
||||
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 @@ final class ExternalFunction implements FreeRefFunction {
|
||||
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 @@ final class ExternalFunction implements FreeRefFunction {
|
||||
}
|
||||
// TODO find the implementation for the user defined function
|
||||
|
||||
throw new EvaluationException(ErrorEval.FUNCTION_NOT_IMPLEMENTED);
|
||||
throw new NotImplementedException(functionName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ package org.apache.poi.hssf.record.formula.eval;
|
||||
|
||||
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 < amolweb at ya hoo dot com >
|
||||
@ -35,7 +36,7 @@ public final class FuncVarEval extends FunctionEval {
|
||||
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
|
||||
Function f = getFunction();
|
||||
if (f == null) {
|
||||
return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
|
||||
throw new NotImplementedException("FuncIx=" + getFunctionIndex());
|
||||
}
|
||||
return f.evaluate(operands, srcRow, srcCol);
|
||||
}
|
||||
|
@ -43,17 +43,14 @@ public abstract class FunctionEval implements OperationEval {
|
||||
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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 @@ public abstract class FunctionEval implements OperationEval {
|
||||
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;
|
||||
|
@ -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 final class Indirect implements FreeRefFunction {
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 < amolweb at ya hoo dot com >
|
||||
* 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 {
|
||||
private final String _functionName;
|
||||
protected NotImplementedFunction() {
|
||||
_functionName = getClass().getName();
|
||||
}
|
||||
public NotImplementedFunction(String name) {
|
||||
_functionName = name;
|
||||
}
|
||||
|
||||
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
|
||||
return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
|
||||
throw new NotImplementedException(_functionName);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||
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 @@ public final class WorkbookEvaluator {
|
||||
}
|
||||
|
||||
tracker.updateCacheResult(result);
|
||||
} catch (NotImplementedException e) {
|
||||
throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
|
||||
} finally {
|
||||
tracker.endEvaluate(cce);
|
||||
}
|
||||
@ -236,6 +239,25 @@ public final class WorkbookEvaluator {
|
||||
}
|
||||
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>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
Binary file not shown.
@ -28,6 +28,7 @@ import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
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 @@ public final class TestExternalFunction extends TestCase {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ 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.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,6 +84,7 @@ public final class NumericFunctionInvoker {
|
||||
throws NumericEvalEx {
|
||||
Eval evalResult;
|
||||
// TODO - make OperationEval extend Function
|
||||
try {
|
||||
if (target instanceof Function) {
|
||||
Function ff = (Function) target;
|
||||
evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol);
|
||||
@ -90,6 +92,9 @@ public final class NumericFunctionInvoker {
|
||||
OperationEval ff = (OperationEval) target;
|
||||
evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol);
|
||||
}
|
||||
} catch (NotImplementedException e) {
|
||||
throw new NumericEvalEx("Not implemented:" + e.getMessage());
|
||||
}
|
||||
|
||||
if(evalResult == null) {
|
||||
throw new NumericEvalEx("Result object was null");
|
||||
@ -108,9 +113,6 @@ public final class NumericFunctionInvoker {
|
||||
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)";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user