Patch 48284 - raise visibility of FormulaParseException
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@885007 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c73dd9d324
commit
5c7dbb2730
@ -20,6 +20,7 @@ package org.apache.poi.hssf.model;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.formula.FormulaParseException;
|
||||
import org.apache.poi.ss.formula.FormulaParser;
|
||||
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
|
||||
import org.apache.poi.ss.formula.FormulaRenderer;
|
||||
@ -41,17 +42,18 @@ public final class HSSFFormulaParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, int)}
|
||||
* Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, int, int)}
|
||||
*/
|
||||
public static Ptg[] parse(String formula, HSSFWorkbook workbook) {
|
||||
public static Ptg[] parse(String formula, HSSFWorkbook workbook) throws FormulaParseException {
|
||||
return parse(formula, workbook, FormulaType.CELL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param formulaType a constant from {@link FormulaType}
|
||||
* @return the parsed formula tokens
|
||||
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
|
||||
*/
|
||||
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) {
|
||||
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) throws FormulaParseException {
|
||||
return parse(formula, workbook, formulaType, -1);
|
||||
}
|
||||
|
||||
@ -64,8 +66,9 @@ public final class HSSFFormulaParser {
|
||||
* the scope of the name will be ignored and the parser will match named ranges only by name
|
||||
*
|
||||
* @return the parsed formula tokens
|
||||
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
|
||||
*/
|
||||
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) {
|
||||
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) throws FormulaParseException {
|
||||
return FormulaParser.parse(formula, createParsingWorkbook(workbook), formulaType, sheetIndex);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class HSSFCell implements Cell {
|
||||
*/
|
||||
public static final int LAST_COLUMN_NUMBER = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); // 2^8 - 1
|
||||
private static final String LAST_COLUMN_NAME = SpreadsheetVersion.EXCEL97.getLastColumnName();
|
||||
|
||||
|
||||
public final static short ENCODING_UNCHANGED = -1;
|
||||
public final static short ENCODING_COMPRESSED_UNICODE = 0;
|
||||
public final static short ENCODING_UTF_16 = 1;
|
||||
@ -507,7 +507,7 @@ public class HSSFCell implements Cell {
|
||||
}
|
||||
|
||||
/**
|
||||
* set a string value for the cell.
|
||||
* set a string value for the cell.
|
||||
*
|
||||
* @param value value to set the cell to. For formulas we'll set the formula
|
||||
* cached string result, for String cells we'll set its value. For other types we will
|
||||
@ -573,17 +573,6 @@ public class HSSFCell implements Cell {
|
||||
_stringValue.setUnicodeString(_book.getWorkbook().getSSTString(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets formula for this cell.
|
||||
* <p>
|
||||
* Note, this method only sets the formula string and does not calculate the formula value.
|
||||
* To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)}
|
||||
* </p>
|
||||
*
|
||||
* @param formula the formula to set, e.g. <code>SUM(C4:E4)</code>.
|
||||
* If the argument is <code>null</code> then the current formula is removed.
|
||||
* @throws IllegalArgumentException if the formula is unparsable
|
||||
*/
|
||||
public void setCellFormula(String formula) {
|
||||
int row=_record.getRow();
|
||||
short col=_record.getColumn();
|
||||
@ -918,8 +907,8 @@ public class HSSFCell implements Cell {
|
||||
*/
|
||||
private static void checkBounds(int cellIndex) {
|
||||
if (cellIndex < 0 || cellIndex > LAST_COLUMN_NUMBER) {
|
||||
throw new IllegalArgumentException("Invalid column index (" + cellIndex
|
||||
+ "). Allowable column range for " + FILE_FORMAT_NAME + " is (0.."
|
||||
throw new IllegalArgumentException("Invalid column index (" + cellIndex
|
||||
+ "). Allowable column range for " + FILE_FORMAT_NAME + " is (0.."
|
||||
+ LAST_COLUMN_NUMBER + ") or ('A'..'" + LAST_COLUMN_NAME + "')");
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import org.apache.poi.ss.formula.EvaluationCell;
|
||||
import org.apache.poi.ss.formula.EvaluationName;
|
||||
import org.apache.poi.ss.formula.EvaluationSheet;
|
||||
import org.apache.poi.ss.formula.EvaluationWorkbook;
|
||||
import org.apache.poi.ss.formula.FormulaParseException;
|
||||
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
import org.apache.poi.ss.formula.FormulaType;
|
||||
@ -129,7 +130,7 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||
// to make sure that all formulas POI can evaluate can also be parsed.
|
||||
try {
|
||||
return HSSFFormulaParser.parse(cell.getCellFormula(), _uBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
|
||||
} catch (RuntimeException e) {
|
||||
} catch (FormulaParseException e) {
|
||||
// Note - as of Bugzilla 48036 (svn r828244, r828247) POI is capable of evaluating
|
||||
// IntesectionPtg. However it is still not capable of parsing it.
|
||||
// So FormulaEvalTestData.xls now contains a few formulas that produce errors here.
|
||||
|
@ -0,0 +1,33 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
/**
|
||||
* This exception thrown when a supplied formula has incorrect syntax (or syntax currently not
|
||||
* supported by POI). It is primarily used by test code to confirm specific parsing exceptions.
|
||||
* Application code should also handle this exception if it potentially supplies formula text
|
||||
* that is not guaranteed to be well-formed.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class FormulaParseException extends RuntimeException {
|
||||
|
||||
FormulaParseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ 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.ValueOperatorPtg;
|
||||
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;
|
||||
@ -42,6 +41,10 @@ import org.apache.poi.ss.SpreadsheetVersion;
|
||||
* <term> ::= <factor> [ <mulop> <factor> ]*
|
||||
* <factor> ::= <number> | (<expression>) | <cellRef> | <function>
|
||||
* <function> ::= <functionName> ([expression [, expression]*])
|
||||
* <p/>
|
||||
* For POI internal use only
|
||||
* <p/>
|
||||
*
|
||||
*
|
||||
* @author Avik Sengupta <avik at apache dot org>
|
||||
* @author Andrew C. oliver (acoliver at apache dot org)
|
||||
@ -111,20 +114,6 @@ public final class FormulaParser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific exception thrown when a supplied formula does not parse properly.<br/>
|
||||
* Primarily used by test cases when testing for specific parsing exceptions.</p>
|
||||
*
|
||||
*/
|
||||
static final class FormulaParseException extends RuntimeException {
|
||||
// This class was given package scope until it would become clear that it is useful to
|
||||
// general client code.
|
||||
public FormulaParseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final String _formulaString;
|
||||
private final int _formulaLength;
|
||||
/** points at the next character to be read (after the {@link #look} char) */
|
||||
@ -141,7 +130,7 @@ public final class FormulaParser {
|
||||
private char look;
|
||||
|
||||
private FormulaParsingWorkbook _book;
|
||||
private SpreadsheetVersion _ssVersion;
|
||||
private SpreadsheetVersion _ssVersion;
|
||||
|
||||
private int _sheetIndex;
|
||||
|
||||
@ -162,19 +151,11 @@ public final class FormulaParser {
|
||||
_formulaString = formula;
|
||||
_pointer=0;
|
||||
_book = book;
|
||||
_ssVersion = book == null ? SpreadsheetVersion.EXCEL97 : book.getSpreadsheetVersion();
|
||||
_formulaLength = _formulaString.length();
|
||||
_ssVersion = book == null ? SpreadsheetVersion.EXCEL97 : book.getSpreadsheetVersion();
|
||||
_formulaLength = _formulaString.length();
|
||||
_sheetIndex = sheetIndex;
|
||||
}
|
||||
|
||||
public static Ptg[] parse(String formula, FormulaParsingWorkbook book) {
|
||||
return parse(formula, book, FormulaType.CELL);
|
||||
}
|
||||
|
||||
public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, int formulaType) {
|
||||
return parse(formula, workbook, formulaType, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a formula into a array of tokens
|
||||
*
|
||||
@ -186,7 +167,7 @@ public final class FormulaParser {
|
||||
* the scope of the name will be ignored and the parser will match names only by name
|
||||
*
|
||||
* @return array of parsed tokens
|
||||
* @throws FormulaParseException if the formula is unparsable
|
||||
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
|
||||
*/
|
||||
public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, int formulaType, int sheetIndex) {
|
||||
FormulaParser fp = new FormulaParser(formula, workbook, sheetIndex);
|
||||
@ -702,7 +683,7 @@ public final class FormulaParser {
|
||||
if (!isValidCellReference(rep)) {
|
||||
return null;
|
||||
}
|
||||
} else if (hasLetters) {
|
||||
} else if (hasLetters) {
|
||||
if (!CellReference.isColumnWithnRange(rep.replace("$", ""), _ssVersion)) {
|
||||
return null;
|
||||
}
|
||||
@ -881,29 +862,29 @@ public final class FormulaParser {
|
||||
* @return <code>true</code> if the specified name is a valid cell reference
|
||||
*/
|
||||
private boolean isValidCellReference(String str) {
|
||||
//check range bounds against grid max
|
||||
boolean result = CellReference.classifyCellReference(str, _ssVersion) == NameType.CELL;
|
||||
//check range bounds against grid max
|
||||
boolean result = CellReference.classifyCellReference(str, _ssVersion) == NameType.CELL;
|
||||
|
||||
if(result){
|
||||
/**
|
||||
* Check if the argument is a function. Certain names can be either a cell reference or a function name
|
||||
* depending on the contenxt. Compare the following examples in Excel 2007:
|
||||
* (a) LOG10(100) + 1
|
||||
* (b) LOG10 + 1
|
||||
* In (a) LOG10 is a name of a built-in function. In (b) LOG10 is a cell reference
|
||||
*/
|
||||
boolean isFunc = FunctionMetadataRegistry.getFunctionByName(str.toUpperCase()) != null;
|
||||
if(isFunc){
|
||||
int savePointer = _pointer;
|
||||
resetPointer(_pointer + str.length());
|
||||
SkipWhite();
|
||||
// open bracket indicates that the argument is a function,
|
||||
// the returning value should be false, i.e. "not a valid cell reference"
|
||||
result = look != '(';
|
||||
resetPointer(savePointer);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if(result){
|
||||
/**
|
||||
* Check if the argument is a function. Certain names can be either a cell reference or a function name
|
||||
* depending on the contenxt. Compare the following examples in Excel 2007:
|
||||
* (a) LOG10(100) + 1
|
||||
* (b) LOG10 + 1
|
||||
* In (a) LOG10 is a name of a built-in function. In (b) LOG10 is a cell reference
|
||||
*/
|
||||
boolean isFunc = FunctionMetadataRegistry.getFunctionByName(str.toUpperCase()) != null;
|
||||
if(isFunc){
|
||||
int savePointer = _pointer;
|
||||
resetPointer(_pointer + str.length());
|
||||
SkipWhite();
|
||||
// open bracket indicates that the argument is a function,
|
||||
// the returning value should be false, i.e. "not a valid cell reference"
|
||||
result = look != '(';
|
||||
resetPointer(savePointer);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,6 +20,8 @@ package org.apache.poi.ss.usermodel;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.poi.ss.formula.FormulaParseException;
|
||||
|
||||
/**
|
||||
* High level representation of a cell in a row of a spreadsheet.
|
||||
* <p>
|
||||
@ -76,7 +78,7 @@ public interface Cell {
|
||||
* @see #getCellType()
|
||||
*/
|
||||
public final static int CELL_TYPE_ERROR = 5;
|
||||
|
||||
|
||||
/**
|
||||
* Returns column index of this cell
|
||||
*
|
||||
@ -158,7 +160,7 @@ public interface Cell {
|
||||
* data type is now something besides {@link Cell#CELL_TYPE_NUMERIC}. POI
|
||||
* does not attempt to replicate this behaviour. To make a numeric cell
|
||||
* display as a date, use {@link #setCellStyle(CellStyle)} etc.
|
||||
*
|
||||
*
|
||||
* @param value the numeric value to set this cell to. For formulas we'll set the
|
||||
* precalculated value, for numerics we'll set its value. For other types we
|
||||
* will change the cell to a numerics cell and set its value.
|
||||
@ -203,6 +205,7 @@ public interface Cell {
|
||||
*/
|
||||
void setCellValue(String value);
|
||||
|
||||
|
||||
/**
|
||||
* Sets formula for this cell.
|
||||
* <p>
|
||||
@ -210,11 +213,11 @@ public interface Cell {
|
||||
* To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)}
|
||||
* </p>
|
||||
*
|
||||
* @param formula the formula to set, e.g. <code>SUM(C4:E4)</code>.
|
||||
* @param formula the formula to set, e.g. <code>"SUM(C4:E4)"</code>.
|
||||
* If the argument is <code>null</code> then the current formula is removed.
|
||||
* @throws IllegalArgumentException if the formula is unparsable
|
||||
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
|
||||
*/
|
||||
void setCellFormula(String formula);
|
||||
void setCellFormula(String formula) throws FormulaParseException;
|
||||
|
||||
/**
|
||||
* Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
|
||||
|
@ -362,17 +362,6 @@ public final class XSSFCell implements Cell {
|
||||
return FormulaRenderer.toFormulaString(fpb, fmla);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets formula for this cell.
|
||||
* <p>
|
||||
* Note, this method only sets the formula string and does not calculate the formula value.
|
||||
* To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)}
|
||||
* </p>
|
||||
*
|
||||
* @param formula the formula to set, e.g. <code>SUM(C4:E4)</code>.
|
||||
* If the argument is <code>null</code> then the current formula is removed.
|
||||
* @throws IllegalArgumentException if the formula is invalid
|
||||
*/
|
||||
public void setCellFormula(String formula) {
|
||||
XSSFWorkbook wb = _row.getSheet().getWorkbook();
|
||||
if (formula == null) {
|
||||
|
@ -23,55 +23,53 @@ import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||
import org.apache.poi.hssf.record.formula.IntPtg;
|
||||
import org.apache.poi.hssf.record.formula.FuncPtg;
|
||||
import org.apache.poi.ss.formula.FormulaParseException;
|
||||
import org.apache.poi.ss.formula.FormulaParser;
|
||||
import org.apache.poi.ss.formula.FormulaType;
|
||||
|
||||
public final class TestXSSFFormulaParser extends TestCase {
|
||||
|
||||
private static Ptg[] parse(XSSFEvaluationWorkbook fpb, String fmla) {
|
||||
return FormulaParser.parse(fmla, fpb, FormulaType.CELL, -1);
|
||||
}
|
||||
|
||||
|
||||
public void testParse() {
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
|
||||
String fmla;
|
||||
Ptg[] ptgs;
|
||||
|
||||
fmla = "ABC10";
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "ABC10");
|
||||
assertEquals(1, ptgs.length);
|
||||
assertTrue("",(ptgs[0] instanceof RefPtg));
|
||||
assertTrue("", ptgs[0] instanceof RefPtg);
|
||||
|
||||
fmla = "A500000";
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "A500000");
|
||||
assertEquals(1, ptgs.length);
|
||||
assertTrue("",(ptgs[0] instanceof RefPtg));
|
||||
assertTrue("", ptgs[0] instanceof RefPtg);
|
||||
|
||||
fmla = "ABC500000";
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "ABC500000");
|
||||
assertEquals(1, ptgs.length);
|
||||
assertTrue("",(ptgs[0] instanceof RefPtg));
|
||||
assertTrue("", ptgs[0] instanceof RefPtg);
|
||||
|
||||
//highest allowed rows and column (XFD and 0x100000)
|
||||
fmla = "XFD1048576";
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "XFD1048576");
|
||||
assertEquals(1, ptgs.length);
|
||||
assertTrue("",(ptgs[0] instanceof RefPtg));
|
||||
assertTrue("", ptgs[0] instanceof RefPtg);
|
||||
|
||||
|
||||
//column greater than XFD
|
||||
fmla = "XFE10";
|
||||
try {
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "XFE10");
|
||||
fail("expected exception");
|
||||
} catch (Exception e){
|
||||
} catch (FormulaParseException e){
|
||||
assertEquals("Specified named range 'XFE10' does not exist in the current workbook.", e.getMessage());
|
||||
}
|
||||
|
||||
//row greater than 0x100000
|
||||
fmla = "XFD1048577";
|
||||
try {
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "XFD1048577");
|
||||
fail("expected exception");
|
||||
} catch (Exception e){
|
||||
} catch (FormulaParseException e){
|
||||
assertEquals("Specified named range 'XFD1048577' does not exist in the current workbook.", e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -79,19 +77,15 @@ public final class TestXSSFFormulaParser extends TestCase {
|
||||
public void testBuiltInFormulas() {
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
|
||||
String fmla;
|
||||
Ptg[] ptgs;
|
||||
|
||||
fmla = "LOG10";
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "LOG10");
|
||||
assertEquals(1, ptgs.length);
|
||||
assertTrue("",(ptgs[0] instanceof RefPtg));
|
||||
|
||||
fmla = "LOG10(100)";
|
||||
ptgs = FormulaParser.parse(fmla, fpb, FormulaType.CELL);
|
||||
ptgs = parse(fpb, "LOG10(100)");
|
||||
assertEquals(2, ptgs.length);
|
||||
assertTrue("",(ptgs[0] instanceof IntPtg));
|
||||
assertTrue("",(ptgs[1] instanceof FuncPtg));
|
||||
|
||||
assertTrue("", ptgs[0] instanceof IntPtg);
|
||||
assertTrue("", ptgs[1] instanceof FuncPtg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,8 +65,9 @@ import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.TestHSSFName;
|
||||
import org.apache.poi.ss.formula.FormulaParseException;
|
||||
import org.apache.poi.ss.formula.FormulaParser;
|
||||
import org.apache.poi.ss.formula.FormulaParserTestHelper;
|
||||
import org.apache.poi.ss.formula.FormulaType;
|
||||
import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
|
||||
import org.apache.poi.ss.usermodel.Name;
|
||||
|
||||
@ -684,9 +685,9 @@ public final class TestFormulaParser extends TestCase {
|
||||
try {
|
||||
parseFormula(formula);
|
||||
throw new AssertionFailedError("expected parse exception");
|
||||
} catch (RuntimeException e) {
|
||||
} catch (FormulaParseException e) {
|
||||
// expected during successful test
|
||||
FormulaParserTestHelper.confirmParseException(e);
|
||||
assertNotNull(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -782,8 +783,8 @@ public final class TestFormulaParser extends TestCase {
|
||||
try {
|
||||
HSSFFormulaParser.parse(formula, book);
|
||||
throw new AssertionFailedError("Didn't get parse exception as expected");
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e, expectedMessage);
|
||||
} catch (FormulaParseException e) {
|
||||
confirmParseException(e, expectedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -792,16 +793,16 @@ public final class TestFormulaParser extends TestCase {
|
||||
try {
|
||||
parseFormula("round(3.14;2)");
|
||||
throw new AssertionFailedError("Didn't get parse exception as expected");
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e,
|
||||
} catch (FormulaParseException e) {
|
||||
confirmParseException(e,
|
||||
"Parse error near char 10 ';' in specified formula 'round(3.14;2)'. Expected ',' or ')'");
|
||||
}
|
||||
|
||||
try {
|
||||
parseFormula(" =2+2");
|
||||
throw new AssertionFailedError("Didn't get parse exception as expected");
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e,
|
||||
} catch (FormulaParseException e) {
|
||||
confirmParseException(e,
|
||||
"The specified formula ' =2+2' starts with an equals sign which is not allowed.");
|
||||
}
|
||||
}
|
||||
@ -853,8 +854,8 @@ public final class TestFormulaParser extends TestCase {
|
||||
try {
|
||||
cell.setCellFormula("count(pf1)");
|
||||
throw new AssertionFailedError("Expected formula parse execption");
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e,
|
||||
} catch (FormulaParseException e) {
|
||||
confirmParseException(e,
|
||||
"Specified named range 'pf1' does not exist in the current workbook.");
|
||||
}
|
||||
cell.setCellFormula("count(fp1)"); // plain cell ref, col is in range
|
||||
@ -962,7 +963,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
String formula = "Sheet1!$B$2:$C$3,OFFSET(Sheet1!$E$2:$E$4,1,Sheet1!$A$1),Sheet1!$D$6";
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
wb.createSheet("Sheet1");
|
||||
Ptg[] ptgs = FormulaParser.parse(formula, HSSFEvaluationWorkbook.create(wb));
|
||||
Ptg[] ptgs = FormulaParser.parse(formula, HSSFEvaluationWorkbook.create(wb), FormulaType.CELL, -1);
|
||||
|
||||
Class<?>[] expectedClasses = {
|
||||
// TODO - AttrPtg.class, // Excel prepends this
|
||||
@ -985,7 +986,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
String formula = "Sheet1!A1:Sheet1!B3";
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
wb.createSheet("Sheet1");
|
||||
Ptg[] ptgs = FormulaParser.parse(formula, HSSFEvaluationWorkbook.create(wb));
|
||||
Ptg[] ptgs = FormulaParser.parse(formula, HSSFEvaluationWorkbook.create(wb), FormulaType.CELL, -1);
|
||||
|
||||
if (ptgs.length == 3) {
|
||||
confirmTokenClasses(ptgs, new Class[] { Ref3DPtg.class, Ref3DPtg.class, RangePtg.class,});
|
||||
@ -1195,8 +1196,8 @@ public final class TestFormulaParser extends TestCase {
|
||||
try {
|
||||
HSSFFormulaParser.parse(formula, wb);
|
||||
throw new AssertionFailedError("Expected formula parse execption");
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e, expectedMessage);
|
||||
} catch (FormulaParseException e) {
|
||||
confirmParseException(e, expectedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1220,8 +1221,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
Ptg[] result;
|
||||
try {
|
||||
result = HSSFFormulaParser.parse("1+foo", wb);
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e);
|
||||
} catch (FormulaParseException e) {
|
||||
if (e.getMessage().equals("Specified name 'foo' is not a range as expected.")) {
|
||||
throw new AssertionFailedError("Identified bug 47078c");
|
||||
}
|
||||
@ -1247,9 +1247,9 @@ public final class TestFormulaParser extends TestCase {
|
||||
HSSFFormulaParser.parse(badCellRef, wb);
|
||||
throw new AssertionFailedError("Identified bug 47312b - Shouldn't be able to parse cell ref '"
|
||||
+ badCellRef + "'.");
|
||||
} catch (RuntimeException e) {
|
||||
} catch (FormulaParseException e) {
|
||||
// expected during successful test
|
||||
FormulaParserTestHelper.confirmParseException(e, "Specified named range '"
|
||||
confirmParseException(e, "Specified named range '"
|
||||
+ badCellRef + "' does not exist in the current workbook.");
|
||||
}
|
||||
|
||||
@ -1257,8 +1257,8 @@ public final class TestFormulaParser extends TestCase {
|
||||
try {
|
||||
ptgs = HSSFFormulaParser.parse(leadingZeroCellRef, wb);
|
||||
assertEquals("B1", ((RefPtg) ptgs[0]).toFormulaString());
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e, "Specified named range '"
|
||||
} catch (FormulaParseException e) {
|
||||
confirmParseException(e, "Specified named range '"
|
||||
+ leadingZeroCellRef + "' does not exist in the current workbook.");
|
||||
// close but no cigar
|
||||
throw new AssertionFailedError("Identified bug 47312c - '"
|
||||
@ -1272,4 +1272,8 @@ public final class TestFormulaParser extends TestCase {
|
||||
ptgs = HSSFFormulaParser.parse("B0", wb);
|
||||
assertEquals(NamePtg.class, ptgs[0].getClass());
|
||||
}
|
||||
|
||||
private static void confirmParseException(FormulaParseException e, String expMsg) {
|
||||
assertEquals(expMsg, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -29,12 +29,12 @@ import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.formula.FormulaParserTestHelper;
|
||||
import org.apache.poi.ss.formula.FormulaParseException;
|
||||
import org.apache.poi.ss.usermodel.CellValue;
|
||||
|
||||
/**
|
||||
* Test the low level formula parser functionality,
|
||||
* but using parts which need to use
|
||||
* but using parts which need to use
|
||||
* HSSFFormulaEvaluator.
|
||||
*/
|
||||
public final class TestFormulaParserEval extends TestCase {
|
||||
@ -56,11 +56,11 @@ public final class TestFormulaParserEval extends TestCase {
|
||||
// Now make it a single cell
|
||||
name.setRefersToFormula("C3");
|
||||
confirmParseFormula(workbook);
|
||||
|
||||
|
||||
// And make it non-contiguous
|
||||
// using area unions
|
||||
name.setRefersToFormula("A1:A2,C3");
|
||||
|
||||
|
||||
confirmParseFormula(workbook);
|
||||
}
|
||||
|
||||
@ -75,11 +75,11 @@ public final class TestFormulaParserEval extends TestCase {
|
||||
}
|
||||
|
||||
public void testEvaluateFormulaWithRowBeyond32768_Bug44539() {
|
||||
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
wb.setSheetName(0, "Sheet1");
|
||||
|
||||
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
HSSFCell cell = row.createCell(0);
|
||||
cell.setCellFormula("SUM(A32769:A32770)");
|
||||
@ -87,13 +87,12 @@ public final class TestFormulaParserEval extends TestCase {
|
||||
// put some values in the cells to make the evaluation more interesting
|
||||
sheet.createRow(32768).createCell(0).setCellValue(31);
|
||||
sheet.createRow(32769).createCell(0).setCellValue(11);
|
||||
|
||||
|
||||
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
|
||||
CellValue result;
|
||||
try {
|
||||
result = fe.evaluate(cell);
|
||||
} catch (RuntimeException e) {
|
||||
FormulaParserTestHelper.confirmParseException(e);
|
||||
} catch (FormulaParseException e) {
|
||||
if (!e.getMessage().equals("Found reference to named range \"A\", but that named range wasn't defined!")) {
|
||||
throw new AssertionFailedError("Identifed bug 44539");
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import org.apache.poi.hssf.usermodel.*;
|
||||
import org.apache.poi.ss.usermodel.CellValue;
|
||||
import org.apache.poi.ss.formula.FormulaParser;
|
||||
import org.apache.poi.ss.formula.FormulaRenderer;
|
||||
import org.apache.poi.ss.formula.FormulaType;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
|
||||
/**
|
||||
@ -101,7 +102,7 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
HSSFEvaluationWorkbook fpb = HSSFEvaluationWorkbook.create(wb);
|
||||
Ptg[] sharedFormula, convertedFormula;
|
||||
|
||||
sharedFormula = FormulaParser.parse("A2", fpb);
|
||||
sharedFormula = FormulaParser.parse("A2", fpb, FormulaType.CELL, -1);
|
||||
convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 0, 0);
|
||||
confirmOperandClasses(sharedFormula, convertedFormula);
|
||||
//conversion relative to [0,0] should return the original formula
|
||||
@ -117,7 +118,7 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
//one row down and one cell right
|
||||
assertEquals("B3", FormulaRenderer.toFormulaString(fpb, convertedFormula));
|
||||
|
||||
sharedFormula = FormulaParser.parse("SUM(A1:C1)", fpb);
|
||||
sharedFormula = FormulaParser.parse("SUM(A1:C1)", fpb, FormulaType.CELL, -1);
|
||||
convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 0, 0);
|
||||
confirmOperandClasses(sharedFormula, convertedFormula);
|
||||
assertEquals("SUM(A1:C1)", FormulaRenderer.toFormulaString(fpb, convertedFormula));
|
||||
@ -139,22 +140,22 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
HSSFSheet sheet;
|
||||
HSSFCell cellB32769;
|
||||
HSSFCell cellC32769;
|
||||
|
||||
|
||||
// Reading directly from XLS file
|
||||
wb = HSSFTestDataSamples.openSampleWorkbook(SHARED_FORMULA_TEST_XLS);
|
||||
sheet = wb.getSheetAt(0);
|
||||
cellB32769 = sheet.getRow(32768).getCell(1);
|
||||
cellC32769 = sheet.getRow(32768).getCell(2);
|
||||
// check reading of formulas which are shared (two cells from a 1R x 8C range)
|
||||
assertEquals("B32770*2", cellB32769.getCellFormula());
|
||||
// check reading of formulas which are shared (two cells from a 1R x 8C range)
|
||||
assertEquals("B32770*2", cellB32769.getCellFormula());
|
||||
assertEquals("C32770*2", cellC32769.getCellFormula());
|
||||
confirmCellEvaluation(wb, cellB32769, 4);
|
||||
confirmCellEvaluation(wb, cellC32769, 6);
|
||||
// Confirm this example really does have SharedFormulas.
|
||||
// there are 3 others besides the one at A32769:H32769
|
||||
assertEquals(4, countSharedFormulas(sheet));
|
||||
|
||||
|
||||
assertEquals(4, countSharedFormulas(sheet));
|
||||
|
||||
|
||||
// Re-serialize and check again
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
@ -164,18 +165,18 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
confirmCellEvaluation(wb, cellB32769, 4);
|
||||
assertEquals(4, countSharedFormulas(sheet));
|
||||
}
|
||||
|
||||
|
||||
public void testUnshareFormulaDueToChangeFormula() {
|
||||
HSSFWorkbook wb;
|
||||
HSSFSheet sheet;
|
||||
HSSFCell cellB32769;
|
||||
HSSFCell cellC32769;
|
||||
|
||||
|
||||
wb = HSSFTestDataSamples.openSampleWorkbook(SHARED_FORMULA_TEST_XLS);
|
||||
sheet = wb.getSheetAt(0);
|
||||
cellB32769 = sheet.getRow(32768).getCell(1);
|
||||
cellC32769 = sheet.getRow(32768).getCell(2);
|
||||
|
||||
|
||||
// Updating cell formula, causing it to become unshared
|
||||
cellB32769.setCellFormula("1+1");
|
||||
confirmCellEvaluation(wb, cellB32769, 2);
|
||||
@ -194,25 +195,25 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
// changing shared formula cell to blank
|
||||
wb = HSSFTestDataSamples.openSampleWorkbook(SHARED_FORMULA_TEST_XLS);
|
||||
sheet = wb.getSheetAt(0);
|
||||
|
||||
|
||||
assertEquals("A$1*2", sheet.getRow(ROW_IX).getCell(1).getCellFormula());
|
||||
cell = sheet.getRow(ROW_IX).getCell(1);
|
||||
cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
|
||||
assertEquals(3, countSharedFormulas(sheet));
|
||||
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
assertEquals("A$1*2", sheet.getRow(ROW_IX+1).getCell(1).getCellFormula());
|
||||
|
||||
|
||||
// deleting shared formula cell
|
||||
wb = HSSFTestDataSamples.openSampleWorkbook(SHARED_FORMULA_TEST_XLS);
|
||||
sheet = wb.getSheetAt(0);
|
||||
|
||||
|
||||
assertEquals("A$1*2", sheet.getRow(ROW_IX).getCell(1).getCellFormula());
|
||||
cell = sheet.getRow(ROW_IX).getCell(1);
|
||||
sheet.getRow(ROW_IX).removeCell(cell);
|
||||
assertEquals(3, countSharedFormulas(sheet));
|
||||
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
assertEquals("A$1*2", sheet.getRow(ROW_IX+1).getCell(1).getCellFormula());
|
||||
|
@ -1,55 +0,0 @@
|
||||
/* ====================================================================
|
||||
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 junit.framework.Assert;
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.apache.poi.ss.formula.FormulaParser.FormulaParseException;
|
||||
/**
|
||||
* Avoids making {@link FormulaParseException} public
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public class FormulaParserTestHelper {
|
||||
/**
|
||||
* @throws AssertionFailedError if <tt>e</tt> is not a formula parser exception
|
||||
* or if the exception message doesn't match.
|
||||
*/
|
||||
public static void confirmParseException(RuntimeException e, String expectedMessage) {
|
||||
checkType(e);
|
||||
Assert.assertEquals(expectedMessage, e.getMessage());
|
||||
}
|
||||
/**
|
||||
* @throws AssertionFailedError if <tt>e</tt> is not a formula parser exception
|
||||
* or if <tt>e</tt> has no message.
|
||||
*/
|
||||
public static void confirmParseException(RuntimeException e) {
|
||||
checkType(e);
|
||||
Assert.assertNotNull(e.getMessage());
|
||||
}
|
||||
private static void checkType(RuntimeException e) throws AssertionFailedError {
|
||||
if (!(e instanceof FormulaParseException)) {
|
||||
String failMsg = "Expected FormulaParseException, but got ("
|
||||
+ e.getClass().getName() + "):";
|
||||
System.err.println(failMsg);
|
||||
e.printStackTrace();
|
||||
throw new AssertionFailedError(failMsg);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user