]> source.dussan.org Git - poi.git/commitdiff
Some more clean up of array formula support in preparation for patch 48292
authorJosh Micich <josh@apache.org>
Tue, 8 Dec 2009 21:30:35 +0000 (21:30 +0000)
committerJosh Micich <josh@apache.org>
Tue, 8 Dec 2009 21:30:35 +0000 (21:30 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@888577 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
src/java/org/apache/poi/ss/formula/FormulaParser.java
src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java

index 0058985ae349333329f10c72abdc87b8a7a2c1c4..3a6354e01e38ac58d53ec341e1232db74a8bfbe3 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.constant.ConstantValueParser;
 import org.apache.poi.hssf.record.constant.ErrorConstant;
+import org.apache.poi.ss.util.NumberToTextConverter;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -193,7 +194,7 @@ public final class ArrayPtg extends Ptg {
                        return "\"" + (String)o + "\"";
                }
                if (o instanceof Double) {
-                       return ((Double)o).toString();
+                       return NumberToTextConverter.toText(((Double)o).doubleValue());
                }
                if (o instanceof Boolean) {
                        return ((Boolean)o).booleanValue() ? "TRUE" : "FALSE";
index a750ed13f286737dea466d74a5ecb61c599532a8..d7827b137cfb2ba0e9d97dd4b5d5021316aab06a 100644 (file)
@@ -21,16 +21,15 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
 
-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.function.FunctionMetadata;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
 import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.util.AreaReference;
 import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.ss.util.CellReference.NameType;
-import org.apache.poi.ss.SpreadsheetVersion;
 
 /**
  * This class parses a formula string into a List of tokens in RPN order.
@@ -1205,7 +1204,7 @@ public final class FormulaParser {
        private Object parseArrayItem() {
                SkipWhite();
                switch(look) {
-                       case '"': return new UnicodeString(parseStringLiteral());
+                       case '"': return parseStringLiteral();
                        case '#': return ErrorConstant.valueOf(parseErrorLiteral());
                        case 'F': case 'f':
                        case 'T': case 't':
index cdf42e07f571227e9485040324b0d16f855bf538..5891831cba503ebf9720b8cc74704fbd97e3c485 100644 (file)
 
 package org.apache.poi.hssf.model;
 
+import java.util.Arrays;
+
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.UnicodeString;
 import org.apache.poi.hssf.record.constant.ErrorConstant;
 import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
 import org.apache.poi.hssf.record.formula.AddPtg;
@@ -71,6 +74,8 @@ import org.apache.poi.ss.formula.FormulaParser;
 import org.apache.poi.ss.formula.FormulaType;
 import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
 import org.apache.poi.ss.usermodel.Name;
+import org.apache.poi.util.HexRead;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
 
 /**
  * Test the low level formula parser functionality. High level tests are to
@@ -830,7 +835,7 @@ public final class TestFormulaParser extends TestCase {
                Ptg[] ptgs;
                ptgs = parseFormula("mode({1,2,2,#REF!;FALSE,3,3,2})");
                confirmTokenClasses(ptgs, ArrayPtg.class, FuncVarPtg.class);
-               assertEquals("{1.0,2.0,2.0,#REF!;FALSE,3.0,3.0,2.0}", ptgs[0].toFormulaString());
+               assertEquals("{1,2,2,#REF!;FALSE,3,3,2}", ptgs[0].toFormulaString());
 
                ArrayPtg aptg = (ArrayPtg) ptgs[0];
                Object[][] values = aptg.getTokenArrayValues();
@@ -838,6 +843,34 @@ public final class TestFormulaParser extends TestCase {
                assertEquals(Boolean.FALSE, values[1][0]);
        }
 
+       public void testParseStringElementInArray() {
+               Ptg[] ptgs;
+               ptgs = parseFormula("MAX({\"5\"},3)");
+               confirmTokenClasses(ptgs, ArrayPtg.class, IntPtg.class, FuncVarPtg.class);
+               Object element = ((ArrayPtg)ptgs[0]).getTokenArrayValues()[0][0];
+               if (element instanceof UnicodeString) {
+                       // this would cause ClassCastException below
+                       throw new AssertionFailedError("Wrong encoding of array element value");
+               }
+               assertEquals(String.class, element.getClass());
+
+               // make sure the formula encodes OK
+               int encSize = Ptg.getEncodedSize(ptgs);
+               byte[] data = new byte[encSize];
+               Ptg.serializePtgs(ptgs, data, 0);
+               byte[] expData = HexRead.readFromString(
+                               "20 00 00 00 00 00 00 00 " // tArray
+                               + "1E 03 00 "      // tInt(3)
+                               + "42 02 07 00 "   // tFuncVar(MAX) 2-arg
+                               + "00 00 00 "      // Array data: 1 col, 1 row
+                               + "02 01 00 00 35" // elem (type=string, len=1, "5")
+               );
+               assertTrue(Arrays.equals(expData, data));
+               int initSize = Ptg.getEncodedSizeWithoutArrayData(ptgs);
+               Ptg[] ptgs2 = Ptg.readTokens(initSize, new LittleEndianByteArrayInputStream(data));
+               confirmTokenClasses(ptgs2, ArrayPtg.class, IntPtg.class, FuncVarPtg.class);
+       }
+
        public void testRangeOperator() {
 
                HSSFWorkbook wb = new HSSFWorkbook();
index b7eed27dff80056f85a5f1762966066aff632689..3379cee2850a5a024b05e7d82a771b4de0450ce2 100644 (file)
@@ -106,12 +106,11 @@ public final class TestArrayPtg extends TestCase {
 
                // The formula has an array with 3 rows and 5 columns
                String formula = wb.getSheetAt(0).getRow(0).getCell(0).getCellFormula();
-               // TODO - These number literals should not have '.0'. Excel has different number rendering rules
 
-               if (formula.equals("SUM({1.0,6.0,11.0;2.0,7.0,12.0;3.0,8.0,13.0;4.0,9.0,14.0;5.0,10.0,15.0})")) {
+               if (formula.equals("SUM({1,6,11;2,7,12;3,8,13;4,9,14;5,10,15})")) {
                        throw new AssertionFailedError("Identified bug 42564 b");
                }
-               assertEquals("SUM({1.0,2.0,3.0,4.0,5.0;6.0,7.0,8.0,9.0,10.0;11.0,12.0,13.0,14.0,15.0})", formula);
+               assertEquals("SUM({1,2,3,4,5;6,7,8,9,10;11,12,13,14,15})", formula);
        }
 
        public void testToFormulaString() {
@@ -125,7 +124,7 @@ public final class TestArrayPtg extends TestCase {
                        }
                        throw e;
                }
-               assertEquals("{TRUE,\"ABCD\",\"E\";0.0,FALSE,\"FG\"}", actualFormula);
+               assertEquals("{TRUE,\"ABCD\",\"E\";0,FALSE,\"FG\"}", actualFormula);
        }
 
        /**