Generalise the CollaboratingWorkbooksEnvironment setup, so that XSSF can use it too

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1612254 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-07-21 12:23:54 +00:00
parent 5dfd7ea48c
commit 70f40542fd
7 changed files with 131 additions and 10 deletions

View File

@ -17,9 +17,12 @@
package org.apache.poi.hssf.usermodel;
import java.util.Map;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
import org.apache.poi.ss.formula.IStabilityClassifier;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.WorkbookEvaluatorProvider;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumericValueEval;
@ -40,7 +43,7 @@ import org.apache.poi.ss.usermodel.Workbook;
* cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between
* calls to evaluate~ methods on this class.
*/
public class HSSFFormulaEvaluator implements FormulaEvaluator {
public class HSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider {
private WorkbookEvaluator _bookEvaluator;
private HSSFWorkbook _book;
@ -101,7 +104,15 @@ public class HSSFFormulaEvaluator implements FormulaEvaluator {
CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
}
/**
public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> evaluators) {
CollaboratingWorkbooksEnvironment.setupFormulaEvaluator(evaluators);
}
public WorkbookEvaluator _getWorkbookEvaluator() {
return _bookEvaluator;
}
/**
* Does nothing
* @deprecated (Aug 2008) - not needed, since the current row can be derived from the cell
*/

View File

@ -24,6 +24,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.util.Internal;
/**
@ -73,6 +74,19 @@ public final class CollaboratingWorkbooksEnvironment {
evaluatorsByName.values().toArray(new WorkbookEvaluator[evaluatorsByName.size()]);
new CollaboratingWorkbooksEnvironment(evaluatorsByName, evaluators);
}
public static void setupFormulaEvaluator(Map<String,FormulaEvaluator> evaluators) {
Map<String, WorkbookEvaluator> evaluatorsByName = new HashMap<String, WorkbookEvaluator>(evaluators.size());
for (String wbName : evaluators.keySet()) {
FormulaEvaluator eval = evaluators.get(wbName);
if (eval instanceof WorkbookEvaluatorProvider) {
evaluatorsByName.put(wbName, ((WorkbookEvaluatorProvider)eval)._getWorkbookEvaluator());
} else {
throw new IllegalArgumentException("Formula Evaluator " + eval +
" provides no WorkbookEvaluator access");
}
}
setup(evaluatorsByName);
}
private CollaboratingWorkbooksEnvironment(String[] workbookNames, WorkbookEvaluator[] evaluators, int nItems) {
this(toUniqueMap(workbookNames, evaluators, nItems), evaluators);

View File

@ -0,0 +1,34 @@
/* ====================================================================
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 org.apache.poi.util.Internal;
/**
* Provides access to a {@link WorkbookEvaluator}, eg for use with
* {@link CollaboratingWorkbooksEnvironment}
*
* <p>For POI internal use only
*/
@Internal
public interface WorkbookEvaluatorProvider {
/**
* Provide the underlying WorkbookEvaluator
*/
WorkbookEvaluator _getWorkbookEvaluator();
}

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.usermodel;
import java.util.Map;
/**
* Evaluates formula cells.<p/>
*
@ -114,6 +116,16 @@ public interface FormulaEvaluator {
* @param cell
*/
Cell evaluateInCell(Cell cell);
/**
* Sets up the Formula Evaluator to be able to reference and resolve
* links to other workbooks, eg [Test.xls]Sheet1!A1.
* <p>For a workbook referenced as [Test.xls]Sheet1!A1, you should
* supply a map containing the key Test.xls (no square brackets),
* and an open FormulaEvaluator onto that Workbook.
* @param otherWorkbooks Map of workbook names (no square brackets) to an evaluator on that workbook
*/
void setupReferencedWorkbooks(Map<String,FormulaEvaluator> workbooks);
/**
* Perform detailed output of formula evaluation for next evaluation only?
@ -124,5 +136,4 @@ public interface FormulaEvaluator {
* @param value whether to perform detailed output
*/
void setDebugEvaluationOutputForNextEval(boolean value);
}

View File

@ -17,13 +17,23 @@
package org.apache.poi.ss.util;
import org.apache.poi.ss.usermodel.*;
import java.text.AttributedString;
import java.awt.font.TextLayout;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.text.AttributedString;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
/**
@ -61,6 +71,7 @@ public class SheetUtil {
public void notifyUpdateCell(Cell cell) {}
public CellValue evaluate(Cell cell) {return null; }
public Cell evaluateInCell(Cell cell) { return null; }
public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> workbooks) {}
public void setDebugEvaluationOutputForNextEval(boolean value) {}
public void evaluateAll() {}

View File

@ -17,9 +17,13 @@
package org.apache.poi.xssf.usermodel;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
import org.apache.poi.ss.formula.IStabilityClassifier;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.WorkbookEvaluatorProvider;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumberEval;
@ -41,7 +45,7 @@ import org.apache.poi.ss.usermodel.Workbook;
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* @author Josh Micich
*/
public class XSSFFormulaEvaluator implements FormulaEvaluator {
public class XSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider {
private WorkbookEvaluator _bookEvaluator;
private XSSFWorkbook _book;
@ -280,6 +284,14 @@ public class XSSFFormulaEvaluator implements FormulaEvaluator {
throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
}
public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> evaluators) {
CollaboratingWorkbooksEnvironment.setupFormulaEvaluator(evaluators);
}
public WorkbookEvaluator _getWorkbookEvaluator() {
return _bookEvaluator;
}
/** {@inheritDoc} */
public void setDebugEvaluationOutputForNextEval(boolean value){
_bookEvaluator.setDebugEvaluationOutputForNextEval(value);

View File

@ -17,6 +17,10 @@
package org.apache.poi.xssf.usermodel;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
@ -126,8 +130,32 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator {
assertEquals("Test A1", cXSL_sNR.getStringCellValue());
assertEquals(142.0, cXSL_gNR.getNumericCellValue());
// Try evaluating
// TODO
// Try to evaluate without references, won't work
// (At least, not unit we fix bug #56752 that is)
try {
evaluator.evaluate(cXSL_cell);
fail("Without a fix for #56752, shouldn't be able to evaluate a " +
"reference to a non-provided linked workbook");
} catch(Exception e) {}
// Setup the environment
Map<String,FormulaEvaluator> evaluators = new HashMap<String, FormulaEvaluator>();
evaluators.put("ref2-56737.xlsx", evaluator);
evaluators.put("56737.xlsx",
_testDataProvider.openSampleWorkbook("56737.xlsx").getCreationHelper().createFormulaEvaluator());
evaluators.put("56737.xls",
HSSFTestDataSamples.openSampleWorkbook("56737.xls").getCreationHelper().createFormulaEvaluator());
evaluator.setupReferencedWorkbooks(evaluators);
// Try evaluating all of them, ensure we don't blow up
for(Row r : s) {
for (Cell c : r) {
// TODO Fix and enable
// evaluator.evaluate(c);
}
}
// Evaluate and check results
}
/**