]> source.dussan.org Git - poi.git/commitdiff
Merged revisions 696813 via svnmerge from
authorJosh Micich <josh@apache.org>
Thu, 18 Sep 2008 23:14:48 +0000 (23:14 +0000)
committerJosh Micich <josh@apache.org>
Thu, 18 Sep 2008 23:14:48 +0000 (23:14 +0000)
https://svn.apache.org/repos/asf/poi/trunk

........
  r696813 | josh | 2008-09-18 14:22:23 -0700 (Thu, 18 Sep 2008) | 1 line

  Partitioning common formula logic.  Introduced FormulaRenderingWorkbook interface to make merge with ooxml branch easier
........

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@696847 13f79535-47bb-0310-9956-ffa450edef68

53 files changed:
src/java/org/apache/poi/hssf/dev/FormulaViewer.java
src/java/org/apache/poi/hssf/model/FormulaParser.java
src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java
src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
src/java/org/apache/poi/hssf/record/formula/BoolPtg.java
src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java
src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java
src/java/org/apache/poi/hssf/record/formula/ErrPtg.java
src/java/org/apache/poi/hssf/record/formula/ExpPtg.java
src/java/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java
src/java/org/apache/poi/hssf/record/formula/IntPtg.java
src/java/org/apache/poi/hssf/record/formula/IntersectionPtg.java
src/java/org/apache/poi/hssf/record/formula/MemAreaPtg.java
src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java
src/java/org/apache/poi/hssf/record/formula/MemFuncPtg.java
src/java/org/apache/poi/hssf/record/formula/MissingArgPtg.java
src/java/org/apache/poi/hssf/record/formula/NamePtg.java
src/java/org/apache/poi/hssf/record/formula/NameXPtg.java
src/java/org/apache/poi/hssf/record/formula/NumberPtg.java
src/java/org/apache/poi/hssf/record/formula/OperandPtg.java
src/java/org/apache/poi/hssf/record/formula/OperationPtg.java
src/java/org/apache/poi/hssf/record/formula/ParenthesisPtg.java
src/java/org/apache/poi/hssf/record/formula/Ptg.java
src/java/org/apache/poi/hssf/record/formula/RangePtg.java
src/java/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java
src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
src/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java
src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java
src/java/org/apache/poi/hssf/record/formula/StringPtg.java
src/java/org/apache/poi/hssf/record/formula/TblPtg.java
src/java/org/apache/poi/hssf/record/formula/UnionPtg.java
src/java/org/apache/poi/hssf/record/formula/UnknownPtg.java
src/java/org/apache/poi/hssf/record/formula/ValueOperatorPtg.java
src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java [new file with mode: 0644]
src/java/org/apache/poi/ss/formula/FormulaRenderer.java [new file with mode: 0644]
src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java [new file with mode: 0644]
src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java [new file with mode: 0644]
src/java/org/apache/poi/ss/formula/package.html [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/eventusermodel/TestEventWorkbookBuilder.java
src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
src/testcases/org/apache/poi/hssf/model/TestFormulaParserIf.java
src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java
src/testcases/org/apache/poi/hssf/record/formula/TestArea3DPtg.java
src/testcases/org/apache/poi/hssf/record/formula/TestAreaPtg.java
src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
src/testcases/org/apache/poi/hssf/record/formula/TestRef3DPtg.java
src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java
src/testcases/org/apache/poi/hssf/util/TestAreaReference.java

index 36e527ae5bd4445b12a963c33e53ac58cd68c8fa..167eaba53265853f1fbf65ab91810956e22a35fe 100644 (file)
@@ -97,7 +97,7 @@ public class FormulaViewer
             StringBuffer buf = new StringBuffer();
             
             if (token instanceof ExpPtg) return;
-            buf.append(((OperationPtg) token).toFormulaString((HSSFWorkbook)null));
+            buf.append(((OperationPtg) token).toFormulaString());
             buf.append(sep);
             switch (token.getPtgClass()) {
                 case Ptg.CLASS_REF :
@@ -161,7 +161,7 @@ public class FormulaViewer
                Ptg[] tokens = record.getParsedExpression();
                for (int i = 0; i < tokens.length; i++) {
                        Ptg token = tokens[i];
-            buf.append( token.toFormulaString((HSSFWorkbook)null));
+            buf.append( token.toFormulaString());
             switch (token.getPtgClass()) {
                 case Ptg.CLASS_REF :
                     buf.append("(R)");
index a3fc9c1c4995201d6d99b7cf50c04d168fa9022d..e849dbf6eb26bf9ddc333036f58192319c949f69 100644 (file)
@@ -19,22 +19,54 @@ package org.apache.poi.hssf.model;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Stack;
 
-//import PTGs .. since we need everything, import *
 import org.apache.poi.hssf.record.UnicodeString;
 import org.apache.poi.hssf.record.constant.ErrorConstant;
-import org.apache.poi.hssf.record.formula.*;
+import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
+import org.apache.poi.hssf.record.formula.AddPtg;
+import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.hssf.record.formula.AreaPtg;
+import org.apache.poi.hssf.record.formula.ArrayPtg;
+import org.apache.poi.hssf.record.formula.BoolPtg;
+import org.apache.poi.hssf.record.formula.ConcatPtg;
+import org.apache.poi.hssf.record.formula.DividePtg;
+import org.apache.poi.hssf.record.formula.EqualPtg;
+import org.apache.poi.hssf.record.formula.ErrPtg;
+import org.apache.poi.hssf.record.formula.FuncPtg;
+import org.apache.poi.hssf.record.formula.FuncVarPtg;
+import org.apache.poi.hssf.record.formula.GreaterEqualPtg;
+import org.apache.poi.hssf.record.formula.GreaterThanPtg;
+import org.apache.poi.hssf.record.formula.IntPtg;
+import org.apache.poi.hssf.record.formula.LessEqualPtg;
+import org.apache.poi.hssf.record.formula.LessThanPtg;
+import org.apache.poi.hssf.record.formula.MissingArgPtg;
+import org.apache.poi.hssf.record.formula.MultiplyPtg;
+import org.apache.poi.hssf.record.formula.NamePtg;
+import org.apache.poi.hssf.record.formula.NameXPtg;
+import org.apache.poi.hssf.record.formula.NotEqualPtg;
+import org.apache.poi.hssf.record.formula.NumberPtg;
+import org.apache.poi.hssf.record.formula.ParenthesisPtg;
+import org.apache.poi.hssf.record.formula.PercentPtg;
+import org.apache.poi.hssf.record.formula.PowerPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
+import org.apache.poi.hssf.record.formula.StringPtg;
+import org.apache.poi.hssf.record.formula.SubtractPtg;
+import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
+import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
 import org.apache.poi.ss.usermodel.Name;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.util.AreaReference;
 import org.apache.poi.hssf.util.CellReference;
 import org.apache.poi.hssf.util.CellReference.NameType;
+import org.apache.poi.ss.formula.FormulaRenderer;
 
 /**
  * This class parses a formula string into a List of tokens in RPN order.
@@ -974,7 +1006,7 @@ end;
      * @param lptgs  list of Ptg, can be null or empty
      * @return a human readable String
      */
-    public static String toFormulaString(Workbook book, List lptgs) {
+    public static String toFormulaString(HSSFWorkbook book, List lptgs) {
         String retval = null;
         if (lptgs == null || lptgs.size() == 0) return "#NAME";
         Ptg[] ptgs = new Ptg[lptgs.size()];
@@ -982,16 +1014,6 @@ end;
         retval = toFormulaString(book, ptgs);
         return retval;
     }
-    /**
-     * Convenience method which takes in a list then passes it to the
-     *  other toFormulaString signature. Works on the current
-     *  workbook for 3D and named references
-     * @param lptgs  list of Ptg, can be null or empty
-     * @return a human readable String
-     */
-    public String toFormulaString(List lptgs) {
-        return toFormulaString(book, lptgs);
-    }
 
     /**
      * Static method to convert an array of Ptgs in RPN order
@@ -1000,95 +1022,7 @@ end;
      * @param ptgs  array of Ptg, can be null or empty
      * @return a human readable String
      */
-    public static String toFormulaString(Workbook book, Ptg[] ptgs) {
-        if (ptgs == null || ptgs.length == 0) {
-            // TODO - what is the justification for returning "#NAME" (which is not "#NAME?", btw)
-            return "#NAME";
-        }
-        Stack stack = new Stack();
-
-        for (int i=0 ; i < ptgs.length; i++) {
-            Ptg ptg = ptgs[i];
-            // TODO - what about MemNoMemPtg?
-            if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) {
-                // marks the start of a list of area expressions which will be naturally combined
-                // by their trailing operators (e.g. UnionPtg)
-                // TODO - put comment and throw exception in toFormulaString() of these classes
-                continue;
-            }
-            if (ptg instanceof ParenthesisPtg) {
-                String contents = (String)stack.pop();
-                stack.push ("(" + contents + ")");
-                continue;
-            }
-            if (ptg instanceof AttrPtg) {
-                AttrPtg attrPtg = ((AttrPtg) ptg);
-                if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) {
-                    continue;
-                }
-                if (attrPtg.isSpace()) {
-                    // POI currently doesn't render spaces in formulas
-                    continue;
-                    // but if it ever did, care must be taken:
-                    // tAttrSpace comes *before* the operand it applies to, which may be consistent
-                    // with how the formula text appears but is against the RPN ordering assumed here
-                }
-                if (attrPtg.isSemiVolatile()) {
-                    // similar to tAttrSpace - RPN is violated
-                    continue;
-                }
-                if (attrPtg.isSum()) {
-                    String[] operands = getOperands(stack, attrPtg.getNumberOfOperands());
-                    stack.push(attrPtg.toFormulaString(operands));
-                    continue;
-                }
-                throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString());
-            }
-
-            if (! (ptg instanceof OperationPtg)) {
-                stack.push(ptg.toFormulaString(book));
-                continue;
-            }
-
-            OperationPtg o = (OperationPtg) ptg;
-            String[] operands = getOperands(stack, o.getNumberOfOperands());
-            stack.push(o.toFormulaString(operands));
-        }
-        if(stack.isEmpty()) {
-            // inspection of the code above reveals that every stack.pop() is followed by a
-            // stack.push(). So this is either an internal error or impossible.
-            throw new IllegalStateException("Stack underflow");
-        }
-        String result = (String) stack.pop();
-        if(!stack.isEmpty()) {
-            // Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't
-            // put anything on the stack
-            throw new IllegalStateException("too much stuff left on the stack");
-        }
-        return result;
-    }
-
-    private static String[] getOperands(Stack stack, int nOperands) {
-        String[] operands = new String[nOperands];
-
-        for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order
-            if(stack.isEmpty()) {
-               String msg = "Too few arguments supplied to operation. Expected (" + nOperands
-                    + ") operands but got (" + (nOperands - j - 1) + ")";
-                throw new IllegalStateException(msg);
-            }
-            operands[j] = (String) stack.pop();
-        }
-        return operands;
-    }
-    /**
-     * Static method to convert an array of Ptgs in RPN order
-     *  to a human readable string format in infix mode. Works
-     *  on the current workbook for named and 3D references.
-     * @param ptgs  array of Ptg, can be null or empty
-     * @return a human readable String
-     */
-    public String toFormulaString(Ptg[] ptgs) {
-        return toFormulaString(book, ptgs);
+    public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) {
+        return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs);
     }
 }
index 800f45dbf5d1ec6734ae9cb38f55b3a0f87e785d..037ebb83ae176083ba807b63770483aeb992512d 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
 
@@ -71,7 +70,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
         return field_2_fnc_index == FUNCTION_INDEX_EXTERNAL;
     }
 
-    public String toFormulaString(Workbook book) {
+    public String toFormulaString() {
         return getName();
     }
 
index 68ae5b48c1a49ce30c68d10623bea1e1f88861dd..f16a20077966d8ed7cea6521f73be1631ccead17 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.poi.hssf.record.formula;\r
 \r
 import org.apache.poi.hssf.record.RecordInputStream;\r
-import org.apache.poi.ss.usermodel.Workbook;\r
 import org.apache.poi.util.LittleEndian;\r
 \r
 /**\r
@@ -45,7 +44,7 @@ public abstract class Area2DPtgBase extends AreaPtgBase {
        public final int getSize() {\r
                return SIZE;\r
        }\r
-       public final String toFormulaString(Workbook book) {\r
+       public final String toFormulaString() {\r
        return formatReferenceAsString();\r
        }\r
     public final String toString() {\r
index 0c97d03d29cf70efe3af92e7be9d63dcbcbcba8c..9a538cf70dbe4ba9881c4bd1d94bb5ac6d8182cb 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.util.AreaReference;
-import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -32,7 +31,7 @@ import org.apache.poi.util.LittleEndian;
  * @author Jason Height (jheight at chariot dot net dot au)
  * @version 1.0-pre
  */
-public final class Area3DPtg extends AreaPtgBase {
+public final class Area3DPtg extends AreaPtgBase implements WorkbookDependentFormula {
        public final static byte sid = 0x3b;
        private final static int SIZE = 11; // 10 + 1 for Ptg
        
@@ -89,7 +88,10 @@ public final class Area3DPtg extends AreaPtgBase {
         * @return text representation of this area reference that can be used in text
         *  formulas. The sheet name will get properly delimited if required.
         */
-       public String toFormulaString(Workbook book) {
+       public String toFormulaString(FormulaRenderingWorkbook book) {
                return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
        }
+       public String toFormulaString() {
+               throw new RuntimeException("3D references need a workbook to determine formula text");
+       }
 }
index 1387e76856f491276695c12f03a7cee1cec59def..bfe247897dc7047ba8f28c2d96e6eec1bc93bbcb 100644 (file)
@@ -18,8 +18,7 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.ErrorConstants;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -49,9 +48,8 @@ public final class AreaErrPtg extends OperandPtg {
                LittleEndian.putInt(array, offset + 5, unused2);
        }
 
-
-       public String toFormulaString(Workbook book) {
-               return ErrorConstants.getText(ErrorConstants.ERROR_REF);
+       public String toFormulaString() {
+               return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
        }
 
        public byte getDefaultOperandClass() {
index cf3d82cacf9c06bd2811bcb55d61b3f829de1aac..7bfefc5526808a3e406e3016d239a0ed528c639d 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
-
-import org.apache.poi.ss.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.ss.util.AreaReference;
-import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * Specifies a rectangular area of cells A1:A4 for instance.
@@ -269,7 +267,7 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
         return topLeft.formatAsString() + ":" + botRight.formatAsString(); 
     }
     
-    public String toFormulaString(Workbook book) {
+    public String toFormulaString() {
         return formatReferenceAsString();
     }
 
index 48acaac20564f9b3798f49b1a309d1ecc76f3bce..5e9a3682e99e64e5c0a9807c9d7ad9e14f0a8d17 100644 (file)
@@ -21,7 +21,6 @@ import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.UnicodeString;
 import org.apache.poi.hssf.record.constant.ConstantValueParser;
 import org.apache.poi.hssf.record.constant.ErrorConstant;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -184,7 +183,7 @@ public final class ArrayPtg extends Ptg {
                        + ConstantValueParser.getEncodedSize(token_3_arrayValues);
        }
 
-       public String formatAsString() {
+       public String formatAsString() { // TODO - fold into toFormulaString
                StringBuffer b = new StringBuffer();
                b.append("{");
                for (int y=0;y<getRowCount();y++) {
@@ -202,7 +201,7 @@ public final class ArrayPtg extends Ptg {
                b.append("}");
                return b.toString();
        }
-       public String toFormulaString(Workbook book) {
+       public String toFormulaString() {
                return formatAsString();
        }
        
index 8ebbdc33160df20024311966ad11c29596a47d54..34558ebdf8671722a72482e7258f8b73499ad0be 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
-
-import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * "Special Attributes"
@@ -244,11 +242,11 @@ public final class AttrPtg extends ControlPtg {
         if(space.isSet(field_1_options)) {
             return operands[ 0 ];
         } else if (optiIf.isSet(field_1_options)) {
-            return toFormulaString((Workbook)null) + "(" + operands[ 0 ]             +")";
+            return toFormulaString() + "(" + operands[ 0 ]             +")";
         } else if (optGoto.isSet(field_1_options)) {
-            return toFormulaString((Workbook)null) + operands[0];   //goto isn't a real formula element should not show up
+            return toFormulaString() + operands[0];   //goto isn't a real formula element should not show up
         } else {
-            return toFormulaString((Workbook)null) + "(" + operands[ 0 ] + ")";
+            return toFormulaString() + "(" + operands[ 0 ] + ")";
         }
     }
   
@@ -263,7 +261,7 @@ public final class AttrPtg extends ControlPtg {
         return -1;
     }
         
-   public String toFormulaString(Workbook book) {
+   public String toFormulaString() {
       if(semiVolatile.isSet(field_1_options)) {
         return "ATTR(semiVolatile)";
       }
index ae2fd541cc28bcdfc82b9fb5a3fb52df6b79a9f0..f975b0419ee4ac86e2a2af696664cc580ae9b7ce 100644 (file)
@@ -52,7 +52,7 @@ public final class BoolPtg extends ScalarConstantPtg {
         return SIZE;
     }
 
-    protected String toFormulaString() {
+    public String toFormulaString() {
         return _value ? "TRUE" : "FALSE";
     }
 }
index 92506dfbe723499e0f6d5499d3dc22750b93e7f6..a45cfcd69ea040e6fdff97a723afe2f02cec22dd 100644 (file)
@@ -18,8 +18,9 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.ErrorConstants;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -29,7 +30,7 @@ import org.apache.poi.util.LittleEndian;
  * @author Patrick Luby
  * @version 1.0-pre
  */
-public final class DeletedArea3DPtg extends OperandPtg {
+public final class DeletedArea3DPtg extends OperandPtg implements WorkbookDependentFormula {
        public final static byte sid = 0x3d;
        private final int field_1_index_extern_sheet;
        private final int unused1;
@@ -46,10 +47,12 @@ public final class DeletedArea3DPtg extends OperandPtg {
                unused1 = in.readInt();
                unused2 = in.readInt();
        }
-
-       public String toFormulaString(Workbook book) {
+       public String toFormulaString(FormulaRenderingWorkbook book) {
                return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, 
-                               ErrorConstants.getText(ErrorConstants.ERROR_REF));
+                               HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF));
+       }
+       public String toFormulaString() {
+               throw new RuntimeException("3D references need a workbook to determine formula text");
        }
        public byte getDefaultOperandClass() {
                return Ptg.CLASS_REF;
index 900a48fe8e3ccc849a4a6cbd55e4f6dcf2eafb34..4dbf09b7ff1f46797e29b0d6842ab87c720611b1 100644 (file)
@@ -19,8 +19,9 @@ package org.apache.poi.hssf.record.formula;
 
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.ErrorConstants;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -30,7 +31,7 @@ import org.apache.poi.util.LittleEndian;
  * @author Patrick Luby
  * @version 1.0-pre
  */
-public final class DeletedRef3DPtg extends OperandPtg {
+public final class DeletedRef3DPtg extends OperandPtg implements WorkbookDependentFormula {
        public final static byte sid  = 0x3c;
        private final int field_1_index_extern_sheet;
        private final int unused1;
@@ -46,9 +47,12 @@ public final class DeletedRef3DPtg extends OperandPtg {
                unused1 = 0;
        }
 
-       public String toFormulaString(Workbook book) {
+       public String toFormulaString(FormulaRenderingWorkbook book) {
                return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, 
-                               ErrorConstants.getText(ErrorConstants.ERROR_REF));
+                               HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF));
+       }
+       public String toFormulaString() {
+               throw new RuntimeException("3D references need a workbook to determine formula text");
        }
        public byte getDefaultOperandClass() {
                return Ptg.CLASS_REF;
index d94f2a38072658d53fe51d91203c5240473e02b2..65d40dc51ed2a7880991b835bca2bc290c0c47e9 100644 (file)
@@ -67,7 +67,7 @@ public final class ErrPtg extends ScalarConstantPtg {
         array[offset + 1] = (byte)field_1_error_code;
     }
 
-    protected String toFormulaString() {
+    public String toFormulaString() {
         return HSSFErrorConstants.getText(field_1_error_code);
     }
 
index 62a8878508565b21e823cb592c0fa5cf3d37b139..5c48aeb6b0805605c288d3dbeea3135d71b85231 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordFormatException;
 import org.apache.poi.hssf.record.RecordInputStream;
-
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -61,7 +59,7 @@ public final class ExpPtg extends ControlPtg {
       return field_2_first_col;
     }    
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         throw new RecordFormatException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula by ValueRecordsAggregate, but it wasn't");
     }
index b928931b098703bd4591ef5eb302c0b98534f256..412c110d3a14382ff4ed473664c3afe6c8ed25c5 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 
 /**
  * @author Josh Micich
@@ -28,16 +28,16 @@ final class ExternSheetNameResolver {
                // no instances of this class
        }
 
-       public static String prependSheetName(Workbook book, int field_1_index_extern_sheet, String cellRefText) {
-               String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet);
+       public static String prependSheetName(FormulaRenderingWorkbook book, int field_1_index_extern_sheet, String cellRefText) {
+               String sheetName = book.getSheetNameByExternSheet(field_1_index_extern_sheet);
                StringBuffer sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4);
                if (sheetName.length() < 1) {
                        // What excel does if sheet has been deleted
                        sb.append("#REF"); // note - '!' added just once below
                } else {
-                       SheetNameFormatter.appendFormat(sb, sheetName);
+               SheetNameFormatter.appendFormat(sb, sheetName);
                }
-                       sb.append('!');
+               sb.append('!');
                sb.append(cellRefText);
                return sb.toString();
        }
index c4abb7b1bc2bd9e563c8280b14e9afaced69c3b6..ea3fc80bd6f523d9cf39efa5f278ddd9b9350d10 100644 (file)
@@ -68,7 +68,7 @@ public final class IntPtg extends ScalarConstantPtg {
         return SIZE;
     }
 
-    protected String toFormulaString() {
+    public String toFormulaString() {
         return String.valueOf(getValue());
     }
 }
index d939e057026288b1a2348d9b6bef91916d0edab8..f96c5ecb1a181c722712e6024bd068a7294f283e 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 
 /**
  * @author Daniel Noll (daniel at nuix dot com dot au)
@@ -46,7 +45,7 @@ public final class IntersectionPtg extends OperationPtg {
     }
 
     /** Implementation of method from Ptg */
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return " ";
     }
index 10ce43789a781f83291509640c8fed6acaf674f1..951fd7c43647ad6c21cbe2ad672e570fcf756d5a 100644 (file)
@@ -17,9 +17,8 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * @author Daniel Noll (daniel at nuix dot com dot au)
@@ -74,7 +73,7 @@ public class MemAreaPtg extends OperandPtg {
         return SIZE;
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return ""; // TODO: Not sure how to format this. -- DN
     }
index e6afeae958c9cf8ea7a8b9c9318701f686ff8519..d3de53fe1327ecf4d592e15c69ca3519db127187 100644 (file)
@@ -18,7 +18,7 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
  *
@@ -45,7 +45,7 @@ public final class MemErrPtg extends MemAreaPtg {
         array[offset] = (byte) (sid + getPtgClass());
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return "ERR#";
     }
index 26fe637baedb51b08e1c15b231f3e355d68ad9c7..991f1742c01266265a8428aebd20615aa3eca4f3 100644 (file)
@@ -17,9 +17,8 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * @author Glen Stampoultzis (glens at apache.org)
@@ -51,7 +50,7 @@ public final class MemFuncPtg extends OperandPtg {
         LittleEndian.putUShort( array, offset + 1, field_1_len_ref_subexpression );
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return "";
     }
index ffcf423b4f1559aa994bc0efec57667cd3a9d1ca..075105f50c9a11dba07c0f4d3901a081cb32af13 100644 (file)
@@ -42,7 +42,7 @@ public final class MissingArgPtg extends ScalarConstantPtg {
         return SIZE;
     }
    
-    protected String toFormulaString() {
+    public String toFormulaString() {
         return " ";
     }
 }
index 1087ed9d236b41e577b37d5d48206e0c20fdd60a..59670f87580c1ac1adcf75fbc9432a440e6db26a 100644 (file)
@@ -18,7 +18,8 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -26,7 +27,7 @@ import org.apache.poi.util.LittleEndian;
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public final class NamePtg extends OperandPtg {
+public final class NamePtg extends OperandPtg implements WorkbookDependentFormula {
     public final static short sid  = 0x23;
     private final static int  SIZE = 5;
     /** one-based index to defined name record */
@@ -64,10 +65,13 @@ public final class NamePtg extends OperandPtg {
         return SIZE;
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString(FormulaRenderingWorkbook book)
     {
-       return book.getNameName(field_1_label_index - 1);
+       return book.getNameText(this);
     }
+       public String toFormulaString() {
+               throw new RuntimeException("3D references need a workbook to determine formula text");
+       }
     
     public byte getDefaultOperandClass() {
                return Ptg.CLASS_REF;
index 393a8cd69053c6600e978e007a45bf1f5ff3c999..7f1614347f322fa9a7c1428370fca90dd1032b63 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * 
  * @author aviks
  */
-public final class NameXPtg extends OperandPtg {
+public final class NameXPtg extends OperandPtg implements WorkbookDependentFormula {
        public final static short sid = 0x39;
        private final static int SIZE = 7;
 
@@ -65,9 +66,12 @@ public final class NameXPtg extends OperandPtg {
                return SIZE;
        }
 
-       public String toFormulaString(Workbook book) {
+       public String toFormulaString(FormulaRenderingWorkbook book) {
                // -1 to convert definedNameIndex from 1-based to zero-based
-               return book.resolveNameXText(_sheetRefIndex, _nameNumber - 1);
+               return book.resolveNameXText(this);
+       }
+       public String toFormulaString() {
+               throw new RuntimeException("3D references need a workbook to determine formula text");
        }
 
        public byte getDefaultOperandClass() {
index d7f7195e05051374e68bd64742af5178de871eb8..cddb674475dc46d499e344396a1012232c3eec02 100644 (file)
@@ -63,7 +63,7 @@ public final class NumberPtg extends ScalarConstantPtg {
         return SIZE;
     }
 
-    protected String toFormulaString() {
+    public String toFormulaString() {
         // TODO - java's rendering of double values is not quite same as excel's
         // Maybe use HSSFDataFormatter?
         return String.valueOf(field_1_value);
index 02a708f64a030d8f3c1b11a977fcd12533d90967..0c1d1faeb865edefff4d1861846bc781c37169ac 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.record.formula;
 
+
 /**
  * @author Josh Micich
  */
index 085fa1e16b9567d1b8071b71fbc0725b164db7d5..1e7800b55d655e7de9451a7e4131c3f01e9e99de 100644 (file)
@@ -46,5 +46,4 @@ public abstract class OperationPtg extends Ptg {
        // TODO remove "int getType();" from Eval hierarchy
        throw new RuntimeException("remove this method");
     }
-    
 }
index 67bb85bfedcac8b8bfc98180d4d60c90e7b15376..5365b939d82aa7d7f79f230896c9f94b9ebd17d1 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import java.util.List;
-
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * While formula tokens are stored in RPN order and thus do not need parenthesis for 
@@ -52,7 +48,7 @@ public final class ParenthesisPtg extends ControlPtg {
         return SIZE;
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return "()";
     }
index 630803c3cbe915ab2ee7b750eda3accc03bae0db..4b952b65f747091d2cf7f7267ecbb2d35c7a6896 100644 (file)
@@ -22,7 +22,7 @@ import java.util.List;
 import java.util.Stack;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
  * <tt>Ptg</tt> represents a syntactic token in a formula.  'PTG' is an acronym for 
@@ -305,7 +305,7 @@ public abstract class Ptg implements Cloneable {
        /**
         * return a string representation of this token alone
         */
-       public abstract String toFormulaString(Workbook book);
+       public abstract String toFormulaString();
        /**
         * dump a debug representation (hexdump) to a string
         */
index d6076f2baf2b31d46163961e8e99d108e2ac48bb..658e2f47b412e875597726462782442a3aa8e122 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 
 /**
  * @author Daniel Noll (daniel at nuix dot com dot au)
@@ -46,7 +45,7 @@ public final class RangePtg  extends OperationPtg {
         array[ offset + 0 ] = sid;
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return ":";
     }
index 2fff41d6b7f5f0ccbc097a974f3827e1f747ea05..545ff0bfc4b728f214c7b3f37a2bc4bde0d1212c 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -49,7 +48,7 @@ abstract class Ref2DPtgBase extends RefPtgBase {
        LittleEndian.putByte(array, offset+0, getSid() + getPtgClass());
        writeCoordinates(array, offset+1);
     }
-    public final String toFormulaString(Workbook book) {
+    public final String toFormulaString() {
        return formatReferenceAsString();
     }
 
index a6ca3db2ebbe54344511281516aecf199fd4bfd6..790d3cd1a736bd44376b893f1d06212b715dc121 100644 (file)
@@ -18,8 +18,9 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -30,7 +31,7 @@ import org.apache.poi.util.LittleEndian;
  * @author Jason Height (jheight at chariot dot net dot au)
  * @version 1.0-pre
  */
-public final class Ref3DPtg extends RefPtgBase {
+public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula {
     public final static byte sid  = 0x3a;
 
     private final static int  SIZE = 7; // 6 + 1 for Ptg
@@ -86,7 +87,10 @@ public final class Ref3DPtg extends RefPtgBase {
      * @return text representation of this cell reference that can be used in text 
      * formulas. The sheet name will get properly delimited if required.
      */
-    public String toFormulaString(Workbook book) {
+    public String toFormulaString(FormulaRenderingWorkbook book) {
                return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
     }
+       public String toFormulaString() {
+               throw new RuntimeException("3D references need a workbook to determine formula text");
+       }
 }
index a3030e1bd719ed329fe4d92062a057fe2e788a06..699f6344a3865c296fa445eed0bfbca1664c406c 100755 (executable)
@@ -18,8 +18,8 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.ErrorConstants;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -53,8 +53,8 @@ public final class RefErrorPtg extends OperandPtg {
         return SIZE;
     }
 
-    public String toFormulaString(Workbook book) {
-        return ErrorConstants.getText(ErrorConstants.ERROR_REF);
+    public String toFormulaString() {
+        return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
     }
     
     public byte getDefaultOperandClass() {
index bb1613c9acc5d93f51465cb57767882d8cdf2602..869e38d2e08f5022ae0fe9a4bd69887a6d5699a9 100644 (file)
@@ -17,7 +17,6 @@
 \r
 package org.apache.poi.hssf.record.formula;\r
 \r
-import org.apache.poi.ss.usermodel.Workbook;\r
 \r
 /**\r
  * @author Josh Micich\r
@@ -31,12 +30,6 @@ abstract class ScalarConstantPtg extends Ptg {
                return Ptg.CLASS_VALUE;\r
        }\r
 \r
-       public final String toFormulaString(Workbook book) {\r
-               return toFormulaString();\r
-       }\r
-\r
-       protected abstract String toFormulaString();\r
-\r
        public final String toString() {\r
                StringBuffer sb = new StringBuffer(64);\r
                sb.append(getClass().getName()).append(" [");\r
index 7007b48fdb71b13798f0bafa005aed0e9f8e26fe..2f34e2e360d48b3f90702066aa3190d72d0add85 100644 (file)
@@ -97,7 +97,7 @@ public final class StringPtg extends ScalarConstantPtg {
         }
     }
 
-    protected String toFormulaString() {
+    public String toFormulaString() {
         String value = field_3_string;
         int len = value.length();
         StringBuffer sb = new StringBuffer(len + 4);
index 9cc7334605a6ed916dc8a8121cff90ab562b67ad..0b17e268e254e5a732e6872ff8cf2ffa12ab79f8 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordFormatException;
 import org.apache.poi.hssf.record.RecordInputStream;
-
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -68,7 +66,7 @@ public final class TblPtg extends ControlPtg {
       return field_2_first_col;
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         // table(....)[][]
         throw new RecordFormatException("Table and Arrays are not yet supported");
index 266f7decabd63ef192a43955d8f775222bba9d82..fdd82ce54927fb5bc0e52c053b6648f84b07c726 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 
 /**
  * @author Glen Stampoultzis (glens at apache.org)
@@ -45,7 +44,7 @@ public final class UnionPtg extends OperationPtg {
         array[ offset + 0 ] = sid;
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return ",";
     }
index 07749022edc0e4dc63d869a42c6c1502175332a3..d073878707f61bb3ddc7b143a5b85e728df1c10b 100644 (file)
@@ -16,7 +16,6 @@
 ==================================================================== */
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
@@ -49,7 +48,7 @@ public class UnknownPtg extends Ptg {
         return size;
     }
 
-    public String toFormulaString(Workbook book)
+    public String toFormulaString()
     {
         return "UNKNOWN";
     }
index 7f5d86cac1eb00623cb384516a7a83e8cd086182..7bb632b59598a543b8a4c1d77674a40b3e07a357 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
  * Common superclass of all value operators.
@@ -47,7 +47,7 @@ public abstract class ValueOperatorPtg extends OperationPtg {
        public final int getSize() {
                return 1;
        }
-    public final String toFormulaString(Workbook book) {
+    public final String toFormulaString() {
        // TODO - prune this method out of the hierarchy
        throw new RuntimeException("toFormulaString(String[] operands) should be used for subclasses of OperationPtgs");
        }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
new file mode 100644 (file)
index 0000000..f9399ee
--- /dev/null
@@ -0,0 +1,38 @@
+package org.apache.poi.hssf.usermodel;\r
+\r
+import org.apache.poi.hssf.model.Workbook;\r
+import org.apache.poi.hssf.record.formula.NamePtg;\r
+import org.apache.poi.hssf.record.formula.NameXPtg;\r
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;\r
+\r
+/**\r
+ * Internal POI use only\r
+ * \r
+ * @author Josh Micich\r
+ */\r
+public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook {\r
+\r
+       private final Workbook _iBook;\r
+       \r
+       public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {\r
+               if (book == null) {\r
+                       return null;\r
+               }\r
+               return new HSSFEvaluationWorkbook(book);\r
+       }\r
+\r
+       private HSSFEvaluationWorkbook(HSSFWorkbook book) {\r
+               _iBook = book.getWorkbook();\r
+       }\r
+\r
+       public String resolveNameXText(NameXPtg n) {\r
+               return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());\r
+       }\r
+\r
+       public String getSheetNameByExternSheet(int externSheetIndex) {\r
+               return _iBook.findSheetNameFromExternSheet(externSheetIndex);\r
+       }\r
+       public String getNameText(NamePtg namePtg) {\r
+               return _iBook.getNameRecord(namePtg.getIndex()).getNameText();\r
+       }\r
+}\r
diff --git a/src/java/org/apache/poi/ss/formula/FormulaRenderer.java b/src/java/org/apache/poi/ss/formula/FormulaRenderer.java
new file mode 100644 (file)
index 0000000..21386cd
--- /dev/null
@@ -0,0 +1,124 @@
+package org.apache.poi.ss.formula;\r
+\r
+import java.util.List;\r
+import java.util.Stack;\r
+\r
+import org.apache.poi.hssf.record.formula.AttrPtg;\r
+import org.apache.poi.hssf.record.formula.MemAreaPtg;\r
+import org.apache.poi.hssf.record.formula.MemErrPtg;\r
+import org.apache.poi.hssf.record.formula.MemFuncPtg;\r
+import org.apache.poi.hssf.record.formula.OperationPtg;\r
+import org.apache.poi.hssf.record.formula.ParenthesisPtg;\r
+import org.apache.poi.hssf.record.formula.Ptg;\r
+\r
+public class FormulaRenderer {\r
+    /**\r
+     * Convenience method which takes in a list then passes it to the\r
+     *  other toFormulaString signature.\r
+     * @param book   workbook for 3D and named references\r
+     * @param lptgs  list of Ptg, can be null or empty\r
+     * @return a human readable String\r
+     */\r
+    public static String toFormulaString(FormulaRenderingWorkbook book, List lptgs) {\r
+        String retval = null;\r
+        if (lptgs == null || lptgs.size() == 0) return "#NAME";\r
+        Ptg[] ptgs = new Ptg[lptgs.size()];\r
+        ptgs = (Ptg[])lptgs.toArray(ptgs);\r
+        retval = toFormulaString(book, ptgs);\r
+        return retval;\r
+    }\r
+    \r
+    /**\r
+     * Static method to convert an array of Ptgs in RPN order\r
+     * to a human readable string format in infix mode.\r
+     * @param book  workbook for named and 3D references\r
+     * @param ptgs  array of Ptg, can be null or empty\r
+     * @return a human readable String\r
+     */\r
+    public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) {\r
+        if (ptgs == null || ptgs.length == 0) {\r
+            // TODO - what is the justification for returning "#NAME" (which is not "#NAME?", btw)\r
+            return "#NAME";\r
+        }\r
+        Stack stack = new Stack();\r
+\r
+        for (int i=0 ; i < ptgs.length; i++) {\r
+            Ptg ptg = ptgs[i];\r
+            // TODO - what about MemNoMemPtg?\r
+            if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) {\r
+                // marks the start of a list of area expressions which will be naturally combined\r
+                // by their trailing operators (e.g. UnionPtg)\r
+                // TODO - put comment and throw exception in toFormulaString() of these classes\r
+                continue;\r
+            }\r
+            if (ptg instanceof ParenthesisPtg) {\r
+                String contents = (String)stack.pop();\r
+                stack.push ("(" + contents + ")");\r
+                continue;\r
+            }\r
+            if (ptg instanceof AttrPtg) {\r
+                AttrPtg attrPtg = ((AttrPtg) ptg);\r
+                if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) {\r
+                    continue;\r
+                }\r
+                if (attrPtg.isSpace()) {\r
+                    // POI currently doesn't render spaces in formulas\r
+                    continue;\r
+                    // but if it ever did, care must be taken:\r
+                    // tAttrSpace comes *before* the operand it applies to, which may be consistent\r
+                    // with how the formula text appears but is against the RPN ordering assumed here\r
+                }\r
+                if (attrPtg.isSemiVolatile()) {\r
+                    // similar to tAttrSpace - RPN is violated\r
+                    continue;\r
+                }\r
+                if (attrPtg.isSum()) {\r
+                    String[] operands = getOperands(stack, attrPtg.getNumberOfOperands());\r
+                    stack.push(attrPtg.toFormulaString(operands));\r
+                    continue;\r
+                }\r
+                throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString());\r
+            }\r
+\r
+            if (ptg instanceof WorkbookDependentFormula) {\r
+                WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg;\r
+                               stack.push(optg.toFormulaString(book));\r
+                continue;\r
+            }\r
+            if (! (ptg instanceof OperationPtg)) {\r
+                stack.push(ptg.toFormulaString());\r
+                continue;\r
+            }\r
+\r
+            OperationPtg o = (OperationPtg) ptg;\r
+            String[] operands = getOperands(stack, o.getNumberOfOperands());\r
+            stack.push(o.toFormulaString(operands));\r
+        }\r
+        if(stack.isEmpty()) {\r
+            // inspection of the code above reveals that every stack.pop() is followed by a\r
+            // stack.push(). So this is either an internal error or impossible.\r
+            throw new IllegalStateException("Stack underflow");\r
+        }\r
+        String result = (String) stack.pop();\r
+        if(!stack.isEmpty()) {\r
+            // Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't\r
+            // put anything on the stack\r
+            throw new IllegalStateException("too much stuff left on the stack");\r
+        }\r
+        return result;\r
+    }\r
+\r
+    private static String[] getOperands(Stack stack, int nOperands) {\r
+        String[] operands = new String[nOperands];\r
+\r
+        for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order\r
+            if(stack.isEmpty()) {\r
+               String msg = "Too few arguments supplied to operation. Expected (" + nOperands\r
+                    + ") operands but got (" + (nOperands - j - 1) + ")";\r
+                throw new IllegalStateException(msg);\r
+            }\r
+            operands[j] = (String) stack.pop();\r
+        }\r
+        return operands;\r
+    }\r
+}\r
diff --git a/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java b/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java
new file mode 100644 (file)
index 0000000..3a92aa8
--- /dev/null
@@ -0,0 +1,11 @@
+package org.apache.poi.ss.formula;\r
+\r
+import org.apache.poi.hssf.record.formula.NamePtg;\r
+import org.apache.poi.hssf.record.formula.NameXPtg;\r
+\r
+public interface FormulaRenderingWorkbook {\r
+\r
+       String getSheetNameByExternSheet(int externSheetIndex);\r
+       String resolveNameXText(NameXPtg nameXPtg);\r
+       String getNameText(NamePtg namePtg);\r
+}\r
diff --git a/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java b/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java
new file mode 100644 (file)
index 0000000..420527d
--- /dev/null
@@ -0,0 +1,5 @@
+package org.apache.poi.ss.formula;\r
+\r
+public interface WorkbookDependentFormula {\r
+       String toFormulaString(FormulaRenderingWorkbook book);\r
+}\r
diff --git a/src/java/org/apache/poi/ss/formula/package.html b/src/java/org/apache/poi/ss/formula/package.html
new file mode 100644 (file)
index 0000000..1af2f84
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\r
+<!--\r
+   ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+   ====================================================================\r
+-->\r
+<html>\r
+<head>\r
+</head>\r
+<body bgcolor="white">\r
+\r
+This package contains common internal POI code for manipulating formulas.\r
+Client applications should not refer to these classes directly.\r
+\r
+</body>\r
+</html>\r
index e88d274eacdbd987ab15a634f4a271f149457279..a17414af749a76eaa617db7288a0309c1be6c56e 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.poi.hssf.record.FormulaRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.Ref3DPtg;
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 /**
@@ -110,7 +111,8 @@ public final class TestEventWorkbookBuilder extends TestCase {
                assertTrue(ptgs[0] instanceof Ref3DPtg);
                
                Ref3DPtg ptg = (Ref3DPtg)ptgs[0];
-               assertEquals("Sheet1!A1", ptg.toFormulaString(stubHSSF));
+               HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(stubHSSF);
+               assertEquals("Sheet1!A1", ptg.toFormulaString(book));
                
                
                // Now check we get the right formula back for
index e1ffc2538d6e9d55f5899b808d01a046f3174c58..bb9f3de605343caf41b29e51a7b46aa590df2ce6 100644 (file)
@@ -51,6 +51,7 @@ import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
 import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFName;
 import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
@@ -130,13 +131,14 @@ public final class TestFormulaParser extends TestCase {
        public void testMacroFunction() {
                // testNames.xls contains a VB function called 'myFunc'
                HSSFWorkbook w = HSSFTestDataSamples.openSampleWorkbook("testNames.xls");
+               HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(w);
 
                Ptg[] ptg = FormulaParser.parse("myFunc()", w);
                // myFunc() actually takes 1 parameter.  Don't know if POI will ever be able to detect this problem
 
                // the name gets encoded as the first arg
                NamePtg tname = (NamePtg) ptg[0];
-               assertEquals("myFunc", tname.toFormulaString(w));
+               assertEquals("myFunc", tname.toFormulaString(book));
 
                AbstractFunctionPtg tfunc = (AbstractFunctionPtg) ptg[1];
                assertTrue(tfunc.isExternalFunction());
@@ -871,7 +873,7 @@ public final class TestFormulaParser extends TestCase {
                assertEquals(2, ptgs.length);
                Ptg ptg0 = ptgs[0];
                assertEquals(ArrayPtg.class, ptg0.getClass());
-               assertEquals("{1.0,2.0,2.0,#REF!;FALSE,3.0,3.0,2.0}", ptg0.toFormulaString(null));
+               assertEquals("{1.0,2.0,2.0,#REF!;FALSE,3.0,3.0,2.0}", ptg0.toFormulaString());
                
                ArrayPtg aptg = (ArrayPtg) ptg0;
                Object[][] values = aptg.getTokenArrayValues();
index 6f7c4747cfc327d7611718ff1c2230d098b75959..415cca33f1a4e79d778a5376c0513828698cb636 100644 (file)
@@ -33,7 +33,6 @@ import org.apache.poi.hssf.record.formula.NotEqualPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.StringPtg;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
  * Tests <tt>FormulaParser</tt> specifically with respect to IF() functions
@@ -202,7 +201,7 @@ public final class TestFormulaParserIf extends TestCase {
                assertEquals(true, flag.getValue());
                assertEquals("Y", y.getValue());
                assertEquals("N", n.getValue());
-               assertEquals("IF", funif.toFormulaString((HSSFWorkbook) null));
+               assertEquals("IF", funif.toFormulaString());
                assertTrue("Goto ptg exists", goto1.isGoto());
        }
        /**
index 3742342360a357cc74707a8313f48b416e8aae92..7a13cfe5fda3c25db6380351308c607a5d2ad06d 100644 (file)
@@ -66,7 +66,7 @@ public final class TestSharedFormulaRecord extends TestCase {
                Ptg[] convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 100, 200);
                
                RefPtg refPtg = (RefPtg) convertedFormula[1];
-               assertEquals("$C101", refPtg.toFormulaString(null));
+               assertEquals("$C101", refPtg.toFormulaString());
                if (refPtg.getPtgClass() == Ptg.CLASS_REF) {
                        throw new AssertionFailedError("Identified bug 45123");
                }
index e83a59b42db4681a9a5ba79875b02e075c2c35d5..b4aa683833df0cd88c480abd09b166091de51ec9 100644 (file)
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record.formula;
 
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
@@ -27,21 +27,22 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  */
 public final class TestArea3DPtg extends AbstractPtgTestCase {
 
-    /**
-     * confirms that sheet names get properly escaped
-     */
+       /**
+        * confirms that sheet names get properly escaped
+        */
        public void testToFormulaString() {
-               
+
                Area3DPtg target = new Area3DPtg("A1:B1", (short)0);
-               
+
                String sheetName = "my sheet";
-               HSSFWorkbook book = createWorkbookWithSheet(sheetName);
+               HSSFWorkbook wb = createWorkbookWithSheet(sheetName);
+               HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(wb);
                assertEquals("'my sheet'!A1:B1", target.toFormulaString(book));
-               
-        book.setSheetName(0, "Sheet1");
-        assertEquals("Sheet1!A1:B1", target.toFormulaString(book));
-        
-        book.setSheetName(0, "C64");
-        assertEquals("'C64'!A1:B1", target.toFormulaString(book));
+
+               wb.setSheetName(0, "Sheet1");
+               assertEquals("Sheet1!A1:B1", target.toFormulaString(book));
+
+               wb.setSheetName(0, "C64");
+               assertEquals("'C64'!A1:B1", target.toFormulaString(book));
        }
 }
index 3a7f2f29a418c14abbb94c089bb7971e2ab9db74..f5b80f6dac38fc7694a87f9ccdd0edada5c2dd65 100644 (file)
@@ -21,6 +21,7 @@ package org.apache.poi.hssf.record.formula;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.model.FormulaParser;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
  * Tests for {@link AreaPtg}.
@@ -83,14 +84,10 @@ public final class TestAreaPtg extends TestCase {
                assertEquals("Relative references changed", expectedFormula2, newFormula2);
        }
        
-       private String shiftAllColumnsBy1(String  formula)
-       {
+       private static String shiftAllColumnsBy1(String  formula) {
                int letUsShiftColumn1By1Column=1;
-               
-               FormulaParser parser = new FormulaParser(formula,null);
-               parser.parse();
-
-               final Ptg[] ptgs = parser.getRPNPtg();
+               HSSFWorkbook wb = null;
+               Ptg[] ptgs = FormulaParser.parse(formula, wb);
                for(int i=0; i<ptgs.length; i++)
                {
                        Ptg ptg = ptgs[i];
@@ -101,10 +98,7 @@ public final class TestAreaPtg extends TestCase {
                                aptg.setLastColumn((short)(aptg.getLastColumn()+letUsShiftColumn1By1Column));
                        }
                }
-               String newFormula = parser.toFormulaString(ptgs);
+               String newFormula = FormulaParser.toFormulaString(wb, ptgs);
                return newFormula;
        }
-       
-       
-
 }
index 2455c87ab9c35d3fc9fd090503f166d7598d2bca..df2c1f77bd6d6e1aad0f858e2c4de4e0f0c61b69 100644 (file)
@@ -119,7 +119,7 @@ public final class TestArrayPtg extends TestCase {
                
                String actualFormula;
                try {
-                       actualFormula = ptg.toFormulaString(null);
+                       actualFormula = ptg.toFormulaString();
                } catch (IllegalArgumentException e) {
                        if (e.getMessage().equals("Unexpected constant class (java.lang.Boolean)")) {
                                throw new AssertionFailedError("Identified bug 45380");
index 4de0c7bdb270b240d648d508b4f280a500dd7d5c..9ccb7c89458640819cf6c7884230d6100e90a5de 100644 (file)
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record.formula;
 
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
@@ -28,17 +28,17 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 public final class TestRef3DPtg extends AbstractPtgTestCase {
 
        public void testToFormulaString() {
-               
+
                Ref3DPtg target = new Ref3DPtg("A1", (short)0);
-               
-               HSSFWorkbook book = createWorkbookWithSheet("my sheet");
-               
+
+               HSSFWorkbook wb = createWorkbookWithSheet("my sheet");
+               HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(wb);
                assertEquals("'my sheet'!A1", target.toFormulaString(book));
 
-        book.setSheetName(0, "ProfitAndLoss");
-        assertEquals("ProfitAndLoss!A1", target.toFormulaString(book));
-        
-        book.setSheetName(0, "profit+loss");
-        assertEquals("'profit+loss'!A1", target.toFormulaString(book));
+               wb.setSheetName(0, "ProfitAndLoss");
+               assertEquals("ProfitAndLoss!A1", target.toFormulaString(book));
+
+               wb.setSheetName(0, "profit+loss");
+               assertEquals("'profit+loss'!A1", target.toFormulaString(book));
        }
 }
index dc4454d51574cb28cd32f4cb4b757aa6e653169d..c2f11cfcc9b48895a23da7fb22d8e67254fbc1c6 100644 (file)
@@ -202,7 +202,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
                assertEquals(2, ptg.getLastColumn());
                assertEquals(0, ptg.getFirstRow());
                assertEquals(65535, ptg.getLastRow());
-               assertEquals("C:C", ptg.toFormulaString(wb));
+               assertEquals("C:C", ptg.toFormulaString());
 
                // Will show as C:C, but won't know how many
                // rows it covers as we don't have the sheet
@@ -316,6 +316,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
                evaluator.evaluate(cell);
                int evalCount = evaluator.getEvaluationCount();
                // With caching, the evaluationCount is 8 which is a big improvement
+               assertTrue(evalCount > 0);  // make sure the counter is actually working
                if (evalCount > 10) {
                        // Without caching, evaluating cell 'A9' takes 21845 evaluations which consumes
                        // much time (~3 sec on Core 2 Duo 2.2GHz)
index c9356b85271dcd197de81f1dd14313b68474bcc9..f19aa0ca4d741eb18f3f4c31fac6c6e84b9b68a5 100644 (file)
@@ -30,6 +30,7 @@ import org.apache.poi.hssf.record.formula.MemFuncPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.UnionPtg;
 import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFName;
 import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
@@ -192,6 +193,7 @@ public final class TestAreaReference extends TestCase {
         InputStream is = HSSFTestDataSamples.openSampleFileStream("44167.xls");
         HSSFWB wb = new HSSFWB(is);
         Workbook workbook = wb.getWorkbook();
+        HSSFEvaluationWorkbook eb = HSSFEvaluationWorkbook.create(wb);
 
         assertEquals(1, wb.getNumberOfNames());
         String sheetName = "Tabelle1";
@@ -213,10 +215,10 @@ public final class TestAreaReference extends TestCase {
         Area3DPtg ptgB = (Area3DPtg)def[1];
         Area3DPtg ptgC = (Area3DPtg)def[2];
         UnionPtg ptgD = (UnionPtg)def[3];
-        assertEquals("", ptgA.toFormulaString(wb));
-        assertEquals(refA, ptgB.toFormulaString(wb));
-        assertEquals(refB, ptgC.toFormulaString(wb));
-        assertEquals(",", ptgD.toFormulaString(wb));
+        assertEquals("", ptgA.toFormulaString());
+        assertEquals(refA, ptgB.toFormulaString(eb));
+        assertEquals(refB, ptgC.toFormulaString(eb));
+        assertEquals(",", ptgD.toFormulaString());
 
         assertEquals(ref, nr.getAreaReference(wb));