bugzilla 52575: added an option to ignore missing workbook references in formula evaluator
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1240903 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0efe45cb7d
commit
2e2559d80a
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.8-beta6" date="2012-??-??">
|
<release version="3.8-beta6" date="2012-??-??">
|
||||||
|
<action dev="poi-developers" type="add">52575 - added an option to ignore missing workbook references in formula evaluator</action>
|
||||||
<action dev="poi-developers" type="add">Validate address of hyperlinks in XSSF</action>
|
<action dev="poi-developers" type="add">Validate address of hyperlinks in XSSF</action>
|
||||||
<action dev="poi-developers" type="fix">52540 - Relax the M4.1 constraint on reading OOXML files, as some Office produced ones do have 2 Core Properties, despite the specification explicitly forbidding this</action>
|
<action dev="poi-developers" type="fix">52540 - Relax the M4.1 constraint on reading OOXML files, as some Office produced ones do have 2 Core Properties, despite the specification explicitly forbidding this</action>
|
||||||
<action dev="poi-developers" type="add">52462 - Added implementation for SUMIFS()</action>
|
<action dev="poi-developers" type="add">52462 - Added implementation for SUMIFS()</action>
|
||||||
|
@ -69,4 +69,7 @@ final class HSSFEvaluationCell implements EvaluationCell {
|
|||||||
public String getStringCellValue() {
|
public String getStringCellValue() {
|
||||||
return _cell.getRichStringCellValue().getString();
|
return _cell.getRichStringCellValue().getString();
|
||||||
}
|
}
|
||||||
|
public int getCachedFormulaResultType() {
|
||||||
|
return _cell.getCachedFormulaResultType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,4 +41,6 @@ public interface EvaluationCell {
|
|||||||
String getStringCellValue();
|
String getStringCellValue();
|
||||||
boolean getBooleanCellValue();
|
boolean getBooleanCellValue();
|
||||||
int getErrorCellValue();
|
int getErrorCellValue();
|
||||||
|
|
||||||
|
int getCachedFormulaResultType();
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ public final class OperationEvaluationContext {
|
|||||||
try {
|
try {
|
||||||
targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
|
targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
|
||||||
} catch (WorkbookNotFoundException e) {
|
} catch (WorkbookNotFoundException e) {
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
otherSheetIndex = targetEvaluator.getSheetIndex(externalSheet.getSheetName());
|
otherSheetIndex = targetEvaluator.getSheetIndex(externalSheet.getSheetName());
|
||||||
if (otherSheetIndex < 0) {
|
if (otherSheetIndex < 0) {
|
||||||
|
@ -67,6 +67,8 @@ import org.apache.poi.ss.util.CellReference;
|
|||||||
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
|
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
|
||||||
import org.apache.poi.ss.formula.eval.NotImplementedException;
|
import org.apache.poi.ss.formula.eval.NotImplementedException;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates formula cells.<p/>
|
* Evaluates formula cells.<p/>
|
||||||
@ -81,6 +83,14 @@ import org.apache.poi.ss.usermodel.Cell;
|
|||||||
*/
|
*/
|
||||||
public final class WorkbookEvaluator {
|
public final class WorkbookEvaluator {
|
||||||
|
|
||||||
|
private static final POILogger LOG = POILogFactory.getLogger(WorkbookEvaluator.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to use cached formula results if external workbook references in a formula is not available.
|
||||||
|
* See Bugzilla 52575 for details.
|
||||||
|
*/
|
||||||
|
private static final String IGNORE_MISSING_WORKBOOKS = WorkbookEvaluator.class.getName() + ".IGNORE_MISSING_WORKBOOKS";
|
||||||
|
|
||||||
private final EvaluationWorkbook _workbook;
|
private final EvaluationWorkbook _workbook;
|
||||||
private EvaluationCache _cache;
|
private EvaluationCache _cache;
|
||||||
/** part of cache entry key (useful when evaluating multiple workbooks) */
|
/** part of cache entry key (useful when evaluating multiple workbooks) */
|
||||||
@ -144,11 +154,19 @@ public final class WorkbookEvaluator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isDebugLogEnabled() {
|
private static boolean isDebugLogEnabled() {
|
||||||
return false;
|
return LOG.check(POILogger.DEBUG);
|
||||||
|
}
|
||||||
|
private static boolean isInfoLogEnabled() {
|
||||||
|
return LOG.check(POILogger.INFO);
|
||||||
}
|
}
|
||||||
private static void logDebug(String s) {
|
private static void logDebug(String s) {
|
||||||
if (isDebugLogEnabled()) {
|
if (isDebugLogEnabled()) {
|
||||||
System.out.println(s);
|
LOG.log(POILogger.DEBUG, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void logInfo(String s) {
|
||||||
|
if (isInfoLogEnabled()) {
|
||||||
|
LOG.log(POILogger.INFO, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* package */ void attachToEnvironment(CollaboratingWorkbooksEnvironment collaboratingWorkbooksEnvironment, EvaluationCache cache, int workbookIx) {
|
/* package */ void attachToEnvironment(CollaboratingWorkbooksEnvironment collaboratingWorkbooksEnvironment, EvaluationCache cache, int workbookIx) {
|
||||||
@ -288,8 +306,37 @@ public final class WorkbookEvaluator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tracker.updateCacheResult(result);
|
tracker.updateCacheResult(result);
|
||||||
} catch (NotImplementedException e) {
|
}
|
||||||
|
catch (NotImplementedException e) {
|
||||||
throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
|
throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
if (re.getCause() instanceof WorkbookNotFoundException
|
||||||
|
//To be replaced by configuration infrastructure
|
||||||
|
&& Boolean.valueOf(System.getProperty(IGNORE_MISSING_WORKBOOKS))) {
|
||||||
|
logInfo(re.getCause().getMessage() + " - Continuing with cached value!");
|
||||||
|
switch(srcCell.getCachedFormulaResultType()) {
|
||||||
|
case Cell.CELL_TYPE_NUMERIC:
|
||||||
|
result = new NumberEval(srcCell.getNumericCellValue());
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_STRING:
|
||||||
|
result = new StringEval(srcCell.getStringCellValue());
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_BLANK:
|
||||||
|
result = BlankEval.instance;
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_BOOLEAN:
|
||||||
|
result = BoolEval.valueOf(srcCell.getBooleanCellValue());
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_ERROR:
|
||||||
|
result = ErrorEval.valueOf(srcCell.getErrorCellValue());
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_FORMULA:
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unexpected cell type '" + srcCell.getCellType()+"' found!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw re;
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
tracker.endEvaluate(cce);
|
tracker.endEvaluate(cce);
|
||||||
}
|
}
|
||||||
|
@ -128,4 +128,8 @@ final class ForkedEvaluationCell implements EvaluationCell {
|
|||||||
public int getColumnIndex() {
|
public int getColumnIndex() {
|
||||||
return _masterCell.getColumnIndex();
|
return _masterCell.getColumnIndex();
|
||||||
}
|
}
|
||||||
|
public int getCachedFormulaResultType() {
|
||||||
|
return _masterCell.getCachedFormulaResultType();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -72,4 +72,7 @@ final class XSSFEvaluationCell implements EvaluationCell {
|
|||||||
public String getStringCellValue() {
|
public String getStringCellValue() {
|
||||||
return _cell.getRichStringCellValue().getString();
|
return _cell.getRichStringCellValue().getString();
|
||||||
}
|
}
|
||||||
|
public int getCachedFormulaResultType() {
|
||||||
|
return _cell.getCachedFormulaResultType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
113
src/testcases/org/apache/poi/ss/formula/TestMissingWorkbook.java
Normal file
113
src/testcases/org/apache/poi/ss/formula/TestMissingWorkbook.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
|
import org.apache.poi.hssf.usermodel.*;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class TestMissingWorkbook extends TestCase {
|
||||||
|
private static final String MAIN_WORKBOOK_FILENAME = "52575_main.xls";
|
||||||
|
private static final String SOURCE_DUMMY_WORKBOOK_FILENAME = "source_dummy.xls";
|
||||||
|
private static final String SOURCE_WORKBOOK_FILENAME = "52575_source.xls";
|
||||||
|
|
||||||
|
private static final String propertyKey = WorkbookEvaluator.class.getName() + ".IGNORE_MISSING_WORKBOOKS";
|
||||||
|
|
||||||
|
private HSSFWorkbook mainWorkbook;
|
||||||
|
private HSSFWorkbook sourceWorkbook;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
mainWorkbook = HSSFTestDataSamples.openSampleWorkbook(MAIN_WORKBOOK_FILENAME);
|
||||||
|
sourceWorkbook = HSSFTestDataSamples.openSampleWorkbook(SOURCE_WORKBOOK_FILENAME);
|
||||||
|
|
||||||
|
assertNotNull(mainWorkbook);
|
||||||
|
assertNotNull(sourceWorkbook);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMissingWorkbookMissing() throws IOException {
|
||||||
|
FormulaEvaluator evaluator = mainWorkbook.getCreationHelper().createFormulaEvaluator();
|
||||||
|
|
||||||
|
HSSFSheet lSheet = mainWorkbook.getSheetAt(0);
|
||||||
|
HSSFRow lARow = lSheet.getRow(0);
|
||||||
|
HSSFCell lA1Cell = lARow.getCell(0);
|
||||||
|
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, lA1Cell.getCellType());
|
||||||
|
try {
|
||||||
|
evaluator.evaluateFormulaCell(lA1Cell);
|
||||||
|
fail("Missing external workbook reference exception expected!");
|
||||||
|
}catch(RuntimeException re) {
|
||||||
|
assertTrue("Unexpected exception: " + re, re.getMessage().indexOf(SOURCE_DUMMY_WORKBOOK_FILENAME) != -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMissingWorkbookMissingOverride() throws IOException {
|
||||||
|
HSSFSheet lSheet = mainWorkbook.getSheetAt(0);
|
||||||
|
HSSFCell lA1Cell = lSheet.getRow(0).getCell(0);
|
||||||
|
HSSFCell lB1Cell = lSheet.getRow(1).getCell(0);
|
||||||
|
HSSFCell lC1Cell = lSheet.getRow(2).getCell(0);
|
||||||
|
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, lA1Cell.getCellType());
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, lB1Cell.getCellType());
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, lC1Cell.getCellType());
|
||||||
|
|
||||||
|
FormulaEvaluator evaluator = mainWorkbook.getCreationHelper().createFormulaEvaluator();
|
||||||
|
|
||||||
|
System.setProperty(propertyKey, Boolean.toString(true));
|
||||||
|
assertEquals(Cell.CELL_TYPE_NUMERIC, evaluator.evaluateFormulaCell(lA1Cell));
|
||||||
|
assertEquals(Cell.CELL_TYPE_STRING, evaluator.evaluateFormulaCell(lB1Cell));
|
||||||
|
assertEquals(Cell.CELL_TYPE_BOOLEAN, evaluator.evaluateFormulaCell(lC1Cell));
|
||||||
|
|
||||||
|
assertEquals(10.0d, lA1Cell.getNumericCellValue(), 0.00001d);
|
||||||
|
assertEquals("POI rocks!", lB1Cell.getStringCellValue());
|
||||||
|
assertEquals(true, lC1Cell.getBooleanCellValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testExistingWorkbook() throws IOException {
|
||||||
|
HSSFSheet lSheet = mainWorkbook.getSheetAt(0);
|
||||||
|
HSSFCell lA1Cell = lSheet.getRow(0).getCell(0);
|
||||||
|
HSSFCell lB1Cell = lSheet.getRow(1).getCell(0);
|
||||||
|
HSSFCell lC1Cell = lSheet.getRow(2).getCell(0);
|
||||||
|
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, lA1Cell.getCellType());
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, lB1Cell.getCellType());
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, lC1Cell.getCellType());
|
||||||
|
|
||||||
|
HSSFFormulaEvaluator lMainWorkbookEvaluator = new HSSFFormulaEvaluator(mainWorkbook);
|
||||||
|
HSSFFormulaEvaluator lSourceEvaluator = new HSSFFormulaEvaluator(sourceWorkbook);
|
||||||
|
HSSFFormulaEvaluator.setupEnvironment(
|
||||||
|
new String[]{MAIN_WORKBOOK_FILENAME, SOURCE_DUMMY_WORKBOOK_FILENAME},
|
||||||
|
new HSSFFormulaEvaluator[] {lMainWorkbookEvaluator, lSourceEvaluator});
|
||||||
|
|
||||||
|
assertEquals(Cell.CELL_TYPE_NUMERIC, lMainWorkbookEvaluator.evaluateFormulaCell(lA1Cell));
|
||||||
|
assertEquals(Cell.CELL_TYPE_STRING, lMainWorkbookEvaluator.evaluateFormulaCell(lB1Cell));
|
||||||
|
assertEquals(Cell.CELL_TYPE_BOOLEAN, lMainWorkbookEvaluator.evaluateFormulaCell(lC1Cell));
|
||||||
|
|
||||||
|
assertEquals(20.0d, lA1Cell.getNumericCellValue(), 0.00001d);
|
||||||
|
assertEquals("Apache rocks!", lB1Cell.getStringCellValue());
|
||||||
|
assertEquals(false, lC1Cell.getBooleanCellValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
test-data/spreadsheet/52575_main.xls
Normal file
BIN
test-data/spreadsheet/52575_main.xls
Normal file
Binary file not shown.
BIN
test-data/spreadsheet/52575_source.xls
Normal file
BIN
test-data/spreadsheet/52575_source.xls
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user