From 86746dde006c3b3ab5a1c8f58925030c9165dd10 Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Thu, 8 May 2008 00:52:05 +0000 Subject: [PATCH] 44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@654356 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 1 + src/documentation/content/xdocs/status.xml | 1 + .../hssf/record/formula/eval/Area2DEval.java | 80 +---------- .../hssf/record/formula/eval/Area3DEval.java | 86 ++---------- .../record/formula/eval/AreaEvalBase.java | 122 ++++++++++++++++ .../apache/poi/hssf/usermodel/HSSFCell.java | 3 +- .../hssf/usermodel/HSSFFormulaEvaluator.java | 3 +- .../formula/eval/AllFormulaEvalTests.java | 3 +- .../record/formula/eval/TestAreaEval.java | 62 ++++++++ .../formula/functions/TestCountFuncs.java | 7 +- .../record/formula/functions/TestIndex.java | 2 +- .../poi/hssf/usermodel/AllUserModelTests.java | 12 +- .../usermodel/TestFormulaEvaluatorBugs.java | 132 ++++++++++-------- 13 files changed, 292 insertions(+), 222 deletions(-) create mode 100644 src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java create mode 100644 src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index c711678b3..3f8aa68d7 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + 44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals 42570 - fixed LabelRecord to use empty string instead of null when the length is zero. 42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues. Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 63a6b12bf..75e8a30de 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals 42570 - fixed LabelRecord to use empty string instead of null when the length is zero. 42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues. Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java index 4b9a64c1c..5ae98b39f 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java @@ -22,79 +22,11 @@ import org.apache.poi.hssf.record.formula.Ptg; /** * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * + * */ -public final class Area2DEval implements AreaEval { -// TODO -refactor with Area3DEval - private final AreaPtg _delegate; +public final class Area2DEval extends AreaEvalBase { - private final ValueEval[] _values; - - public Area2DEval(Ptg ptg, ValueEval[] values) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - if(values == null) { - throw new IllegalArgumentException("values must not be null"); - } - for(int i=values.length-1; i>=0; i--) { - if(values[i] == null) { - throw new IllegalArgumentException("value array elements must not be null"); - } - } - // TODO - check size of array vs size of AreaPtg - _delegate = (AreaPtg) ptg; - _values = values; - } - - public int getFirstColumn() { - return _delegate.getFirstColumn(); - } - - public int getFirstRow() { - return _delegate.getFirstRow(); - } - - public int getLastColumn() { - return _delegate.getLastColumn(); - } - - public int getLastRow() { - return _delegate.getLastRow(); - } - - public ValueEval[] getValues() { - return _values; - } - - public ValueEval getValueAt(int row, int col) { - ValueEval retval; - int index = ((row-getFirstRow())*(getLastColumn()-getFirstColumn()+1))+(col-getFirstColumn()); - if (index <0 || index >= _values.length) - retval = ErrorEval.VALUE_INVALID; - else - retval = _values[index]; - return retval; - } - - public boolean contains(int row, int col) { - return (getFirstRow() <= row) && (getLastRow() >= row) - && (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean containsRow(int row) { - return (getFirstRow() <= row) && (getLastRow() >= row); - } - - public boolean containsColumn(short col) { - return (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean isColumn() { - return _delegate.getFirstColumn() == _delegate.getLastColumn(); - } - - public boolean isRow() { - return _delegate.getFirstRow() == _delegate.getLastRow(); - } -} + public Area2DEval(Ptg ptg, ValueEval[] values) { + super((AreaPtg) ptg, values); + } +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java index 2f539142d..89209e21b 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java @@ -22,84 +22,18 @@ import org.apache.poi.hssf.record.formula.Ptg; /** * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * + * */ -public final class Area3DEval implements AreaEval { - // TODO -refactor with Area3DEval - private final Area3DPtg _delegate; +public final class Area3DEval extends AreaEvalBase { - private final ValueEval[] _values; + private final int _externSheetIndex; - public Area3DEval(Ptg ptg, ValueEval[] values) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - if(values == null) { - throw new IllegalArgumentException("values must not be null"); - } - for(int i=values.length-1; i>=0; i--) { - if(values[i] == null) { - throw new IllegalArgumentException("value array elements must not be null"); - } - } - // TODO - check size of array vs size of AreaPtg - _values = values; - _delegate = (Area3DPtg) ptg; - } + public Area3DEval(Ptg ptg, ValueEval[] values) { + super((Area3DPtg) ptg, values); + _externSheetIndex = ((Area3DPtg) ptg).getExternSheetIndex(); + } - public int getFirstColumn() { - return _delegate.getFirstColumn(); - } - - public int getFirstRow() { - return _delegate.getFirstRow(); - } - - public int getLastColumn() { - return (short) _delegate.getLastColumn(); - } - - public int getLastRow() { - return _delegate.getLastRow(); - } - - public ValueEval[] getValues() { - return _values; - } - - public ValueEval getValueAt(int row, int col) { - ValueEval retval; - int index = (row-getFirstRow())*(col-getFirstColumn()); - if (index <0 || index >= _values.length) - retval = ErrorEval.VALUE_INVALID; - else - retval = _values[index]; - return retval; - } - - public boolean contains(int row, int col) { - return (getFirstRow() <= row) && (getLastRow() >= row) - && (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean containsRow(int row) { - return (getFirstRow() <= row) && (getLastRow() >= row); - } - - public boolean containsColumn(short col) { - return (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - - public boolean isColumn() { - return _delegate.getFirstColumn() == _delegate.getLastColumn(); - } - - public boolean isRow() { - return _delegate.getFirstRow() == _delegate.getLastRow(); - } - - public int getExternSheetIndex() { - return _delegate.getExternSheetIndex(); - } + public int getExternSheetIndex() { + return _externSheetIndex; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java new file mode 100644 index 000000000..9436ae0aa --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java @@ -0,0 +1,122 @@ +/* + * 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.eval; + +import org.apache.poi.hssf.record.formula.AreaI; + +/** + * @author Josh Micich + */ +abstract class AreaEvalBase implements AreaEval { + + private final int _firstColumn; + private final int _firstRow; + private final int _lastColumn; + private final int _lastRow; + private final ValueEval[] _values; + private final int _nColumns; + private final int _nRows; + + protected AreaEvalBase(AreaI ptg, ValueEval[] values) { + if (values == null) { + throw new IllegalArgumentException("values must not be null"); + } + _firstRow = ptg.getFirstRow(); + _firstColumn = ptg.getFirstColumn(); + _lastRow = ptg.getLastRow(); + _lastColumn = ptg.getLastColumn(); + + _nColumns = _lastColumn - _firstColumn + 1; + _nRows = _lastRow - _firstRow + 1; + + int expectedItemCount = _nRows * _nColumns; + if ((values.length != expectedItemCount)) { + // Note - this math may need alteration when POI starts to support full column or full row refs + throw new IllegalArgumentException("Array size should be (" + expectedItemCount + + ") but was (" + values.length + ")"); + } + + + + for (int i = values.length - 1; i >= 0; i--) { + if (values[i] == null) { + throw new IllegalArgumentException("value array elements must not be null"); + } + } + _values = values; + } + + public final int getFirstColumn() { + return _firstColumn; + } + + public final int getFirstRow() { + return _firstRow; + } + + public final int getLastColumn() { + return _lastColumn; + } + + public final int getLastRow() { + return _lastRow; + } + + public final ValueEval[] getValues() { + // TODO - clone() - but some junits rely on not cloning at the moment + return _values; + } + + public final ValueEval getValueAt(int row, int col) { + int rowOffsetIx = row - _firstRow; + int colOffsetIx = col - _firstColumn; + + if(rowOffsetIx < 0 || rowOffsetIx >= _nRows) { + throw new IllegalArgumentException("Specified row index (" + row + + ") is outside the allowed range (" + _firstRow + ".." + _lastRow + ")"); + } + if(colOffsetIx < 0 || colOffsetIx >= _nColumns) { + throw new IllegalArgumentException("Specified column index (" + col + + ") is outside the allowed range (" + _firstColumn + ".." + col + ")"); + } + + int index = rowOffsetIx * _nColumns + colOffsetIx; + return _values[index]; + } + + public final boolean contains(int row, int col) { + return _firstRow <= row && _lastRow >= row + && _firstColumn <= col && _lastColumn >= col; + } + + public final boolean containsRow(int row) { + return (_firstRow <= row) && (_lastRow >= row); + } + + public final boolean containsColumn(short col) { + return (_firstColumn <= col) && (_lastColumn >= col); + } + + public final boolean isColumn() { + return _firstColumn == _lastColumn; + } + + public final boolean isRow() { + return _firstRow == _lastRow; + } +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 81a338256..7d2a53d20 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -817,8 +817,7 @@ public class HSSFCell int row=record.getRow(); short col=record.getColumn(); short styleIndex=record.getXFIndex(); - if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA)) - { + if (cellType != CELL_TYPE_ERROR) { setCellType(CELL_TYPE_ERROR, false, row, col, styleIndex); } (( BoolErrRecord ) record).setValue(value); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index 0a9c3dfa8..cf4f83b31 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -232,8 +232,7 @@ public class HSSFFormulaEvaluator { cell.setCellValue(cv.getBooleanValue()); break; case HSSFCell.CELL_TYPE_ERROR: - cell.setCellType(HSSFCell.CELL_TYPE_ERROR); - cell.setCellValue(cv.getErrorValue()); + cell.setCellErrorValue(cv.getErrorValue()); break; case HSSFCell.CELL_TYPE_NUMERIC: cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java index 5098c789a..8887445ad 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java @@ -28,7 +28,8 @@ import junit.framework.TestSuite; public class AllFormulaEvalTests { public static Test suite() { - TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.eval"); + TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName()); + result.addTestSuite(TestAreaEval.class); result.addTestSuite(TestCircularReferences.class); result.addTestSuite(TestExternalFunction.class); result.addTestSuite(TestFormulaBugs.class); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java new file mode 100644 index 000000000..6c855707b --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java @@ -0,0 +1,62 @@ +/* ==================================================================== + 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.eval; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.Area3DPtg; + +/** + * Tests for AreaEval + * + * @author Josh Micich + */ +public final class TestAreaEval extends TestCase { + + public void testGetValue_bug44950() { + + Area3DPtg ptg = new Area3DPtg("B2:D3", (short)0); + NumberEval one = new NumberEval(1); + ValueEval[] values = { + one, + new NumberEval(2), + new NumberEval(3), + new NumberEval(4), + new NumberEval(5), + new NumberEval(6), + }; + AreaEval ae = new Area3DEval(ptg, values); + if (one == ae.getValueAt(1, 2)) { + throw new AssertionFailedError("Identified bug 44950 a"); + } + confirm(1, ae, 1, 1); + confirm(2, ae, 1, 2); + confirm(3, ae, 1, 3); + confirm(4, ae, 2, 1); + confirm(5, ae, 2, 2); + confirm(6, ae, 2, 3); + + } + + private static void confirm(int expectedValue, AreaEval ae, int row, int col) { + NumberEval v = (NumberEval) ae.getValueAt(row, col); + assertEquals(expectedValue, v.getNumberValue(), 0.0); + } + +} 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 ae93a2d41..6d11e5a53 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 @@ -67,7 +67,7 @@ public final class TestCountFuncs extends TestCase { args = new Eval[] { EvalFactory.createAreaEval("D1:F5", 3, 5), // 15 EvalFactory.createRefEval("A1"), - EvalFactory.createAreaEval("A1:F6", 7, 6), // 42 + EvalFactory.createAreaEval("A1:G6", 7, 6), // 42 new NumberEval(0), }; confirmCountA(59, args); @@ -87,7 +87,7 @@ public final class TestCountFuncs extends TestCase { BoolEval.TRUE, BlankEval.INSTANCE, }; - range = createAreaEval("A1:B2", values); + range = createAreaEval("A1:B3", values); confirmCountIf(2, range, BoolEval.TRUE); // when criteria is numeric @@ -98,9 +98,8 @@ public final class TestCountFuncs extends TestCase { new NumberEval(2), new NumberEval(2), BoolEval.TRUE, - BlankEval.INSTANCE, }; - range = createAreaEval("A1:B2", values); + range = createAreaEval("A1:B3", values); confirmCountIf(3, range, new NumberEval(2)); // note - same results when criteria is a string that parses as the number with the same value confirmCountIf(3, range, new StringEval("2.00")); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java index 902c4122e..ae9e5c239 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java @@ -44,7 +44,7 @@ public final class TestIndex extends TestCase { 7, 8, 9, 10, 11, 12, - 13, // excess array element. TODO - Area2DEval currently has no validation to ensure correct size of values array +// 13, // excess array element. TODO - Area2DEval currently has no validation to ensure correct size of values array }; /** diff --git a/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java b/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java index 47c2c481e..0e18e21e5 100755 --- a/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java @@ -38,10 +38,12 @@ public class AllUserModelTests { result.addTestSuite(TestEscherGraphics2d.class); result.addTestSuite(TestFontDetails.class); result.addTestSuite(TestFormulas.class); + result.addTestSuite(TestFormulaEvaluatorBugs.class); + result.addTestSuite(TestFormulaEvaluatorDocs.class); result.addTestSuite(TestHSSFCell.class); result.addTestSuite(TestHSSFClientAnchor.class); - result.addTestSuite(TestHSSFConditionalFormatting.class); result.addTestSuite(TestHSSFComment.class); + result.addTestSuite(TestHSSFConditionalFormatting.class); result.addTestSuite(TestHSSFDateUtil.class); result.addTestSuite(TestHSSFHeaderFooter.class); result.addTestSuite(TestHSSFHyperlink.class); @@ -54,17 +56,19 @@ public class AllUserModelTests { result.addTestSuite(TestHSSFSheet.class); result.addTestSuite(TestHSSFSheetOrder.class); result.addTestSuite(TestHSSFSheetSetOrder.class); + result.addTestSuite(TestHSSFTextbox.class); result.addTestSuite(TestHSSFWorkbook.class); result.addTestSuite(TestNamedRange.class); result.addTestSuite(TestOLE2Embeding.class); + result.addTestSuite(TestPOIFSProperties.class); result.addTestSuite(TestReadWriteChart.class); result.addTestSuite(TestSanityChecker.class); result.addTestSuite(TestSheetHiding.class); result.addTestSuite(TestSheetShiftRows.class); if (false) { // deliberately avoiding this one - result.addTestSuite(TestUnfixedBugs.class); - } - result.addTestSuite(TestUnicodeWorkbook.class); + result.addTestSuite(TestUnfixedBugs.class); + } + result.addTestSuite(TestUnicodeWorkbook.class); result.addTestSuite(TestUppercaseWorkbook.class); result.addTestSuite(TestWorkbook.class); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java index 0ef642917..349cfa8a8 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java @@ -22,12 +22,14 @@ import java.io.FileOutputStream; import java.util.Iterator; import java.util.List; +import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.formula.AreaPtg; import org.apache.poi.hssf.record.formula.FuncVarPtg; + /** * */ @@ -51,42 +53,41 @@ public final class TestFormulaEvaluatorBugs extends TestCase { */ public void test44636() throws Exception { // Open the existing file, tweak one value and - // re-calculate + // re-calculate HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44636.xls"); - HSSFSheet sheet = wb.getSheetAt (0); - HSSFRow row = sheet.getRow (0); + HSSFSheet sheet = wb.getSheetAt(0); + HSSFRow row = sheet.getRow(0); - row.getCell((short)0).setCellValue(4.2); - row.getCell((short)2).setCellValue(25); + row.getCell((short) 0).setCellValue(4.2); + row.getCell((short) 2).setCellValue(25); HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - assertEquals(4.2*25, row.getCell((short)3).getNumericCellValue(), 0.0001); + assertEquals(4.2 * 25, row.getCell((short) 3).getNumericCellValue(), 0.0001); // Save - File existing = new File(tmpDirName,"44636-existing.xls"); + File existing = new File(tmpDirName, "44636-existing.xls"); FileOutputStream out = new FileOutputStream(existing); wb.write(out); out.close(); System.err.println("Existing file for bug #44636 written to " + existing.toString()); - // Now, do a new file from scratch wb = new HSSFWorkbook(); sheet = wb.createSheet(); row = sheet.createRow(0); - row.createCell((short)0).setCellValue(1.2); - row.createCell((short)1).setCellValue(4.2); + row.createCell((short) 0).setCellValue(1.2); + row.createCell((short) 1).setCellValue(4.2); row = sheet.createRow(1); - row.createCell((short)0).setCellFormula("SUM(A1:B1)"); + row.createCell((short) 0).setCellFormula("SUM(A1:B1)"); HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - assertEquals(5.4, row.getCell((short)0).getNumericCellValue(), 0.0001); + assertEquals(5.4, row.getCell((short) 0).getNumericCellValue(), 0.0001); // Save - File scratch = new File(tmpDirName,"44636-scratch.xls"); + File scratch = new File(tmpDirName, "44636-scratch.xls"); out = new FileOutputStream(scratch); wb.write(out); out.close(); @@ -105,62 +106,62 @@ public final class TestFormulaEvaluatorBugs extends TestCase { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44297.xls"); HSSFRow row; - HSSFCell cell; + HSSFCell cell; - HSSFSheet sheet = wb.getSheetAt(0); + HSSFSheet sheet = wb.getSheetAt(0); HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); row = sheet.getRow(0); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("31+46", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(77, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(1); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("30+53", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(83, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(2); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("SUM(A1:A2)", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(160, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(4); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("32767+32768", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(7); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("32744+42333", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(8); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("327680.0/32768", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(10, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(9); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("32767+32769", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(10); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("35000+36000", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(11); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("-1000000.0-3000000.0", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0); @@ -176,30 +177,29 @@ public final class TestFormulaEvaluatorBugs extends TestCase { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SingleLetterRanges.xls"); - HSSFSheet sheet = wb.getSheetAt(0); + HSSFSheet sheet = wb.getSheetAt(0); HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); - // =index(C:C,2,1) -> 2 + // =index(C:C,2,1) -> 2 HSSFRow rowIDX = sheet.getRow(3); - // =sum(C:C) -> 6 + // =sum(C:C) -> 6 HSSFRow rowSUM = sheet.getRow(4); - // =sum(C:D) -> 66 + // =sum(C:D) -> 66 HSSFRow rowSUM2D = sheet.getRow(5); // Test the sum - HSSFCell cellSUM = rowSUM.getCell((short)0); + HSSFCell cellSUM = rowSUM.getCell((short) 0); - FormulaRecordAggregate frec = - (FormulaRecordAggregate)cellSUM.getCellValueRecord(); + FormulaRecordAggregate frec = (FormulaRecordAggregate) cellSUM.getCellValueRecord(); List ops = frec.getFormulaRecord().getParsedExpression(); assertEquals(2, ops.size()); assertEquals(AreaPtg.class, ops.get(0).getClass()); assertEquals(FuncVarPtg.class, ops.get(1).getClass()); - // Actually stored as C1 to C65536 - // (last row is -1 === 65535) - AreaPtg ptg = (AreaPtg)ops.get(0); + // Actually stored as C1 to C65536 + // (last row is -1 === 65535) + AreaPtg ptg = (AreaPtg) ops.get(0); assertEquals(2, ptg.getFirstColumn()); assertEquals(2, ptg.getLastColumn()); assertEquals(0, ptg.getFirstRow()); @@ -207,26 +207,25 @@ public final class TestFormulaEvaluatorBugs extends TestCase { assertEquals("C:C", ptg.toFormulaString(wb)); // Will show as C:C, but won't know how many - // rows it covers as we don't have the sheet - // to hand when turning the Ptgs into a string + // rows it covers as we don't have the sheet + // to hand when turning the Ptgs into a string assertEquals("SUM(C:C)", cellSUM.getCellFormula()); eva.setCurrentRow(rowSUM); // But the evaluator knows the sheet, so it - // can do it properly + // can do it properly assertEquals(6, eva.evaluate(cellSUM).getNumberValue(), 0); - // Test the index // Again, the formula string will be right but - // lacking row count, evaluated will be right - HSSFCell cellIDX = rowIDX.getCell((short)0); + // lacking row count, evaluated will be right + HSSFCell cellIDX = rowIDX.getCell((short) 0); assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula()); eva.setCurrentRow(rowIDX); assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0); // Across two colums - HSSFCell cellSUM2D = rowSUM2D.getCell((short)0); + HSSFCell cellSUM2D = rowSUM2D.getCell((short) 0); assertEquals("SUM(C:D)", cellSUM2D.getCellFormula()); eva.setCurrentRow(rowSUM2D); assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0); @@ -240,7 +239,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase { HSSFSheet sheet = wb.createSheet(); wb.setSheetName(0, "Sheet1"); HSSFRow row = sheet.createRow(0); - HSSFCell cell = row.createCell((short)0); + HSSFCell cell = row.createCell((short) 0); cell.setCellFormula("1=1"); @@ -253,29 +252,46 @@ public final class TestFormulaEvaluatorBugs extends TestCase { } assertEquals(true, cell.getBooleanCellValue()); } - + public void testClassCast_bug44861() throws Exception { - HSSFWorkbook wb = HSSFTestDataSamples. - openSampleWorkbook("44861.xls"); - + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44861.xls"); + // Check direct HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - + // And via calls int numSheets = wb.getNumberOfSheets(); - for(int i=0; i