Changed FormulaRecord.getParsedExpression to return Ptg array

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690091 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-08-29 03:25:23 +00:00
parent 43a8618659
commit adff0508bb
7 changed files with 82 additions and 107 deletions

View File

@ -15,25 +15,21 @@
limitations under the License.
==================================================================== */
/*
* FormulaViewer.java - finds formulas in a BIFF8 file and attempts to parse them and
* display info about them.
*
* Created on November 18, 2001, 7:58 AM
*/
package org.apache.poi.hssf.dev;
import java.io.FileInputStream;
//import java.io.*;
import java.util.List;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.formula.*;
import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordFactory;
import org.apache.poi.hssf.record.formula.ExpPtg;
import org.apache.poi.hssf.record.formula.FuncPtg;
import org.apache.poi.hssf.record.formula.OperationPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.model.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
/**
* FormulaViewer - finds formulas in a BIFF8 file and attempts to read them/display
@ -87,20 +83,21 @@ public class FormulaViewer
private void listFormula(FormulaRecord record) {
String sep="~";
List tokens= record.getParsedExpression();
int numptgs = record.getNumberOfExpressionTokens();
Ptg token = null;
String name,numArg;
if (tokens != null) {
token = (Ptg) tokens.get(numptgs-1);
Ptg[] tokens= record.getParsedExpression();
Ptg token;
int numptgs = tokens.length;
String numArg;
token = tokens[numptgs-1];
if (token instanceof FuncPtg) {
numArg = String.valueOf(numptgs-1);
} else { numArg = String.valueOf(-1);}
} else {
numArg = String.valueOf(-1);
}
StringBuffer buf = new StringBuffer();
if (token instanceof ExpPtg) return;
buf.append(name=((OperationPtg) token).toFormulaString((HSSFWorkbook)null));
buf.append(((OperationPtg) token).toFormulaString((HSSFWorkbook)null));
buf.append(sep);
switch (token.getPtgClass()) {
case Ptg.CLASS_REF :
@ -116,7 +113,7 @@ public class FormulaViewer
buf.append(sep);
if (numptgs>1) {
token = (Ptg) tokens.get(numptgs-2);
token = tokens[numptgs-2];
switch (token.getPtgClass()) {
case Ptg.CLASS_REF :
buf.append("REF");
@ -134,9 +131,6 @@ public class FormulaViewer
buf.append(sep);
buf.append(numArg);
System.out.println(buf.toString());
} else {
System.out.println("#NAME");
}
}
/**
@ -155,20 +149,18 @@ public class FormulaViewer
System.out.println("value = " + record.getValue());
System.out.print("xf = " + record.getXFIndex());
System.out.print(", number of ptgs = "
+ record.getNumberOfExpressionTokens());
+ record.getParsedExpression().length);
System.out.println(", options = " + record.getOptions());
System.out.println("RPN List = "+formulaString(record));
System.out.println("Formula text = "+ composeFormula(record));
}
private String formulaString(FormulaRecord record) {
StringBuffer formula = new StringBuffer("=");
int numptgs = record.getNumberOfExpressionTokens();
List tokens = record.getParsedExpression();
Ptg token;
StringBuffer buf = new StringBuffer();
for (int i=0;i<numptgs;i++) {
token = (Ptg) tokens.get(i);
Ptg[] tokens = record.getParsedExpression();
for (int i = 0; i < tokens.length; i++) {
Ptg token = tokens[i];
buf.append( token.toFormulaString((HSSFWorkbook)null));
switch (token.getPtgClass()) {
case Ptg.CLASS_REF :
@ -187,9 +179,9 @@ public class FormulaViewer
}
private String composeFormula(FormulaRecord record)
private static String composeFormula(FormulaRecord record)
{
return org.apache.poi.hssf.model.FormulaParser.toFormulaString((HSSFWorkbook)null,record.getParsedExpression());
return FormulaParser.toFormulaString((HSSFWorkbook)null, record.getParsedExpression());
}
/**

View File

@ -180,18 +180,10 @@ public final class FormulaRecord extends Record implements CellValueRecordInterf
}
/**
* get the size of the stack
* @return size of the stack
* @return the formula tokens. never <code>null</code>
*/
public int getNumberOfExpressionTokens() {
return field_8_parsed_expr.length;
}
/**
* @return list of formula tokens. never <code>null</code>
*/
public List getParsedExpression() {
return Arrays.asList(field_8_parsed_expr); // TODO - return array
public Ptg[] getParsedExpression() {
return (Ptg[]) field_8_parsed_expr.clone();
}
public void setParsedExpression(Ptg[] ptgs) {

View File

@ -29,6 +29,7 @@ import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.model.Workbook;
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.HSSFWorkbook;
import org.apache.poi.hssf.util.SheetReferences;
@ -56,13 +57,13 @@ public final class TestEventWorkbookBuilder extends TestCase {
}
}
public void testBasics() throws Exception {
public void testBasics() {
assertNotNull(listener.getSSTRecord());
assertNotNull(listener.getBoundSheetRecords());
assertNotNull(listener.getExternSheetRecords());
}
public void testGetStubWorkbooks() throws Exception {
public void testGetStubWorkbooks() {
assertNotNull(listener.getStubWorkbook());
assertNotNull(listener.getStubHSSFWorkbook());
@ -70,7 +71,7 @@ public final class TestEventWorkbookBuilder extends TestCase {
assertNotNull(listener.getStubHSSFWorkbook().getSheetReferences());
}
public void testContents() throws Exception {
public void testContents() {
assertEquals(2, listener.getSSTRecord().getNumStrings());
assertEquals(3, listener.getBoundSheetRecords().length);
assertEquals(1, listener.getExternSheetRecords().length);
@ -83,11 +84,12 @@ public final class TestEventWorkbookBuilder extends TestCase {
assertEquals("S2", ref.getSheetName(2));
}
public void testFormulas() throws Exception {
FormulaRecord fr;
public void testFormulas() {
FormulaRecord[] fRecs = mockListen.getFormulaRecords();
// Check our formula records
assertEquals(6, mockListen._frecs.size());
assertEquals(6, fRecs.length);
Workbook stubWB = listener.getStubWorkbook();
assertNotNull(stubWB);
@ -100,47 +102,45 @@ public final class TestEventWorkbookBuilder extends TestCase {
assertEquals("Sh3", stubWB.getSheetName(2));
// Check we can get the formula without breaking
for(int i=0; i<mockListen._frecs.size(); i++) {
fr = (FormulaRecord)mockListen._frecs.get(i);
FormulaParser.toFormulaString(stubHSSF, fr.getParsedExpression());
for(int i=0; i<fRecs.length; i++) {
FormulaParser.toFormulaString(stubHSSF, fRecs[i].getParsedExpression());
}
// Peer into just one formula, and check that
// all the ptgs give back the right things
List ptgs = ((FormulaRecord)mockListen._frecs.get(0)).getParsedExpression();
assertEquals(1, ptgs.size());
assertTrue(ptgs.get(0) instanceof Ref3DPtg);
Ptg[] ptgs = fRecs[0].getParsedExpression();
assertEquals(1, ptgs.length);
assertTrue(ptgs[0] instanceof Ref3DPtg);
Ref3DPtg ptg = (Ref3DPtg)ptgs.get(0);
Ref3DPtg ptg = (Ref3DPtg)ptgs[0];
assertEquals("Sheet1!A1", ptg.toFormulaString(stubHSSF));
// Now check we get the right formula back for
// a few sample ones
FormulaRecord fr;
// Sheet 1 A2 is on same sheet
fr = (FormulaRecord)mockListen._frecs.get(0);
fr = fRecs[0];
assertEquals(1, fr.getRow());
assertEquals(0, fr.getColumn());
assertEquals("Sheet1!A1", FormulaParser.toFormulaString(stubHSSF, fr.getParsedExpression()));
// Sheet 1 A5 is to another sheet
fr = (FormulaRecord)mockListen._frecs.get(3);
fr = fRecs[3];
assertEquals(4, fr.getRow());
assertEquals(0, fr.getColumn());
assertEquals("'S2'!A1", FormulaParser.toFormulaString(stubHSSF, fr.getParsedExpression()));
// Sheet 1 A7 is to another sheet, range
fr = (FormulaRecord)mockListen._frecs.get(5);
fr = fRecs[5];
assertEquals(6, fr.getRow());
assertEquals(0, fr.getColumn());
assertEquals("SUM(Sh3!A1:A4)", FormulaParser.toFormulaString(stubHSSF, fr.getParsedExpression()));
// Now, load via Usermodel and re-check
InputStream is = HSSFTestDataSamples.openSampleFileStream("3dFormulas.xls");
POIFSFileSystem fs = new POIFSFileSystem(is);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("3dFormulas.xls");
assertEquals("Sheet1!A1", wb.getSheetAt(0).getRow(1).getCell(0).getCellFormula());
assertEquals("SUM(Sh3!A1:A4)", wb.getSheetAt(0).getRow(6).getCell(0).getCellFormula());
}
@ -156,5 +156,10 @@ public final class TestEventWorkbookBuilder extends TestCase {
_frecs.add(record);
}
}
public FormulaRecord[] getFormulaRecords() {
FormulaRecord[] result = new FormulaRecord[_frecs.size()];
_frecs.toArray(result);
return result;
}
}
}

View File

@ -17,15 +17,14 @@
package org.apache.poi.hssf.record;
import java.io.ByteArrayInputStream;
import java.util.List;
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.AttrPtg;
import org.apache.poi.hssf.record.formula.FuncVarPtg;
import org.apache.poi.hssf.record.formula.IntPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.RefPtg;
/**
@ -39,14 +38,12 @@ public final class TestFormulaRecord extends TestCase {
public void testCreateFormulaRecord () {
FormulaRecord record = new FormulaRecord();
record.setColumn((short)0);
//record.setRow((short)1);
record.setRow(1);
record.setXFIndex((short)4);
assertEquals(record.getColumn(),(short)0);
//assertEquals(record.getRow(),(short)1);
assertEquals((short)record.getRow(),(short)1);
assertEquals(record.getXFIndex(),(short)4);
assertEquals(record.getColumn(),0);
assertEquals(record.getRow(), 1);
assertEquals(record.getXFIndex(),4);
}
/**
@ -103,7 +100,7 @@ public final class TestFormulaRecord extends TestCase {
assertEquals("Offset 22", 1, output[26]);
}
public void testWithConcat() throws Exception {
public void testWithConcat() {
// =CHOOSE(2,A2,A3,A4)
byte[] data = {
6, 0, 68, 0,
@ -126,23 +123,19 @@ public final class TestFormulaRecord extends TestCase {
FormulaRecord fr = new FormulaRecord(inp);
List ptgs = fr.getParsedExpression();
assertEquals(9, ptgs.size());
assertEquals(IntPtg.class, ptgs.get(0).getClass());
assertEquals(AttrPtg.class, ptgs.get(1).getClass());
assertEquals(RefPtg.class, ptgs.get(2).getClass());
assertEquals(AttrPtg.class, ptgs.get(3).getClass());
assertEquals(RefPtg.class, ptgs.get(4).getClass());
assertEquals(AttrPtg.class, ptgs.get(5).getClass());
assertEquals(RefPtg.class, ptgs.get(6).getClass());
assertEquals(AttrPtg.class, ptgs.get(7).getClass());
assertEquals(FuncVarPtg.class, ptgs.get(8).getClass());
Ptg[] ptgs = fr.getParsedExpression();
assertEquals(9, ptgs.length);
assertEquals(IntPtg.class, ptgs[0].getClass());
assertEquals(AttrPtg.class, ptgs[1].getClass());
assertEquals(RefPtg.class, ptgs[2].getClass());
assertEquals(AttrPtg.class, ptgs[3].getClass());
assertEquals(RefPtg.class, ptgs[4].getClass());
assertEquals(AttrPtg.class, ptgs[5].getClass());
assertEquals(RefPtg.class, ptgs[6].getClass());
assertEquals(AttrPtg.class, ptgs[7].getClass());
assertEquals(FuncVarPtg.class, ptgs[8].getClass());
FuncVarPtg choose = (FuncVarPtg)ptgs.get(8);
FuncVarPtg choose = (FuncVarPtg)ptgs[8];
assertEquals("CHOOSE", choose.getName());
}
public static void main(String [] ignored_args) {
junit.textui.TestRunner.run(TestFormulaRecord.class);
}
}

View File

@ -17,8 +17,6 @@
package org.apache.poi.hssf.usermodel;
import java.util.List;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.Ptg;
@ -40,10 +38,6 @@ public final class FormulaExtractor {
throw new IllegalArgumentException("Not a formula cell");
}
FormulaRecordAggregate fra = (FormulaRecordAggregate) vr;
List tokens = fra.getFormulaRecord().getParsedExpression();
Ptg[] result = new Ptg[tokens.size()];
tokens.toArray(result);
return result;
return fra.getFormulaRecord().getParsedExpression();
}
}

View File

@ -18,13 +18,13 @@
package org.apache.poi.hssf.usermodel;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue;
import org.apache.poi.hssf.util.CellReference;
@ -65,15 +65,14 @@ public final class TestBug42464 extends TestCase {
}
FormulaRecordAggregate record = (FormulaRecordAggregate) cell.getCellValueRecord();
FormulaRecord r = record.getFormulaRecord();
List ptgs = r.getParsedExpression();
Ptg[] ptgs = r.getParsedExpression();
String cellRef = new CellReference(row.getRowNum(), cell.getCellNum(), false, false).formatAsString();
if(false && cellRef.equals("BP24")) { // TODO - replace System.out.println()s with asserts
System.out.print(cellRef);
System.out.println(" - has " + r.getNumberOfExpressionTokens()
+ " ptgs:");
for(int i=0; i<ptgs.size(); i++) {
String c = ptgs.get(i).getClass().toString();
System.out.println(" - has " + ptgs.length + " ptgs:");
for(int i=0; i<ptgs.length; i++) {
String c = ptgs[i].getClass().toString();
System.out.println("\t" + c.substring(c.lastIndexOf('.')+1) );
}
System.out.println("-> " + cell.getCellFormula());

View File

@ -20,7 +20,6 @@ package org.apache.poi.hssf.usermodel;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
@ -29,6 +28,7 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.AreaPtg;
import org.apache.poi.hssf.record.formula.FuncVarPtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
*
@ -183,14 +183,14 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
HSSFCell cellSUM = rowSUM.getCell(0);
FormulaRecordAggregate frec = (FormulaRecordAggregate) cellSUM.getCellValueRecord();
List ops = frec.getFormulaRecord().getParsedExpression();
assertEquals(2, ops.size());
assertEquals(AreaPtg.class, ops.get(0).getClass());
assertEquals(FuncVarPtg.class, ops.get(1).getClass());
Ptg[] ops = frec.getFormulaRecord().getParsedExpression();
assertEquals(2, ops.length);
assertEquals(AreaPtg.class, ops[0].getClass());
assertEquals(FuncVarPtg.class, ops[1].getClass());
// Actually stored as C1 to C65536
// (last row is -1 === 65535)
AreaPtg ptg = (AreaPtg) ops.get(0);
AreaPtg ptg = (AreaPtg) ops[0];
assertEquals(2, ptg.getFirstColumn());
assertEquals(2, ptg.getLastColumn());
assertEquals(0, ptg.getFirstRow());