bug 59814: clear evaluation workbook and evaluation sheet caches. Patch from Greg Woolsey.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1751836 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
77da6237a4
commit
9539c626a9
@ -45,4 +45,8 @@ final class HSSFEvaluationSheet implements EvaluationSheet {
|
|||||||
}
|
}
|
||||||
return new HSSFEvaluationCell(cell, this);
|
return new HSSFEvaluationCell(cell, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,10 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
|||||||
_iBook = book.getWorkbook();
|
_iBook = book.getWorkbook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HSSFName createName() {
|
public HSSFName createName() {
|
||||||
return _uBook.createName();
|
return _uBook.createName();
|
||||||
|
@ -30,4 +30,12 @@ public interface EvaluationSheet {
|
|||||||
* @return <code>null</code> if there is no cell at the specified coordinates
|
* @return <code>null</code> if there is no cell at the specified coordinates
|
||||||
*/
|
*/
|
||||||
EvaluationCell getCell(int rowIndex, int columnIndex);
|
EvaluationCell getCell(int rowIndex, int columnIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propagated from {@link EvaluationWorkbook#clearAllCachedResultValues()} to clear locally cached data.
|
||||||
|
*
|
||||||
|
* @see WorkbookEvaluator#clearAllCachedResultValues()
|
||||||
|
* @see EvaluationWorkbook#clearAllCachedResultValues()
|
||||||
|
*/
|
||||||
|
public void clearAllCachedResultValues();
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,13 @@ public interface EvaluationWorkbook {
|
|||||||
Ptg[] getFormulaTokens(EvaluationCell cell);
|
Ptg[] getFormulaTokens(EvaluationCell cell);
|
||||||
UDFFinder getUDFFinder();
|
UDFFinder getUDFFinder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propagated from {@link WorkbookEvaluator#clearAllCachedResultValues()} to clear locally cached data.
|
||||||
|
* Implementations must call the same method on all referenced {@link EvaluationSheet} instances, as well as clearing local caches.
|
||||||
|
* @see WorkbookEvaluator#clearAllCachedResultValues()
|
||||||
|
*/
|
||||||
|
public void clearAllCachedResultValues();
|
||||||
|
|
||||||
class ExternalSheet {
|
class ExternalSheet {
|
||||||
private final String _workbookName;
|
private final String _workbookName;
|
||||||
private final String _sheetName;
|
private final String _sheetName;
|
||||||
|
@ -208,6 +208,7 @@ public final class WorkbookEvaluator {
|
|||||||
public void clearAllCachedResultValues() {
|
public void clearAllCachedResultValues() {
|
||||||
_cache.clear();
|
_cache.clear();
|
||||||
_sheetIndexesBySheet.clear();
|
_sheetIndexesBySheet.clear();
|
||||||
|
_workbook.clearAllCachedResultValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,6 +101,14 @@ final class ForkedEvaluationSheet implements EvaluationSheet {
|
|||||||
return mewb.getSheetIndex(_masterSheet);
|
return mewb.getSheetIndex(_masterSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* leave the map alone, if it needs resetting, reusing this class is probably a bad idea.
|
||||||
|
* @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues()
|
||||||
|
*/
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
_masterSheet.clearAllCachedResultValues();
|
||||||
|
}
|
||||||
|
|
||||||
private static final class RowColKey implements Comparable<RowColKey>{
|
private static final class RowColKey implements Comparable<RowColKey>{
|
||||||
private final int _rowIndex;
|
private final int _rowIndex;
|
||||||
private final int _columnIndex;
|
private final int _columnIndex;
|
||||||
|
@ -136,4 +136,12 @@ final class ForkedEvaluationWorkbook implements EvaluationWorkbook {
|
|||||||
public UDFFinder getUDFFinder(){
|
public UDFFinder getUDFFinder(){
|
||||||
return _masterBook.getUDFFinder();
|
return _masterBook.getUDFFinder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* leave the map alone, if it needs resetting, reusing this class is probably a bad idea.
|
||||||
|
* @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues()
|
||||||
|
*/
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
_masterBook.clearAllCachedResultValues();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,4 +47,8 @@ final class SXSSFEvaluationSheet implements EvaluationSheet {
|
|||||||
}
|
}
|
||||||
return new SXSSFEvaluationCell(cell, this);
|
return new SXSSFEvaluationCell(cell, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,10 @@ public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWork
|
|||||||
_uBook = book;
|
_uBook = book;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
_tableCache = null;
|
||||||
|
}
|
||||||
|
|
||||||
private int convertFromExternalSheetIndex(int externSheetIndex) {
|
private int convertFromExternalSheetIndex(int externSheetIndex) {
|
||||||
return externSheetIndex;
|
return externSheetIndex;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,10 @@ final class XSSFEvaluationSheet implements EvaluationSheet {
|
|||||||
return _xs;
|
return _xs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
_cellCache = null;
|
||||||
|
}
|
||||||
|
|
||||||
public EvaluationCell getCell(int rowIndex, int columnIndex) {
|
public EvaluationCell getCell(int rowIndex, int columnIndex) {
|
||||||
// cache for performance: ~30% speedup due to caching
|
// cache for performance: ~30% speedup due to caching
|
||||||
if (_cellCache == null) {
|
if (_cellCache == null) {
|
||||||
|
@ -40,6 +40,11 @@ public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
|
|||||||
super(book);
|
super(book);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearAllCachedResultValues() {
|
||||||
|
super.clearAllCachedResultValues();
|
||||||
|
_sheetCache = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSheetIndex(EvaluationSheet evalSheet) {
|
public int getSheetIndex(EvaluationSheet evalSheet) {
|
||||||
XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet();
|
XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet();
|
||||||
|
@ -18,17 +18,22 @@
|
|||||||
package org.apache.poi.ss.formula;
|
package org.apache.poi.ss.formula;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.CellType;
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
import org.apache.poi.ss.usermodel.CellValue;
|
import org.apache.poi.ss.usermodel.CellValue;
|
||||||
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Table;
|
import org.apache.poi.ss.usermodel.Table;
|
||||||
|
import org.apache.poi.ss.util.AreaReference;
|
||||||
|
import org.apache.poi.ss.util.CellReference;
|
||||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFTable;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -63,8 +68,40 @@ public class TestStructuredReferences {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
final FormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
|
final FormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
|
||||||
confirm(eval, wb.getSheet("Table").getRow(5).getCell(0), 49);
|
final XSSFSheet tableSheet = wb.getSheet("Table");
|
||||||
confirm(eval, wb.getSheet("Formulas").getRow(0).getCell(0), 209);
|
final XSSFSheet formulaSheet = wb.getSheet("Formulas");
|
||||||
|
|
||||||
|
confirm(eval, tableSheet.getRow(5).getCell(0), 49);
|
||||||
|
confirm(eval, formulaSheet.getRow(0).getCell(0), 209);
|
||||||
|
confirm(eval, formulaSheet.getRow(1).getCell(0), "one");
|
||||||
|
|
||||||
|
// test changing a table value, to see if the caches are properly cleared
|
||||||
|
// Issue 59814
|
||||||
|
|
||||||
|
// this test passes before the fix for 59814
|
||||||
|
tableSheet.getRow(1).getCell(1).setCellValue("ONEA");
|
||||||
|
confirm(eval, formulaSheet.getRow(1).getCell(0), "ONEA");
|
||||||
|
|
||||||
|
// test adding a row to a table, issue 59814
|
||||||
|
Row newRow = tableSheet.getRow(7);
|
||||||
|
if (newRow == null) newRow = tableSheet.createRow(7);
|
||||||
|
newRow.createCell(0, CellType.FORMULA).setCellFormula("\\_Prime.1[[#This Row],[@Number]]*\\_Prime.1[[#This Row],[@Number]]");
|
||||||
|
newRow.createCell(1, CellType.STRING).setCellValue("thirteen");
|
||||||
|
newRow.createCell(2, CellType.NUMERIC).setCellValue(13);
|
||||||
|
|
||||||
|
// update Table
|
||||||
|
final XSSFTable table = wb.getTable("\\_Prime.1");
|
||||||
|
final AreaReference newArea = new AreaReference(table.getStartCellReference(), new CellReference(table.getEndRowIndex() + 1, table.getEndColIndex()));
|
||||||
|
String newAreaStr = newArea.formatAsString();
|
||||||
|
table.getCTTable().setRef(newAreaStr);
|
||||||
|
table.getCTTable().getAutoFilter().setRef(newAreaStr);
|
||||||
|
table.updateHeaders();
|
||||||
|
table.updateReferences();
|
||||||
|
|
||||||
|
// these fail before the fix for 59814
|
||||||
|
confirm(eval, tableSheet.getRow(7).getCell(0), 13*13);
|
||||||
|
confirm(eval, formulaSheet.getRow(0).getCell(0), 209 + 13*13);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
wb.close();
|
wb.close();
|
||||||
}
|
}
|
||||||
@ -78,4 +115,13 @@ public class TestStructuredReferences {
|
|||||||
}
|
}
|
||||||
assertEquals(expectedResult, cv.getNumberValue(), 0.0);
|
assertEquals(expectedResult, cv.getNumberValue(), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void confirm(FormulaEvaluator fe, Cell cell, String expectedResult) {
|
||||||
|
fe.clearAllCachedResultValues();
|
||||||
|
CellValue cv = fe.evaluate(cell);
|
||||||
|
if (cv.getCellType() != CellType.STRING) {
|
||||||
|
fail("expected String cell type but got " + cv.formatAsString());
|
||||||
|
}
|
||||||
|
assertEquals(expectedResult, cv.getStringValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user