]> source.dussan.org Git - poi.git/commitdiff
Switch XSSF onto BaseFormulaEvaluator, reducing code duplication and fixing XSSFFormu...
authorNick Burch <nick@apache.org>
Wed, 3 Aug 2016 11:53:43 +0000 (11:53 +0000)
committerNick Burch <nick@apache.org>
Wed, 3 Aug 2016 11:53:43 +0000 (11:53 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1755079 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java
src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java

index a20d7cf25af8f6f1302150b40b2c73a4817df6c0..8d7d781f9af58cdb35b3369c2640120789772559 100644 (file)
@@ -33,8 +33,6 @@ import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.CellValue;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.util.Internal;
 
@@ -248,21 +246,7 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator {
      *  cells, and calling evaluateFormulaCell on each one.
      */
     public static void evaluateAllFormulaCells(Workbook wb) {
-        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
-        evaluateAllFormulaCells(wb, evaluator);
-    }
-    private static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
-        for(int i=0; i<wb.getNumberOfSheets(); i++) {
-            Sheet sheet = wb.getSheetAt(i);
-
-            for(Row r : sheet) {
-                for (Cell c : r) {
-                    if (c.getCellTypeEnum() == CellType.FORMULA) {
-                        evaluator.evaluateFormulaCellEnum(c);
-                    }
-                }
-            }
-        }
+        BaseFormulaEvaluator.evaluateAllFormulaCells(wb);
     }
 
     /**
index 787153dd8e5d57d46657c94ec105a70b867f49e0..8746ba7fa06d431ea2605793dcb48c1a698384a9 100644 (file)
@@ -142,8 +142,10 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook
                 return;
             case BLANK:
                 // never happens - blanks eventually get translated to zero
+                throw new IllegalArgumentException("This should never happen. Blanks eventually get translated to zero.");
             case FORMULA:
                 // this will never happen, we have already evaluated the formula
+                throw new IllegalArgumentException("This should never happen. Formulas should have already been evaluated.");
             default:
                 throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
         }
@@ -164,7 +166,7 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook
         FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
         evaluateAllFormulaCells(wb, evaluator);
     }
-    private static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
+    protected static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
         for(int i=0; i<wb.getNumberOfSheets(); i++) {
             Sheet sheet = wb.getSheetAt(i);
 
index 5fe8660b1d7239c168406ad8e9c27d0ead86a454..c6c030b957416432865aa8e4977430c538a89238 100644 (file)
 
 package org.apache.poi.xssf.usermodel;
 
-import java.util.Map;
-
-import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
+import org.apache.poi.ss.formula.BaseFormulaEvaluator;
 import org.apache.poi.ss.formula.EvaluationCell;
 import org.apache.poi.ss.formula.WorkbookEvaluator;
-import org.apache.poi.ss.formula.WorkbookEvaluatorProvider;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.eval.NumberEval;
@@ -31,28 +28,16 @@ import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.CellValue;
-import org.apache.poi.ss.usermodel.FormulaEvaluator;
 import org.apache.poi.util.Internal;
 
 /**
  * Internal POI use only - parent of XSSF and SXSSF formula evaluators
  */
-public abstract class BaseXSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider {
-    private WorkbookEvaluator _bookEvaluator;
-
+public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator {
     protected BaseXSSFFormulaEvaluator(WorkbookEvaluator bookEvaluator) {
-        _bookEvaluator = bookEvaluator;
+        super(bookEvaluator);
     }
 
-    /**
-     * Should be called whenever there are major changes (e.g. moving sheets) to input cells
-     * in the evaluated workbook.
-     * Failure to call this method after changing cell values will cause incorrect behaviour
-     * of the evaluate~ methods of this class
-     */
-    public void clearAllCachedResultValues() {
-        _bookEvaluator.clearAllCachedResultValues();
-    }
     public void notifySetFormula(Cell cell) {
         _bookEvaluator.notifyUpdateCell(new XSSFEvaluationCell((XSSFCell)cell));
     }
@@ -63,60 +48,6 @@ public abstract class BaseXSSFFormulaEvaluator implements FormulaEvaluator, Work
         _bookEvaluator.notifyUpdateCell(new XSSFEvaluationCell((XSSFCell)cell));
     }
 
-    /**
-     * If cell contains a formula, the formula is evaluated and returned,
-     * else the CellValue simply copies the appropriate cell value from
-     * the cell and also its cell type. This method should be preferred over
-     * evaluateInCell() when the call should not modify the contents of the
-     * original cell.
-     * @param cell
-     */
-    public CellValue evaluate(Cell cell) {
-        if (cell == null) {
-            return null;
-        }
-
-        switch (cell.getCellTypeEnum()) {
-            case BOOLEAN:
-                return CellValue.valueOf(cell.getBooleanCellValue());
-            case ERROR:
-                return CellValue.getError(cell.getErrorCellValue());
-            case FORMULA:
-                return evaluateFormulaCellValue(cell);
-            case NUMERIC:
-                return new CellValue(cell.getNumericCellValue());
-            case STRING:
-                return new CellValue(cell.getRichStringCellValue().getString());
-            case BLANK:
-                return null;
-            default:
-                throw new IllegalStateException("Bad cell type (" + cell.getCellTypeEnum() + ")");
-        }
-    }
-
-
-    /**
-     * If cell contains formula, it evaluates the formula,
-     *  and saves the result of the formula. The cell
-     *  remains as a formula cell.
-     * Else if cell does not contain formula, this method leaves
-     *  the cell unchanged.
-     * Note that the type of the formula result is returned,
-     *  so you know what kind of value is also stored with
-     *  the formula.
-     * <pre>
-     * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
-     * </pre>
-     * Be aware that your cell will hold both the formula,
-     *  and the result. If you want the cell replaced with
-     *  the result of the formula, use {@link #evaluate(org.apache.poi.ss.usermodel.Cell)} }
-     * @param cell The cell to evaluate
-     * @return The type of the formula result (the cell's type remains as CellType.FORMULA however)
-     */
-    public int evaluateFormulaCell(Cell cell) {
-        return evaluateFormulaCellEnum(cell).getCode();
-    }
-    
     /**
      * If cell contains formula, it evaluates the formula,
      *  and saves the result of the formula. The cell
@@ -164,27 +95,6 @@ public abstract class BaseXSSFFormulaEvaluator implements FormulaEvaluator, Work
             setCellValue(cell, cv);
         }
     }
-    private static void setCellType(Cell cell, CellValue cv) {
-        CellType cellType = cv.getCellType();
-        switch (cellType) {
-            case BOOLEAN:
-            case ERROR:
-            case NUMERIC:
-            case STRING:
-                cell.setCellType(cellType);
-                return;
-            case BLANK:
-                // never happens - blanks eventually get translated to zero
-                throw new IllegalArgumentException("This should never happen. Blanks eventually get translated to zero.");
-            case FORMULA:
-                // this will never happen, we have already evaluated the formula
-                throw new IllegalArgumentException("This should never happen. Formulas should have already been evaluated.");
-            default:
-                throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
-            
-        }
-        
-    }
 
     private static void setCellValue(Cell cell, CellValue cv) {
         CellType cellType = cv.getCellType();
@@ -218,7 +128,7 @@ public abstract class BaseXSSFFormulaEvaluator implements FormulaEvaluator, Work
     /**
      * Returns a CellValue wrapper around the supplied ValueEval instance.
      */
-    private CellValue evaluateFormulaCellValue(Cell cell) {
+    protected CellValue evaluateFormulaCellValue(Cell cell) {
         EvaluationCell evalCell = toEvaluationCell(cell);
         ValueEval eval = _bookEvaluator.evaluate(evalCell);
         if (eval instanceof NumberEval) {
@@ -238,22 +148,4 @@ public abstract class BaseXSSFFormulaEvaluator implements FormulaEvaluator, Work
         }
         throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
     }
-
-    public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> evaluators) {
-        CollaboratingWorkbooksEnvironment.setupFormulaEvaluator(evaluators);
-    }
-
-    public WorkbookEvaluator _getWorkbookEvaluator() {
-        return _bookEvaluator;
-    }
-
-    /** {@inheritDoc} */
-    public void setIgnoreMissingWorkbooks(boolean ignore){
-        _bookEvaluator.setIgnoreMissingWorkbooks(ignore);
-    }
-
-    /** {@inheritDoc} */
-    public void setDebugEvaluationOutputForNextEval(boolean value){
-        _bookEvaluator.setDebugEvaluationOutputForNextEval(value);
-    }
 }
index ec9ecd4621765f5aae11e3c9d55f10611b86078a..fc456b7e5857a9933070838cdaa93afce535f19c 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.xssf.usermodel;
 
-import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
+import org.apache.poi.ss.formula.BaseFormulaEvaluator;
 import org.apache.poi.ss.formula.EvaluationCell;
 import org.apache.poi.ss.formula.IStabilityClassifier;
 import org.apache.poi.ss.formula.WorkbookEvaluator;
@@ -88,7 +88,7 @@ public final class XSSFFormulaEvaluator extends BaseXSSFFormulaEvaluator {
      *  cells, and calling evaluateFormulaCell on each one.
      */
     public static void evaluateAllFormulaCells(XSSFWorkbook wb) {
-        HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
+        BaseFormulaEvaluator.evaluateAllFormulaCells(wb);
     }
     /**
      * Loops over all cells in all sheets of the supplied
@@ -102,7 +102,7 @@ public final class XSSFFormulaEvaluator extends BaseXSSFFormulaEvaluator {
      *  cells, and calling evaluateFormulaCell on each one.
      */
     public void evaluateAll() {
-        HSSFFormulaEvaluator.evaluateAllFormulaCells(_book);
+        evaluateAllFormulaCells(_book, this);
     }
 
     /**
index 9885fd8863387141e478e563db7f1544a4d725a2..6dcaef960378b34bc871035f5bd2c1482ff2ebf0 100644 (file)
@@ -173,8 +173,19 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator {
                 evaluator.evaluate(c);
             }
         }
+        // And evaluate the other way too
+        evaluator.evaluateAll();
         
-        // Evaluate and check results
+        // Static evaluator won't work, as no references passed in
+        try {
+            XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
+            fail("Static method lacks references, shouldn't work");
+        } catch(Exception e) {
+            // expected here
+        }
+        
+        
+        // Evaluate specific cells and check results
         assertEquals("\"Hello!\"",  evaluator.evaluate(cXSLX_cell).formatAsString());
         assertEquals("\"Test A1\"", evaluator.evaluate(cXSLX_sNR).formatAsString());
         assertEquals("142.0",   evaluator.evaluate(cXSLX_gNR).formatAsString());