]> source.dussan.org Git - poi.git/commitdiff
Finish converting ErrorEval to only use the FormulaError constants, and then finish...
authorNick Burch <nick@apache.org>
Sun, 8 Feb 2015 15:37:14 +0000 (15:37 +0000)
committerNick Burch <nick@apache.org>
Sun, 8 Feb 2015 15:37:14 +0000 (15:37 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1658190 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/formula/eval/ErrorEval.java
src/java/org/apache/poi/ss/usermodel/FormulaError.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java

index 24e5d0a5353ac915036155907dc21576ad34b34e..82a4e9361e32023e708649a47bc56193784a9b83 100644 (file)
 
 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;
 
 /**
  * Evaluations for formula errors
  */
 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 */
     public static final ErrorEval NULL_INTERSECTION = new ErrorEval(FormulaError.NULL);
     /** <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);
 
     // POI internal error codes
-    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(FormulaError.FUNCTION_NOT_IMPLEMENTED);
 
     // 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
      * @param errorCode
      */
     public static ErrorEval valueOf(int errorCode) {
-        switch(errorCode) {
-            case ErrorConstants.ERROR_NULL:  return NULL_INTERSECTION;
-            case ErrorConstants.ERROR_DIV_0: return DIV_ZERO;
-            case ErrorConstants.ERROR_VALUE: return VALUE_INVALID;
-            case ErrorConstants.ERROR_REF:   return REF_INVALID;
-            case ErrorConstants.ERROR_NAME:  return NAME_INVALID;
-            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;
+        FormulaError error = FormulaError.forInt(errorCode);
+        ErrorEval eval = evals.get(error);
+        if (eval != null) {
+            return eval;
+        } else {
+            throw new RuntimeException("Unhandled error type " + eval + " for code " + errorCode);
         }
-        throw new RuntimeException("Unexpected error code (" + errorCode + ")");
     }
 
     /**
@@ -72,36 +70,28 @@ public final class ErrorEval implements ValueEval {
      */
     public static String getText(int errorCode) {
         if(FormulaError.isValidCode(errorCode)) {
-            return FormulaError.forInt((byte)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~";
+            return FormulaError.forInt(errorCode).getString();
         }
+        // Give a special string, based on ~, to make clear this isn't a standard Excel error
         return "~non~std~err(" + errorCode + ")~";
     }
 
-    private int _errorCode;
-    /**
-     * @param errorCode an 8-bit value
-     */
-    private ErrorEval(int errorCode) {
-        _errorCode = errorCode;
-    }
+    private FormulaError _error;
     private ErrorEval(FormulaError error) {
-        _errorCode = error.getCode();
+        _error = error;
+        evals.put(error, this);
     }
 
     public int getErrorCode() {
-        return _errorCode;
+        return _error.getLongCode();
+    }
+    public String getErrorString() {
+        return _error.getString();
     }
     public String toString() {
         StringBuffer sb = new StringBuffer(64);
         sb.append(getClass().getName()).append(" [");
-        sb.append(getText(_errorCode));
+        sb.append(_error.getString());
         sb.append("]");
         return sb.toString();
     }
index 739362436a52d069a3a24ef0150d933d133d016b..e540d69a079714192c3f2195191d9a6a9569e8f6 100644 (file)
@@ -93,7 +93,23 @@ public enum FormulaError {
      * </p>
      * 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 int longType;
@@ -151,6 +167,7 @@ public enum FormulaError {
     }
     public static FormulaError forInt(int type){
         FormulaError err = imap.get(type);
+        if(err == null) err = bmap.get((byte)type);
         if(err == null) throw new IllegalArgumentException("Unknown error type: " + type);
         return err;
     }
index 06af21cc85df3530e487f10f9b5c2878a0114bbe..c2dbb09c86d2dd8c969279891e8b38dcc1a3a09b 100644 (file)
@@ -2151,7 +2151,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
         CellValue value = evaluator.evaluate(cell);
         assertEquals(Cell.CELL_TYPE_ERROR, value.getCellType());
         assertEquals(-60, value.getErrorValue());
-        // TODO Fix this
-//        assertEquals("", FormulaError.forInt(value.getErrorValue()).toString());
+        assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString());
+        assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString());
     }
 }