]> source.dussan.org Git - poi.git/commitdiff
Generalise the CollaboratingWorkbooksEnvironment setup, so that XSSF can use it too
authorNick Burch <nick@apache.org>
Mon, 21 Jul 2014 12:23:54 +0000 (12:23 +0000)
committerNick Burch <nick@apache.org>
Mon, 21 Jul 2014 12:23:54 +0000 (12:23 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1612254 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java
src/java/org/apache/poi/ss/formula/WorkbookEvaluatorProvider.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java
src/java/org/apache/poi/ss/util/SheetUtil.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java

index 38f08cd2ca5be4dd4146a7d44e64b6b19f63ebb5..1e8098b9ef3bbfbebb4ee70b2f4bdad2ce449fef 100644 (file)
 
 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
         */
index 1352b716cdca7e5b2266b8e8d7e6cb6d74e290a2..00b3e8bfcb7d1a3caeac09f0735453d19774e57d 100644 (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);
diff --git a/src/java/org/apache/poi/ss/formula/WorkbookEvaluatorProvider.java b/src/java/org/apache/poi/ss/formula/WorkbookEvaluatorProvider.java
new file mode 100644 (file)
index 0000000..dd6f09b
--- /dev/null
@@ -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();
+}
index 17bb3bd579f00a4caa6641c102ccfe555e744fd3..3e8a337814f327808c9e4156846edb46a8412554 100644 (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);
-       
 }
index a5c1fb736db792ef67b6863a3c9b4fe384dcb56f..792ef31f69c4c89a995b8ba1c735b1c548634411 100644 (file)
 
 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() {}
index 4a429f4b429145b7b22c3a4a23848441d3425b8c..90091a146613fd99e3bb010f4e203dbfe6861b3d 100644 (file)
 
 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);
index 643a9cd2662f0c2d8104392cab24cd9556ca1046..1c1de721b639fb38832c1454165eb942a1234c1e 100644 (file)
 
 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
     }
     
     /**