Finish converting ErrorEval to only use the FormulaError constants, and then finish unit test for 57535
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1658190 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d566e3948d
commit
702f8b9ee7
@ -17,13 +17,17 @@
|
|||||||
|
|
||||||
package org.apache.poi.ss.formula.eval;
|
package org.apache.poi.ss.formula.eval;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.ErrorConstants;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.FormulaError;
|
import org.apache.poi.ss.usermodel.FormulaError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluations for formula errors
|
* Evaluations for formula errors
|
||||||
*/
|
*/
|
||||||
public final class ErrorEval implements ValueEval {
|
public final class ErrorEval implements ValueEval {
|
||||||
|
private static final Map<FormulaError,ErrorEval> evals = new HashMap<FormulaError, ErrorEval>();
|
||||||
|
|
||||||
/** <b>#NULL!</b> - Intersection of two cell ranges is empty */
|
/** <b>#NULL!</b> - Intersection of two cell ranges is empty */
|
||||||
public static final ErrorEval NULL_INTERSECTION = new ErrorEval(FormulaError.NULL);
|
public static final ErrorEval NULL_INTERSECTION = new ErrorEval(FormulaError.NULL);
|
||||||
/** <b>#DIV/0!</b> - Division by zero */
|
/** <b>#DIV/0!</b> - Division by zero */
|
||||||
@ -40,29 +44,23 @@ public final class ErrorEval implements ValueEval {
|
|||||||
public static final ErrorEval NA = new ErrorEval(FormulaError.NA);
|
public static final ErrorEval NA = new ErrorEval(FormulaError.NA);
|
||||||
|
|
||||||
// POI internal error codes
|
// POI internal error codes
|
||||||
private static final int CIRCULAR_REF_ERROR_CODE = 0xFFFFFFC4;
|
public static final ErrorEval FUNCTION_NOT_IMPLEMENTED = new ErrorEval(FormulaError.FUNCTION_NOT_IMPLEMENTED);
|
||||||
private static final int FUNCTION_NOT_IMPLEMENTED_CODE = 0xFFFFFFE2;
|
|
||||||
|
|
||||||
// Note - Excel does not seem to represent this condition with an error 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);
|
public static final ErrorEval CIRCULAR_REF_ERROR = new ErrorEval(FormulaError.CIRCULAR_REF);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates an Excel internal error code into the corresponding POI ErrorEval instance
|
* Translates an Excel internal error code into the corresponding POI ErrorEval instance
|
||||||
* @param errorCode
|
* @param errorCode
|
||||||
*/
|
*/
|
||||||
public static ErrorEval valueOf(int errorCode) {
|
public static ErrorEval valueOf(int errorCode) {
|
||||||
switch(errorCode) {
|
FormulaError error = FormulaError.forInt(errorCode);
|
||||||
case ErrorConstants.ERROR_NULL: return NULL_INTERSECTION;
|
ErrorEval eval = evals.get(error);
|
||||||
case ErrorConstants.ERROR_DIV_0: return DIV_ZERO;
|
if (eval != null) {
|
||||||
case ErrorConstants.ERROR_VALUE: return VALUE_INVALID;
|
return eval;
|
||||||
case ErrorConstants.ERROR_REF: return REF_INVALID;
|
} else {
|
||||||
case ErrorConstants.ERROR_NAME: return NAME_INVALID;
|
throw new RuntimeException("Unhandled error type " + eval + " for code " + errorCode);
|
||||||
case ErrorConstants.ERROR_NUM: return NUM_ERROR;
|
|
||||||
case ErrorConstants.ERROR_NA: return NA;
|
|
||||||
// non-std errors (conditions modelled as errors by POI)
|
|
||||||
case CIRCULAR_REF_ERROR_CODE: return CIRCULAR_REF_ERROR;
|
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Unexpected error code (" + errorCode + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,36 +70,28 @@ public final class ErrorEval implements ValueEval {
|
|||||||
*/
|
*/
|
||||||
public static String getText(int errorCode) {
|
public static String getText(int errorCode) {
|
||||||
if(FormulaError.isValidCode(errorCode)) {
|
if(FormulaError.isValidCode(errorCode)) {
|
||||||
return FormulaError.forInt((byte)errorCode).getString();
|
return FormulaError.forInt(errorCode).getString();
|
||||||
}
|
|
||||||
// It is desirable to make these (arbitrary) strings look clearly different from any other
|
|
||||||
// value expression that might appear in a formula. In addition these error strings should
|
|
||||||
// look unlike the standard Excel errors. Hence tilde ('~') was used.
|
|
||||||
switch(errorCode) {
|
|
||||||
case CIRCULAR_REF_ERROR_CODE: return "~CIRCULAR~REF~";
|
|
||||||
case FUNCTION_NOT_IMPLEMENTED_CODE: return "~FUNCTION~NOT~IMPLEMENTED~";
|
|
||||||
}
|
}
|
||||||
|
// Give a special string, based on ~, to make clear this isn't a standard Excel error
|
||||||
return "~non~std~err(" + errorCode + ")~";
|
return "~non~std~err(" + errorCode + ")~";
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _errorCode;
|
private FormulaError _error;
|
||||||
/**
|
|
||||||
* @param errorCode an 8-bit value
|
|
||||||
*/
|
|
||||||
private ErrorEval(int errorCode) {
|
|
||||||
_errorCode = errorCode;
|
|
||||||
}
|
|
||||||
private ErrorEval(FormulaError error) {
|
private ErrorEval(FormulaError error) {
|
||||||
_errorCode = error.getCode();
|
_error = error;
|
||||||
|
evals.put(error, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getErrorCode() {
|
public int getErrorCode() {
|
||||||
return _errorCode;
|
return _error.getLongCode();
|
||||||
|
}
|
||||||
|
public String getErrorString() {
|
||||||
|
return _error.getString();
|
||||||
}
|
}
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer(64);
|
StringBuffer sb = new StringBuffer(64);
|
||||||
sb.append(getClass().getName()).append(" [");
|
sb.append(getClass().getName()).append(" [");
|
||||||
sb.append(getText(_errorCode));
|
sb.append(_error.getString());
|
||||||
sb.append("]");
|
sb.append("]");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,23 @@ public enum FormulaError {
|
|||||||
* </p>
|
* </p>
|
||||||
* This error value can be produced by calling the function NA
|
* This error value can be produced by calling the function NA
|
||||||
*/
|
*/
|
||||||
NA(0x2A, "#N/A");
|
NA(0x2A, "#N/A"),
|
||||||
|
|
||||||
|
// These are POI-specific error codes
|
||||||
|
// It is desirable to make these (arbitrary) strings look clearly different from any other
|
||||||
|
// value expression that might appear in a formula. In addition these error strings should
|
||||||
|
// look unlike the standard Excel errors. Hence tilde ('~') was used.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POI specific code to indicate that there is a circular reference
|
||||||
|
* in the formula
|
||||||
|
*/
|
||||||
|
CIRCULAR_REF(0xFFFFFFC4, "~CIRCULAR~REF~"),
|
||||||
|
/**
|
||||||
|
* POI specific code to indicate that the funcition required is
|
||||||
|
* not implemented in POI
|
||||||
|
*/
|
||||||
|
FUNCTION_NOT_IMPLEMENTED(0xFFFFFFE2, "~FUNCTION~NOT~IMPLEMENTED~");
|
||||||
|
|
||||||
private final byte type;
|
private final byte type;
|
||||||
private final int longType;
|
private final int longType;
|
||||||
@ -151,6 +167,7 @@ public enum FormulaError {
|
|||||||
}
|
}
|
||||||
public static FormulaError forInt(int type){
|
public static FormulaError forInt(int type){
|
||||||
FormulaError err = imap.get(type);
|
FormulaError err = imap.get(type);
|
||||||
|
if(err == null) err = bmap.get((byte)type);
|
||||||
if(err == null) throw new IllegalArgumentException("Unknown error type: " + type);
|
if(err == null) throw new IllegalArgumentException("Unknown error type: " + type);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -2151,7 +2151,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
|
|||||||
CellValue value = evaluator.evaluate(cell);
|
CellValue value = evaluator.evaluate(cell);
|
||||||
assertEquals(Cell.CELL_TYPE_ERROR, value.getCellType());
|
assertEquals(Cell.CELL_TYPE_ERROR, value.getCellType());
|
||||||
assertEquals(-60, value.getErrorValue());
|
assertEquals(-60, value.getErrorValue());
|
||||||
// TODO Fix this
|
assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString());
|
||||||
// assertEquals("", FormulaError.forInt(value.getErrorValue()).toString());
|
assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user