Minor improvements to error handling in ForkedEvaluator. Added junits.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@820479 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c2d66a280f
commit
a6ced5bc25
@ -27,6 +27,7 @@ import org.apache.poi.ss.formula.EvaluationWorkbook;
|
|||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.util.CellReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a sheet being used for forked evaluation. Initially, objects of this class contain
|
* Represents a sheet being used for forked evaluation. Initially, objects of this class contain
|
||||||
@ -65,6 +66,11 @@ final class ForkedEvaluationSheet implements EvaluationSheet {
|
|||||||
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
|
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex);
|
EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex);
|
||||||
|
if (mcell == null) {
|
||||||
|
CellReference cr = new CellReference(rowIndex, columnIndex);
|
||||||
|
throw new UnsupportedOperationException("Underlying cell '"
|
||||||
|
+ cr.formatAsString() + "' is missing in master sheet.");
|
||||||
|
}
|
||||||
result = new ForkedEvaluationCell(this, mcell);
|
result = new ForkedEvaluationCell(this, mcell);
|
||||||
_sharedCellsByRowCol.put(key, result);
|
_sharedCellsByRowCol.put(key, result);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package org.apache.poi.ss.formula;
|
package org.apache.poi.ss.formula;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.formula.eval.forked.TestForkedEvaluator;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
/**
|
/**
|
||||||
@ -30,6 +32,7 @@ public final class AllSSFormulaTests {
|
|||||||
result.addTestSuite(TestCellCacheEntry.class);
|
result.addTestSuite(TestCellCacheEntry.class);
|
||||||
result.addTestSuite(TestEvaluationCache.class);
|
result.addTestSuite(TestEvaluationCache.class);
|
||||||
result.addTestSuite(TestWorkbookEvaluator.class);
|
result.addTestSuite(TestWorkbookEvaluator.class);
|
||||||
|
result.addTestSuite(TestForkedEvaluator.class);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,118 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.ss.formula.eval.forked;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.ss.formula.IStabilityClassifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Josh Micich
|
||||||
|
*/
|
||||||
|
public final class TestForkedEvaluator extends TestCase {
|
||||||
|
/**
|
||||||
|
* set up a calculation workbook with input cells nicely segregated on a
|
||||||
|
* sheet called "Inputs"
|
||||||
|
*/
|
||||||
|
private static HSSFWorkbook createWorkbook() {
|
||||||
|
HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
|
HSSFSheet sheet1 = wb.createSheet("Inputs");
|
||||||
|
HSSFSheet sheet2 = wb.createSheet("Calculations");
|
||||||
|
HSSFRow row;
|
||||||
|
row = sheet2.createRow(0);
|
||||||
|
row.createCell(0).setCellFormula("B1*Inputs!A1-Inputs!B1");
|
||||||
|
row.createCell(1).setCellValue(5.0); // Calculations!B1
|
||||||
|
|
||||||
|
// some default input values
|
||||||
|
row = sheet1.createRow(0);
|
||||||
|
row.createCell(0).setCellValue(2.0); // Inputs!A1
|
||||||
|
row.createCell(1).setCellValue(3.0); // Inputs!B1
|
||||||
|
return wb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a basic use-case for {@link ForkedEvaluator}
|
||||||
|
*/
|
||||||
|
public void testBasic() {
|
||||||
|
HSSFWorkbook wb = createWorkbook();
|
||||||
|
|
||||||
|
// The stability classifier is useful to reduce memory consumption of caching logic
|
||||||
|
IStabilityClassifier stabilityClassifier = new IStabilityClassifier() {
|
||||||
|
public boolean isCellFinal(int sheetIndex, int rowIndex, int columnIndex) {
|
||||||
|
return sheetIndex == 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ForkedEvaluator fe1 = ForkedEvaluator.create(wb, stabilityClassifier, null);
|
||||||
|
ForkedEvaluator fe2 = ForkedEvaluator.create(wb, stabilityClassifier, null);
|
||||||
|
|
||||||
|
// fe1 and fe2 can be used concurrently on separate threads
|
||||||
|
|
||||||
|
fe1.updateCell("Inputs", 0, 0, new NumberEval(4.0));
|
||||||
|
fe1.updateCell("Inputs", 0, 1, new NumberEval(1.1));
|
||||||
|
|
||||||
|
fe2.updateCell("Inputs", 0, 0, new NumberEval(1.2));
|
||||||
|
fe2.updateCell("Inputs", 0, 1, new NumberEval(2.0));
|
||||||
|
|
||||||
|
assertEquals(18.9, ((NumberEval) fe1.evaluate("Calculations", 0, 0)).getNumberValue(), 0.0);
|
||||||
|
assertEquals(4.0, ((NumberEval) fe2.evaluate("Calculations", 0, 0)).getNumberValue(), 0.0);
|
||||||
|
fe1.updateCell("Inputs", 0, 0, new NumberEval(3.0));
|
||||||
|
assertEquals(13.9, ((NumberEval) fe1.evaluate("Calculations", 0, 0)).getNumberValue(), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As of Sep 2009, the Forked evaluator can update values from existing cells (this is because
|
||||||
|
* the underlying 'master' cell is used as a key into the calculation cache. Prior to the fix
|
||||||
|
* for this bug, an attempt to update a missing cell would result in NPE. This junit tests for
|
||||||
|
* a more meaningful error message.<br/>
|
||||||
|
*
|
||||||
|
* An alternate solution might involve allowing empty cells to be created as necessary. That
|
||||||
|
* was considered less desirable because so far, the underlying 'master' workbook is strictly
|
||||||
|
* <i>read-only</i> with respect to the ForkedEvaluator.
|
||||||
|
*/
|
||||||
|
public void testMissingInputCell() {
|
||||||
|
HSSFWorkbook wb = createWorkbook();
|
||||||
|
|
||||||
|
ForkedEvaluator fe = ForkedEvaluator.create(wb, null, null);
|
||||||
|
|
||||||
|
// attempt update input at cell A2 (which is missing)
|
||||||
|
try {
|
||||||
|
fe.updateCell("Inputs", 1, 0, new NumberEval(4.0));
|
||||||
|
throw new AssertionFailedError(
|
||||||
|
"Expected exception to be thrown due to missing input cell");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
StackTraceElement[] stes = e.getStackTrace();
|
||||||
|
if (stes[0].getMethodName().equals("getIdentityKey")) {
|
||||||
|
throw new AssertionFailedError("Identified bug with update of missing input cell");
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
if (e.getMessage().equals(
|
||||||
|
"Underlying cell 'A2' is missing in master sheet.")) {
|
||||||
|
// expected during successful test
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user