From 40ca65f97ec7ff20a192566d8f23a71862de7735 Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Fri, 12 Sep 2008 08:18:54 +0000 Subject: [PATCH] Made HSSFFormulaEvaluator no longer require initialisation with sheet or row. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@694643 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 1 + src/documentation/content/xdocs/status.xml | 1 + .../record/formula/atp/AnalysisToolPak.java | 5 +- .../record/formula/atp/ParityFunction.java | 8 +- .../poi/hssf/record/formula/atp/YearFrac.java | 12 +- .../record/formula/eval/ExternalFunction.java | 6 +- .../formula/functions/FreeRefFunction.java | 4 +- .../record/formula/functions/Indirect.java | 2 +- .../usermodel/EvaluationCycleDetector.java | 22 +- .../hssf/usermodel/HSSFFormulaEvaluator.java | 392 ++++++++---------- .../eval => usermodel}/LazyAreaEval.java | 14 +- .../eval => usermodel}/LazyRefEval.java | 14 +- .../poi/hssf/model/TestFormulaParserEval.java | 2 +- .../formula/TestExternalFunctionFormulas.java | 2 +- ...TestYearFracCalculatorFromSpreadsheet.java | 2 +- .../formula/eval/TestCircularReferences.java | 10 +- .../formula/eval/TestExternalFunction.java | 2 +- .../record/formula/eval/TestFormulaBugs.java | 6 +- .../eval/TestFormulasFromSpreadsheet.java | 2 +- .../record/formula/eval/TestPercentEval.java | 2 +- .../formula/functions/TestCountFuncs.java | 2 +- .../record/formula/functions/TestDate.java | 2 +- .../TestIndexFunctionFromSpreadsheet.java | 2 +- .../record/formula/functions/TestIsBlank.java | 2 +- .../TestLookupFunctionsFromSpreadsheet.java | 2 +- .../poi/hssf/usermodel/TestBug42464.java | 3 +- .../poi/hssf/usermodel/TestBug43093.java | 4 +- .../apache/poi/hssf/usermodel/TestBugs.java | 2 +- .../usermodel/TestFormulaEvaluatorBugs.java | 12 +- .../usermodel/TestFormulaEvaluatorDocs.java | 4 +- .../hssf/usermodel/TestHSSFDataFormatter.java | 4 +- .../usermodel/TestHSSFFormulaEvaluator.java | 4 +- 32 files changed, 262 insertions(+), 290 deletions(-) rename src/java/org/apache/poi/hssf/{record/formula/eval => usermodel}/LazyAreaEval.java (87%) rename src/java/org/apache/poi/hssf/{record/formula/eval => usermodel}/LazyRefEval.java (85%) diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index f789defe0d..5f7c09520a 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + Made HSSFFormulaEvaluator no longer require initialisation with sheet or row Extended support for cached results of formula cells 45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate Fixed special cases of INDEX function (single column/single row, errors) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 579816b5ba..e62842ba3a 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + Made HSSFFormulaEvaluator no longer require initialisation with sheet or row Extended support for cached results of formula cells 45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate Fixed special cases of INDEX function (single column/single row, errors) diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java b/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java index f46b4aea71..f528fb67bd 100644 --- a/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java +++ b/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java @@ -24,15 +24,14 @@ 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.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; public final class AnalysisToolPak { private static final FreeRefFunction NotImplemented = new FreeRefFunction() { - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, - HSSFWorkbook workbook, HSSFSheet sheet) { + public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, + int srcCellRow, int srcCellCol) { return ErrorEval.FUNCTION_NOT_IMPLEMENTED; } }; diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java b/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java index f7ea76a367..a6dd10a846 100644 --- a/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java +++ b/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java @@ -42,8 +42,8 @@ final class ParityFunction implements FreeRefFunction { _desiredParity = desiredParity; } - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, - HSSFSheet sheet) { + public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow, + int srcCellCol) { if (args.length != 1) { return ErrorEval.VALUE_INVALID; } @@ -58,8 +58,8 @@ final class ParityFunction implements FreeRefFunction { return BoolEval.valueOf(val == _desiredParity); } - private static int evaluateArgParity(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); + private static int evaluateArgParity(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException { + ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short)srcCellCol); double d = OperandResolver.coerceValueToDouble(ve); if (d < 0) { diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java b/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java index 005599d45f..f48eba8d5e 100644 --- a/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java +++ b/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java @@ -61,8 +61,8 @@ final class YearFrac implements FreeRefFunction { // enforce singleton } - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, - HSSFSheet sheet) { + public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow, + int srcCellCol) { double result; try { @@ -85,8 +85,8 @@ final class YearFrac implements FreeRefFunction { return new NumberEval(result); } - private static double evaluateDateArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); + private static double evaluateDateArg(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException { + ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol); if (ve instanceof StringEval) { String strVal = ((StringEval) ve).getStringValue(); @@ -155,8 +155,8 @@ final class YearFrac implements FreeRefFunction { return cal; } - private static int evaluateIntArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); + private static int evaluateIntArg(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException { + ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol); return OperandResolver.coerceValueToInt(ve); } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java b/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java index 8abab17a5b..96cc64310a 100755 --- a/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java @@ -19,7 +19,6 @@ 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.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; /** * @@ -31,7 +30,8 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook; */ final class ExternalFunction implements FreeRefFunction { - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { + public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, + int srcCellSheet, int srcCellRow,int srcCellCol) { int nIncomingArgs = args.length; if(nIncomingArgs < 1) { @@ -55,7 +55,7 @@ final class ExternalFunction implements FreeRefFunction { int nOutGoingArgs = nIncomingArgs -1; Eval[] outGoingArgs = new Eval[nOutGoingArgs]; System.arraycopy(args, 1, outGoingArgs, 0, nOutGoingArgs); - return targetFunc.evaluate(outGoingArgs, srcCellRow, srcCellCol, workbook, sheet); + return targetFunc.evaluate(outGoingArgs, workbook, srcCellSheet, srcCellRow, srcCellCol); } private FreeRefFunction findExternalUserDefinedFunction(HSSFWorkbook workbook, diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java index 56d285543e..977c1b363e 100755 --- a/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java @@ -45,13 +45,13 @@ public interface FreeRefFunction { * * @param args the pre-evaluated arguments for this function. args is never null, * nor are any of its elements. + * @param srcCellSheet zero based sheet index of the cell containing the currently evaluating formula * @param srcCellRow zero based row index of the cell containing the currently evaluating formula * @param srcCellCol zero based column index of the cell containing the currently evaluating formula * @param workbook is the workbook containing the formula/cell being evaluated - * @param sheet is the sheet containing the formula/cell being evaluated * @return never null. Possibly an instance of ErrorEval in the case of * a specified Excel error (Exceptions are never thrown to represent Excel errors). * */ - ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet); + ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow, int srcCellCol); } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java b/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java index 935e7cdbbd..f4036c107b 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java @@ -41,7 +41,7 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook; */ public final class Indirect implements FreeRefFunction { - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { + public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow, int srcCellCol) { // TODO - implement INDIRECT() return ErrorEval.FUNCTION_NOT_IMPLEMENTED; } diff --git a/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java b/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java index 90f5807ff5..0c168af6b3 100755 --- a/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java +++ b/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java @@ -37,19 +37,19 @@ final class EvaluationCycleDetector { private static final class CellEvaluationFrame { private final HSSFWorkbook _workbook; - private final HSSFSheet _sheet; + private final int _sheetIndex; private final int _srcRowNum; private final int _srcColNum; - public CellEvaluationFrame(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { + public CellEvaluationFrame(HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) { if (workbook == null) { throw new IllegalArgumentException("workbook must not be null"); } - if (sheet == null) { - throw new IllegalArgumentException("sheet must not be null"); + if (sheetIndex < 0) { + throw new IllegalArgumentException("sheetIndex must not be negative"); } _workbook = workbook; - _sheet = sheet; + _sheetIndex = sheetIndex; _srcRowNum = srcRowNum; _srcColNum = srcColNum; } @@ -59,7 +59,7 @@ final class EvaluationCycleDetector { if (_workbook != other._workbook) { return false; } - if (_sheet != other._sheet) { + if (_sheetIndex != other._sheetIndex) { return false; } if (_srcRowNum != other._srcRowNum) { @@ -75,7 +75,7 @@ final class EvaluationCycleDetector { * @return human readable string for debug purposes */ public String formatAsString() { - return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _workbook.getSheetIndex(_sheet); + return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _sheetIndex; } public String toString() { @@ -108,8 +108,8 @@ final class EvaluationCycleDetector { * @return true if the specified cell has not been visited yet in the current * evaluation. false if the specified cell is already being evaluated. */ - public boolean startEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { - CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum); + public boolean startEvaluate(HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) { + CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheetIndex, srcRowNum, srcColNum); if (_evaluationFrames.contains(cef)) { return false; } @@ -129,7 +129,7 @@ final class EvaluationCycleDetector { * required. However, they have been included to assert correct behaviour, * and form more meaningful error messages. */ - public void endEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { + public void endEvaluate(HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) { int nFrames = _evaluationFrames.size(); if (nFrames < 1) { throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate"); @@ -137,7 +137,7 @@ final class EvaluationCycleDetector { nFrames--; CellEvaluationFrame cefExpected = (CellEvaluationFrame) _evaluationFrames.get(nFrames); - CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum); + CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheetIndex, srcRowNum, srcColNum); if (!cefActual.equals(cefExpected)) { throw new RuntimeException("Wrong cell specified. " + "Corresponding startEvaluate() call was for cell {" diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index be0262292f..57eebc1dcb 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -47,8 +47,6 @@ import org.apache.poi.hssf.record.formula.eval.BoolEval; 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.FunctionEval; -import org.apache.poi.hssf.record.formula.eval.LazyAreaEval; -import org.apache.poi.hssf.record.formula.eval.LazyRefEval; import org.apache.poi.hssf.record.formula.eval.NameEval; import org.apache.poi.hssf.record.formula.eval.NameXEval; import org.apache.poi.hssf.record.formula.eval.NumberEval; @@ -70,28 +68,36 @@ import org.apache.poi.hssf.util.CellReference; */ public class HSSFFormulaEvaluator { - /** - * used to track the number of evaluations - */ + /** + * used to track the number of evaluations + */ private static final class Counter { public int value; + public int depth; public Counter() { value = 0; } } - private final HSSFSheet _sheet; private final HSSFWorkbook _workbook; private final EvaluationCache _cache; private Counter _evaluationCounter; + /** + * @deprecated (Sep 2008) HSSFSheet parameter is ignored + */ public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) { - this(sheet, workbook, new EvaluationCache(), new Counter()); + this(workbook); + if (false) { + sheet.toString(); // suppress unused parameter compiler warning + } + } + public HSSFFormulaEvaluator(HSSFWorkbook workbook) { + this(workbook, new EvaluationCache(), new Counter()); } - private HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook, EvaluationCache cache, Counter evaluationCounter) { - _sheet = sheet; + private HSSFFormulaEvaluator(HSSFWorkbook workbook, EvaluationCache cache, Counter evaluationCounter) { _workbook = workbook; _cache = cache; _evaluationCounter = evaluationCounter; @@ -100,7 +106,7 @@ public class HSSFFormulaEvaluator { /** * for debug use. Used in toString methods */ - public String getSheetName(HSSFSheet sheet) { + /* package */ String getSheetName(HSSFSheet sheet) { return _workbook.getSheetName(_workbook.getSheetIndex(sheet)); } /** @@ -159,34 +165,23 @@ public class HSSFFormulaEvaluator { * @param cell */ public CellValue evaluate(HSSFCell cell) { - CellValue retval = null; - if (cell != null) { - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_BLANK: - retval = new CellValue(HSSFCell.CELL_TYPE_BLANK); - break; + if (cell == null) { + return null; + } + + switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_BOOLEAN: - retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN); - retval.setBooleanValue(cell.getBooleanCellValue()); - break; + return CellValue.valueOf(cell.getBooleanCellValue()); case HSSFCell.CELL_TYPE_ERROR: - retval = new CellValue(HSSFCell.CELL_TYPE_ERROR); - retval.setErrorValue(cell.getErrorCellValue()); - break; + return CellValue.getError(cell.getErrorCellValue()); case HSSFCell.CELL_TYPE_FORMULA: - retval = getCellValueForEval(internalEvaluate(cell, _sheet)); - break; + return evaluateFormulaCellValue(cell); case HSSFCell.CELL_TYPE_NUMERIC: - retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC); - retval.setNumberValue(cell.getNumericCellValue()); - break; + return new CellValue(cell.getNumericCellValue()); case HSSFCell.CELL_TYPE_STRING: - retval = new CellValue(HSSFCell.CELL_TYPE_STRING); - retval.setRichTextStringValue(cell.getRichStringCellValue()); - break; - } + return new CellValue(cell.getRichStringCellValue()); } - return retval; + throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")"); } @@ -209,32 +204,13 @@ public class HSSFFormulaEvaluator { * @return The type of the formula result (the cell's type remains as HSSFCell.CELL_TYPE_FORMULA however) */ public int evaluateFormulaCell(HSSFCell cell) { - if (cell != null) { - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_FORMULA: - CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet)); - switch (cv.getCellType()) { - case HSSFCell.CELL_TYPE_BOOLEAN: - cell.setCellValue(cv.getBooleanValue()); - break; - case HSSFCell.CELL_TYPE_ERROR: - cell.setCellValue(cv.getErrorValue()); - break; - case HSSFCell.CELL_TYPE_NUMERIC: - cell.setCellValue(cv.getNumberValue()); - break; - case HSSFCell.CELL_TYPE_STRING: - cell.setCellValue(cv.getRichTextStringValue()); - break; - case HSSFCell.CELL_TYPE_BLANK: - break; - case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula - break; - } - return cv.getCellType(); - } + if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) { + return -1; } - return -1; + CellValue cv = evaluateFormulaCellValue(cell); + // cell remains a formula cell, but the cached value is changed + setCellValue(cell, cv); + return cv.getCellType(); } /** @@ -254,35 +230,56 @@ public class HSSFFormulaEvaluator { * @param cell */ public HSSFCell evaluateInCell(HSSFCell cell) { - if (cell != null) { - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_FORMULA: - CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet)); - switch (cv.getCellType()) { - case HSSFCell.CELL_TYPE_BOOLEAN: - cell.setCellType(HSSFCell.CELL_TYPE_BOOLEAN); - cell.setCellValue(cv.getBooleanValue()); - break; - case HSSFCell.CELL_TYPE_ERROR: - cell.setCellErrorValue(cv.getErrorValue()); - break; - case HSSFCell.CELL_TYPE_NUMERIC: - cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - cell.setCellValue(cv.getNumberValue()); - break; - case HSSFCell.CELL_TYPE_STRING: - cell.setCellType(HSSFCell.CELL_TYPE_STRING); - cell.setCellValue(cv.getRichTextStringValue()); - break; - case HSSFCell.CELL_TYPE_BLANK: - break; - case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula - break; - } - } + if (cell == null) { + return null; + } + if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) { + CellValue cv = evaluateFormulaCellValue(cell); + setCellType(cell, cv); // cell will no longer be a formula cell + setCellValue(cell, cv); } return cell; } + private static void setCellType(HSSFCell cell, CellValue cv) { + int cellType = cv.getCellType(); + switch (cellType) { + case HSSFCell.CELL_TYPE_BOOLEAN: + case HSSFCell.CELL_TYPE_ERROR: + case HSSFCell.CELL_TYPE_NUMERIC: + case HSSFCell.CELL_TYPE_STRING: + cell.setCellType(cellType); + return; + case HSSFCell.CELL_TYPE_BLANK: + // never happens - blanks eventually get translated to zero + case HSSFCell.CELL_TYPE_FORMULA: + // this will never happen, we have already evaluated the formula + } + throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); + } + + private static void setCellValue(HSSFCell cell, CellValue cv) { + int cellType = cv.getCellType(); + switch (cellType) { + case HSSFCell.CELL_TYPE_BOOLEAN: + cell.setCellValue(cv.getBooleanValue()); + break; + case HSSFCell.CELL_TYPE_ERROR: + cell.setCellErrorValue(cv.getErrorValue()); + break; + case HSSFCell.CELL_TYPE_NUMERIC: + cell.setCellValue(cv.getNumberValue()); + break; + case HSSFCell.CELL_TYPE_STRING: + cell.setCellValue(cv.getRichTextStringValue()); + break; + case HSSFCell.CELL_TYPE_BLANK: + // never happens - blanks eventually get translated to zero + case HSSFCell.CELL_TYPE_FORMULA: + // this will never happen, we have already evaluated the formula + default: + throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); + } + } /** * Loops over all cells in all sheets of the supplied @@ -296,9 +293,9 @@ public class HSSFFormulaEvaluator { * cells, and calling evaluateFormulaCell on each one. */ public static void evaluateAllFormulaCells(HSSFWorkbook wb) { + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); for(int i=0; inull, never {@link BlankEval} */ - private ValueEval internalEvaluate(HSSFCell srcCell, HSSFSheet sheet) { + private ValueEval internalEvaluate(HSSFCell srcCell) { int srcRowNum = srcCell.getRowIndex(); int srcColNum = srcCell.getCellNum(); ValueEval result; - int sheetIndex = _workbook.getSheetIndex(sheet); + int sheetIndex = _workbook.findSheetIndex(srcCell.getSheet()); result = _cache.getValue(sheetIndex, srcRowNum, srcColNum); if (result != null) { return result; } _evaluationCounter.value++; + _evaluationCounter.depth++; EvaluationCycleDetector tracker = EvaluationCycleDetectorManager.getTracker(); - if(!tracker.startEvaluate(_workbook, sheet, srcRowNum, srcColNum)) { + if(!tracker.startEvaluate(_workbook, sheetIndex, srcRowNum, srcColNum)) { return ErrorEval.CIRCULAR_REF_ERROR; } try { - result = evaluateCell(srcRowNum, (short)srcColNum, srcCell.getCellFormula()); + result = evaluateCell(sheetIndex, srcRowNum, (short)srcColNum, srcCell.getCellFormula()); } finally { - tracker.endEvaluate(_workbook, sheet, srcRowNum, srcColNum); + tracker.endEvaluate(_workbook, sheetIndex, srcRowNum, srcColNum); _cache.setValue(sheetIndex, srcRowNum, srcColNum, result); + _evaluationCounter.depth--; } if (isDebugLogEnabled()) { String sheetName = _workbook.getSheetName(sheetIndex); @@ -386,7 +372,7 @@ public class HSSFFormulaEvaluator { } return result; } - private ValueEval evaluateCell(int srcRowNum, short srcColNum, String cellFormulaText) { + private ValueEval evaluateCell(int sheetIndex, int srcRowNum, short srcColNum, String cellFormulaText) { Ptg[] ptgs = FormulaParser.parse(cellFormulaText, _workbook); @@ -420,15 +406,15 @@ public class HSSFFormulaEvaluator { Eval p = (Eval) stack.pop(); ops[j] = p; } - logDebug("invoke " + operation + " (nAgs=" + numops + ")"); - opResult = invokeOperation(operation, ops, srcRowNum, srcColNum, _workbook, _sheet); +// logDebug("invoke " + operation + " (nAgs=" + numops + ")"); + opResult = invokeOperation(operation, ops, _workbook, sheetIndex, srcRowNum, srcColNum); } else { - opResult = getEvalForPtg(ptg, _sheet); + opResult = getEvalForPtg(ptg, sheetIndex); } if (opResult == null) { throw new RuntimeException("Evaluation result must not be null"); } - logDebug("push " + opResult); +// logDebug("push " + opResult); stack.push(opResult); } @@ -473,25 +459,22 @@ public class HSSFFormulaEvaluator { return evaluationResult; } - private static Eval invokeOperation(OperationEval operation, Eval[] ops, int srcRowNum, short srcColNum, - HSSFWorkbook workbook, HSSFSheet sheet) { + private static Eval invokeOperation(OperationEval operation, Eval[] ops, + HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) { if(operation instanceof FunctionEval) { FunctionEval fe = (FunctionEval) operation; if(fe.isFreeRefFunction()) { - return fe.getFreeRefFunction().evaluate(ops, srcRowNum, srcColNum, workbook, sheet); + return fe.getFreeRefFunction().evaluate(ops, workbook, sheetIndex, srcRowNum, srcColNum); } } - return operation.evaluate(ops, srcRowNum, srcColNum); + return operation.evaluate(ops, srcRowNum, (short)srcColNum); } private HSSFSheet getOtherSheet(int externSheetIndex) { Workbook wb = _workbook.getWorkbook(); return _workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(externSheetIndex)); } - private HSSFFormulaEvaluator createEvaluatorForAnotherSheet(HSSFSheet sheet) { - return new HSSFFormulaEvaluator(sheet, _workbook, _cache, _evaluationCounter); - } /** * returns an appropriate Eval impl instance for the Ptg. The Ptg must be @@ -499,7 +482,7 @@ public class HSSFFormulaEvaluator { * StringPtg, BoolPtg
special Note: OperationPtg subtypes cannot be * passed here! */ - private Eval getEvalForPtg(Ptg ptg, HSSFSheet sheet) { + private Eval getEvalForPtg(Ptg ptg, int sheetIndex) { if (ptg instanceof NamePtg) { // named ranges, macro functions NamePtg namePtg = (NamePtg) ptg; @@ -514,7 +497,7 @@ public class HSSFFormulaEvaluator { return new NameEval(nameRecord.getNameText()); } if (nameRecord.hasFormula()) { - return evaluateNameFormula(nameRecord.getNameDefinition(), sheet); + return evaluateNameFormula(nameRecord.getNameDefinition(), sheetIndex); } throw new RuntimeException("Don't now how to evalate name '" + nameRecord.getNameText() + "'"); @@ -523,22 +506,6 @@ public class HSSFFormulaEvaluator { NameXPtg nameXPtg = (NameXPtg) ptg; return new NameXEval(nameXPtg.getSheetRefIndex(), nameXPtg.getNameIndex()); } - if (ptg instanceof RefPtg) { - return new LazyRefEval(((RefPtg) ptg), sheet, this); - } - if (ptg instanceof Ref3DPtg) { - Ref3DPtg refPtg = (Ref3DPtg) ptg; - HSSFSheet xsheet = getOtherSheet(refPtg.getExternSheetIndex()); - return new LazyRefEval(refPtg, xsheet, createEvaluatorForAnotherSheet(xsheet)); - } - if (ptg instanceof AreaPtg) { - return new LazyAreaEval(((AreaPtg) ptg), sheet, this); - } - if (ptg instanceof Area3DPtg) { - Area3DPtg a3dp = (Area3DPtg) ptg; - HSSFSheet xsheet = getOtherSheet(a3dp.getExternSheetIndex()); - return new LazyAreaEval(a3dp, xsheet, createEvaluatorForAnotherSheet(xsheet)); - } if (ptg instanceof IntPtg) { return new NumberEval(((IntPtg)ptg).getValue()); @@ -555,17 +522,38 @@ public class HSSFFormulaEvaluator { if (ptg instanceof ErrPtg) { return ErrorEval.valueOf(((ErrPtg) ptg).getErrorCode()); } + HSSFSheet sheet = _workbook.getSheetAt(sheetIndex); + if (ptg instanceof RefPtg) { + return new LazyRefEval(((RefPtg) ptg), sheet, this); + } + if (ptg instanceof AreaPtg) { + return new LazyAreaEval(((AreaPtg) ptg), sheet, this); + } + if (ptg instanceof Ref3DPtg) { + Ref3DPtg refPtg = (Ref3DPtg) ptg; + HSSFSheet xsheet = getOtherSheet(refPtg.getExternSheetIndex()); + return new LazyRefEval(refPtg, xsheet, this); + } + if (ptg instanceof Area3DPtg) { + Area3DPtg a3dp = (Area3DPtg) ptg; + HSSFSheet xsheet = getOtherSheet(a3dp.getExternSheetIndex()); + return new LazyAreaEval(a3dp, xsheet, this); + } + if (ptg instanceof UnknownPtg) { - // TODO - remove UnknownPtg + // POI uses UnknownPtg when the encoded Ptg array seems to be corrupted. + // This seems to occur in very rare cases (e.g. unused name formulas in bug 44774, attachment 21790) + // In any case, formulas are re-parsed before execution, so UnknownPtg should not get here throw new RuntimeException("UnknownPtg not allowed"); } + throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")"); } - private Eval evaluateNameFormula(Ptg[] ptgs, HSSFSheet sheet) { + private Eval evaluateNameFormula(Ptg[] ptgs, int sheetIndex) { if (ptgs.length > 1) { throw new RuntimeException("Complex name formulas not supported yet"); } - return getEvalForPtg(ptgs[0], sheet); + return getEvalForPtg(ptgs[0], sheetIndex); } /** @@ -573,11 +561,8 @@ public class HSSFFormulaEvaluator { * impl instance and return that. Since the cell could be an external * reference, we need the sheet that this belongs to. * Non existent cells are treated as empty. - * @param cell - * @param sheet - * @param workbook */ - public ValueEval getEvalForCell(HSSFCell cell, HSSFSheet sheet) { + /* package */ ValueEval getEvalForCell(HSSFCell cell) { if (cell == null) { return BlankEval.INSTANCE; @@ -588,7 +573,7 @@ public class HSSFFormulaEvaluator { case HSSFCell.CELL_TYPE_STRING: return new StringEval(cell.getRichStringCellValue().getString()); case HSSFCell.CELL_TYPE_FORMULA: - return internalEvaluate(cell, sheet); + return internalEvaluate(cell); case HSSFCell.CELL_TYPE_BOOLEAN: return BoolEval.valueOf(cell.getBooleanCellValue()); case HSSFCell.CELL_TYPE_BLANK: @@ -606,43 +591,50 @@ public class HSSFFormulaEvaluator { * @author Amol S. Deshmukh < amolweb at ya hoo dot com > */ public static final class CellValue { - private int cellType; - private HSSFRichTextString richTextStringValue; - private double numberValue; - private boolean booleanValue; - private byte errorValue; - - /** - * CellType should be one of the types defined in HSSFCell - * @param cellType - */ - public CellValue(int cellType) { - super(); - this.cellType = cellType; - } + public static final CellValue TRUE = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN, 0.0, true, null, 0); + public static final CellValue FALSE= new CellValue(HSSFCell.CELL_TYPE_BOOLEAN, 0.0, false, null, 0); + + private final int _cellType; + private final double _numberValue; + private final boolean _booleanValue; + private final HSSFRichTextString _richTextStringValue; + private final int _errorCode; + + private CellValue(int cellType, double numberValue, boolean booleanValue, + HSSFRichTextString textValue, int errorCode) { + _cellType = cellType; + _numberValue = numberValue; + _booleanValue = booleanValue; + _richTextStringValue = textValue; + _errorCode = errorCode; + } + + + /* package*/ CellValue(double numberValue) { + this(HSSFCell.CELL_TYPE_NUMERIC, numberValue, false, null, 0); + } + /* package*/ static CellValue valueOf(boolean booleanValue) { + return booleanValue ? TRUE : FALSE; + } + /* package*/ CellValue(HSSFRichTextString stringValue) { + this(HSSFCell.CELL_TYPE_STRING, 0.0, false, stringValue, 0); + } + /* package*/ static CellValue getError(int errorCode) { + return new CellValue(HSSFCell.CELL_TYPE_ERROR, 0.0, false, null, errorCode); + } + + /** * @return Returns the booleanValue. */ public boolean getBooleanValue() { - return booleanValue; - } - /** - * @param booleanValue The booleanValue to set. - */ - public void setBooleanValue(boolean booleanValue) { - this.booleanValue = booleanValue; + return _booleanValue; } /** * @return Returns the numberValue. */ public double getNumberValue() { - return numberValue; - } - /** - * @param numberValue The numberValue to set. - */ - public void setNumberValue(double numberValue) { - this.numberValue = numberValue; + return _numberValue; } /** * @return Returns the stringValue. This method is deprecated, use @@ -650,45 +642,25 @@ public class HSSFFormulaEvaluator { * @deprecated */ public String getStringValue() { - return richTextStringValue.getString(); - } - /** - * @param stringValue The stringValue to set. This method is deprecated, use - * getRichTextStringValue instead. - * @deprecated - */ - public void setStringValue(String stringValue) { - this.richTextStringValue = new HSSFRichTextString(stringValue); + return _richTextStringValue.getString(); } /** * @return Returns the cellType. */ public int getCellType() { - return cellType; + return _cellType; } /** * @return Returns the errorValue. */ public byte getErrorValue() { - return errorValue; - } - /** - * @param errorValue The errorValue to set. - */ - public void setErrorValue(byte errorValue) { - this.errorValue = errorValue; + return (byte) _errorCode; } /** * @return Returns the richTextStringValue. */ public HSSFRichTextString getRichTextStringValue() { - return richTextStringValue; - } - /** - * @param richTextStringValue The richTextStringValue to set. - */ - public void setRichTextStringValue(HSSFRichTextString richTextStringValue) { - this.richTextStringValue = richTextStringValue; + return _richTextStringValue; } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LazyAreaEval.java b/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java similarity index 87% rename from src/java/org/apache/poi/hssf/record/formula/eval/LazyAreaEval.java rename to src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java index e2dc42e056..0e1d1fd005 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/LazyAreaEval.java +++ b/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java @@ -15,21 +15,21 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hssf.record.formula.eval; +package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.record.formula.AreaI; import org.apache.poi.hssf.record.formula.AreaI.OffsetArea; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.record.formula.eval.AreaEval; +import org.apache.poi.hssf.record.formula.eval.AreaEvalBase; +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.util.CellReference; /** * * @author Josh Micich */ -public final class LazyAreaEval extends AreaEvalBase { +final class LazyAreaEval extends AreaEvalBase { private final HSSFSheet _sheet; private HSSFFormulaEvaluator _evaluator; @@ -53,7 +53,7 @@ public final class LazyAreaEval extends AreaEvalBase { if (cell == null) { return BlankEval.INSTANCE; } - return _evaluator.getEvalForCell(cell, _sheet); + return _evaluator.getEvalForCell(cell); } public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LazyRefEval.java b/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java similarity index 85% rename from src/java/org/apache/poi/hssf/record/formula/eval/LazyRefEval.java rename to src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java index 436bb4ccbe..d26ac59ffd 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/LazyRefEval.java +++ b/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java @@ -15,23 +15,23 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hssf.record.formula.eval; +package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.record.formula.AreaI; import org.apache.poi.hssf.record.formula.Ref3DPtg; import org.apache.poi.hssf.record.formula.RefPtg; import org.apache.poi.hssf.record.formula.AreaI.OffsetArea; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.record.formula.eval.AreaEval; +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.RefEvalBase; +import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.util.CellReference; /** * * @author Josh Micich */ -public final class LazyRefEval extends RefEvalBase { +final class LazyRefEval extends RefEvalBase { private final HSSFSheet _sheet; private final HSSFFormulaEvaluator _evaluator; @@ -60,7 +60,7 @@ public final class LazyRefEval extends RefEvalBase { if (cell == null) { return BlankEval.INSTANCE; } - return _evaluator.getEvalForCell(cell, _sheet); + return _evaluator.getEvalForCell(cell); } public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java index ac55ce619f..2bede8e5f5 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java @@ -85,7 +85,7 @@ public final class TestFormulaParserEval extends TestCase { sheet.createRow(32768).createCell(0).setCellValue(31); sheet.createRow(32769).createCell(0).setCellValue(11); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue result; try { result = fe.evaluate(cell); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java b/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java index dbfc8269da..53d51ca0f1 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java @@ -74,7 +74,7 @@ public final class TestExternalFunctionFormulas extends TestCase { public void testEvaluate() { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls"); HSSFSheet sheet = wb.getSheetAt(0); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); confirmCellEval(sheet, 0, 0, fe, "YEARFRAC(B1,C1)", 29.0/90.0); confirmCellEval(sheet, 1, 0, fe, "YEARFRAC(B2,C2)", 0.0); confirmCellEval(sheet, 2, 0, fe, "YEARFRAC(B3,C3,D3)", 0.0); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/atp/TestYearFracCalculatorFromSpreadsheet.java b/src/testcases/org/apache/poi/hssf/record/formula/atp/TestYearFracCalculatorFromSpreadsheet.java index 2cad8e3620..37d1bb314b 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/atp/TestYearFracCalculatorFromSpreadsheet.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/atp/TestYearFracCalculatorFromSpreadsheet.java @@ -56,7 +56,7 @@ public final class TestYearFracCalculatorFromSpreadsheet extends TestCase { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("yearfracExamples.xls"); HSSFSheet sheet = wb.getSheetAt(0); - HSSFFormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator(wb); int nSuccess = 0; int nFailures = 0; int nUnexpectedErrors = 0; diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java index 2b09b2219f..3fb2ed8d86 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java @@ -35,9 +35,9 @@ public final class TestCircularReferences extends TestCase { /** * Translates StackOverflowError into AssertionFailedError */ - private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFSheet sheet, HSSFCell testCell) + private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFCell testCell) throws AssertionFailedError { - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); try { return evaluator.evaluate(testCell); } catch (StackOverflowError e) { @@ -75,7 +75,7 @@ public final class TestCircularReferences extends TestCase { // arguments before invoking operators, POI must handle such potential cycles gracefully. - CellValue cellValue = evaluateWithCycles(wb, sheet, testCell); + CellValue cellValue = evaluateWithCycles(wb, testCell); assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_NUMERIC); assertEquals(2, cellValue.getNumberValue(), 0); @@ -93,7 +93,7 @@ public final class TestCircularReferences extends TestCase { HSSFCell testCell = row.createCell(0); testCell.setCellFormula("A1"); - CellValue cellValue = evaluateWithCycles(wb, sheet, testCell); + CellValue cellValue = evaluateWithCycles(wb, testCell); confirmCycleErrorCode(cellValue); } @@ -113,7 +113,7 @@ public final class TestCircularReferences extends TestCase { HSSFCell testCell = row.createCell(3); testCell.setCellFormula("A1"); - CellValue cellValue = evaluateWithCycles(wb, sheet, testCell); + CellValue cellValue = evaluateWithCycles(wb, testCell); confirmCycleErrorCode(cellValue); } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java index 01aa5a36cc..27b62824df 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java @@ -65,7 +65,7 @@ public final class TestExternalFunction extends TestCase { String actualFormula=cell.getCellFormula(); assertEquals("myFunc()", actualFormula); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue evalResult = fe.evaluate(cell); // Check the return value from ExternalFunction.evaluate() diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java index 27ece94785..c5274e09d1 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java @@ -66,7 +66,7 @@ public final class TestFormulaBugs extends TestCase { .getCellFormula()); // We might as well evaluate the formula - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue cv = fe.evaluate(cell); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); @@ -111,7 +111,7 @@ public final class TestFormulaBugs extends TestCase { } // use POI's evaluator as an extra sanity check - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue cv; cv = fe.evaluate(cell); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); @@ -162,7 +162,7 @@ public final class TestFormulaBugs extends TestCase { double expectedResult = (4.0 * 8.0 + 5.0 * 9.0) / 10.0; - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue cv = fe.evaluate(cell); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java index af07b1d432..9f28c488cc 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java @@ -178,7 +178,7 @@ public final class TestFormulasFromSpreadsheet extends TestCase { */ private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) { - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(workbook); int rowIndex = startRowIndex; while (true) { diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java index 310fce68a6..ac19bf391d 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java @@ -67,7 +67,7 @@ public final class TestPercentEval extends TestCase { cell.setCellFormula("B1%"); row.createCell(1).setCellValue(50.0); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue cv; try { cv = fe.evaluate(cell); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java index 0892a0e298..2cf358ad33 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java @@ -268,7 +268,7 @@ public final class TestCountFuncs extends TestCase { int failureCount = 0; HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook(FILE_NAME); HSSFSheet sheet = wb.getSheetAt(0); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); int maxRow = sheet.getLastRowNum(); for (int rowIx=START_ROW_IX; rowIx 2 HSSFRow rowIDX = sheet.getRow(3); @@ -238,7 +238,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase { cell.setCellFormula("1=1"); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); try { fe.evaluateInCell(cell); } catch (NumberFormatException e) { @@ -257,7 +257,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase { int numSheets = wb.getNumberOfSheets(); for (int i = 0; i < numSheets; i++) { HSSFSheet s = wb.getSheetAt(i); - HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb); + HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(wb); for (Iterator rows = s.rowIterator(); rows.hasNext();) { HSSFRow r = (HSSFRow) rows.next(); @@ -276,7 +276,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase { HSSFRow row = sheet.createRow(1); HSSFCell cell = row.createCell(0); cell.setCellFormula("na()"); // this formula evaluates to an Excel error code '#N/A' - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); try { fe.evaluateInCell(cell); } catch (NumberFormatException e) { @@ -312,7 +312,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase { // Choose cell A9, so that the failing test case doesn't take too long to execute. HSSFCell cell = row.getCell(8); - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); evaluator.evaluate(cell); int evalCount = evaluator.getEvaluationCount(); // With caching, the evaluationCount is 8 which is a big improvement diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java index bed8869d54..d2c9d0753c 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java @@ -68,7 +68,7 @@ public final class TestFormulaEvaluatorDocs extends TestCase { // uses evaluateFormulaCell() for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) { HSSFSheet sheet = wb.getSheetAt(sheetNum); - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { HSSFRow r = (HSSFRow)rit.next(); @@ -103,7 +103,7 @@ public final class TestFormulaEvaluatorDocs extends TestCase { // uses evaluateInCell() for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) { HSSFSheet sheet = wb.getSheetAt(sheetNum); - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { HSSFRow r = (HSSFRow)rit.next(); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java index f1be47fd1b..e1a6e1b3ca 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java @@ -243,7 +243,7 @@ public final class TestHSSFDataFormatter extends TestCase { assertEquals("SUM(12.25,12.25)/100", formatter.formatCellValue(cell)); // now with a formula evaluator - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)"); assertEquals("24.50%", formatter.formatCellValue(cell,evaluator)); } @@ -257,7 +257,7 @@ public final class TestHSSFDataFormatter extends TestCase { Iterator it = row.cellIterator(); Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD"); formatter.setDefaultNumberFormat(defaultFormat); - double value = 10d; + log("\n==== DEFAULT NUMBER FORMAT ===="); while (it.hasNext()) { HSSFCell cell = (HSSFCell) it.next(); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java index d4f100cfc7..06213b762c 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java @@ -35,7 +35,7 @@ public final class TestHSSFFormulaEvaluator extends TestCase { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("testNames.xls"); HSSFSheet sheet = wb.getSheetAt(0); HSSFCell cell = sheet.getRow(8).getCell(0); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue cv = fe.evaluate(cell); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); assertEquals(3.72, cv.getNumberValue(), 0.0); @@ -67,7 +67,7 @@ public final class TestHSSFFormulaEvaluator extends TestCase { setValue(sheet, 3, 6, 100.0); - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); assertEquals(26.0, fe.evaluate(cell0).getNumberValue(), 0.0); assertEquals(56.0, fe.evaluate(cell1).getNumberValue(), 0.0); } -- 2.39.5