From 1a941fcd691f9f6a1f7d5c04b87d61a03811da2d Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Fri, 10 Jun 2016 04:20:41 +0000 Subject: [PATCH] bug 57840: add javadocs (warn about stale XSSFTable cache), remove rowIndex argument from calls to FormulaParser.parse(String, FormulaParsingWorkbook, FormulaType, int sheetIndex) when rowIndex is irrelevant, clear xmlColumnPr and commonXPath during updateHeaders so that users have a mechanism to clear invalidated cached values git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xssf_structured_references@1747627 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/formula/EvaluationWorkbook.java | 1 - .../apache/poi/ss/formula/FormulaParser.java | 41 +++++++---- .../poi/ss/formula/WorkbookEvaluator.java | 13 +--- .../poi/ss/formula/functions/Indirect.java | 17 +++-- .../usermodel/BaseXSSFEvaluationWorkbook.java | 8 ++- .../apache/poi/xssf/usermodel/XSSFCell.java | 2 +- .../apache/poi/xssf/usermodel/XSSFTable.java | 69 +++++++++++++++---- .../usermodel/helpers/XSSFFormulaUtils.java | 3 +- .../usermodel/helpers/XSSFRowShifter.java | 9 ++- .../xssf/usermodel/TestXSSFFormulaParser.java | 2 +- .../poi/hssf/model/TestFormulaParser.java | 6 +- .../poi/hssf/record/TestArrayRecord.java | 2 +- .../hssf/record/TestSharedFormulaRecord.java | 4 +- 13 files changed, 116 insertions(+), 61 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java b/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java index 45e6351f53..b0a3c76060 100644 --- a/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java @@ -68,7 +68,6 @@ public interface EvaluationWorkbook { */ ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber); - EvaluationName getName(NamePtg namePtg); EvaluationName getName(String name, int sheetIndex); String resolveNameXText(NameXPtg ptg); diff --git a/src/java/org/apache/poi/ss/formula/FormulaParser.java b/src/java/org/apache/poi/ss/formula/FormulaParser.java index 357e875d8d..74cbd87fb9 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaParser.java +++ b/src/java/org/apache/poi/ss/formula/FormulaParser.java @@ -145,17 +145,20 @@ public final class FormulaParser { } /** - * Parse a formula into a array of tokens - * Side effect: creates name (Workbook.createName) if formula contains unrecognized names (names are likely UDFs) + * Parse a formula into an array of tokens + * Side effect: creates name ({@link org.apache.poi.ss.usermodel.Workbook#createName}) + * if formula contains unrecognized names (names are likely UDFs) * * @param formula the formula to parse * @param workbook the parent workbook * @param formulaType the type of the formula, see {@link FormulaType} * @param sheetIndex the 0-based index of the sheet this formula belongs to. + * The sheet index is required to resolve sheet-level names. -1 means that + * the scope of the name will be ignored and the parser will match names only by name * @param rowIndex - the related cell's row index in 0-based form (-1 if the formula is not cell related) * used to handle structured references that have the "#This Row" quantifier. - * The sheet index is required to resolve sheet-level names. -1 means that - * the scope of the name will be ignored and the parser will match names only by name + * Use rowIndex=-1 or {@link #parseStructuredReference(String, FormulaParsingWorkbook, int, int) if formula + * does not contain structured references. * * @return array of parsed tokens * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid @@ -165,7 +168,22 @@ public final class FormulaParser { fp.parse(); return fp.getRPNPtg(formulaType); } - + + /** + * Parse a formula into an array of tokens + * Side effect: creates name ({@link org.apache.poi.ss.usermodel.Workbook#createName}) + * if formula contains unrecognized names (names are likely UDFs) + * + * @param formula the formula to parse + * @param workbook the parent workbook + * @param formulaType the type of the formula, see {@link FormulaType} + * @param sheetIndex the 0-based index of the sheet this formula belongs to. + * The sheet index is required to resolve sheet-level names. -1 means that + * 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 has incorrect syntax or is otherwise invalid + */ public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, int formulaType, int sheetIndex) { return parse(formula, workbook, formulaType, sheetIndex, -1); } @@ -180,7 +198,8 @@ public final class FormulaParser { * @return the area that being represented by the structured reference. */ public static Area3DPxg parseStructuredReference(String tableText, FormulaParsingWorkbook workbook, int rowIndex) { - Ptg[] arr = FormulaParser.parse(tableText, workbook, 0, 0, rowIndex); + final int sheetIndex = -1; //don't care? + Ptg[] arr = FormulaParser.parse(tableText, workbook, FormulaType.CELL, sheetIndex, rowIndex); if (arr.length != 1 || !(arr[0] instanceof Area3DPxg) ) { throw new IllegalStateException("Illegal structured reference"); } @@ -588,14 +607,14 @@ public final class FormulaParser { * @param tableName * @return */ - private ParseNode parseStructuredReference(String tableName){ + private ParseNode parseStructuredReference(String tableName) { if ( ! (_ssVersion.equals(SpreadsheetVersion.EXCEL2007)) ) { - throw new FormulaParseException("Strctured references work only on XSSF (Excel 2007)!"); + throw new FormulaParseException("Structured references work only on XSSF (Excel 2007+)!"); } Table tbl = _book.getTable(tableName); if (tbl == null) { - throw new FormulaParseException("Illegal table name!"); + throw new FormulaParseException("Illegal table name!"); } String sheetName = tbl.getSheetName(); @@ -845,11 +864,9 @@ public final class FormulaParser { if (look == '(') { return function(name); } - //TODO Livshen's code if(look == '['){ return parseStructuredReference(name); } - //TODO End of Livshen's code if (name.equalsIgnoreCase("TRUE") || name.equalsIgnoreCase("FALSE")) { return new ParseNode(BoolPtg.valueOf(name.equalsIgnoreCase("TRUE"))); } @@ -875,7 +892,7 @@ public final class FormulaParser { // defined names may begin with a letter or underscore or backslash if (!Character.isLetter(look) && look != '_' && look != '\\') { - throw expected("number, string, defined name, or table"); + throw expected("number, string, defined name, or data table"); } while (isValidDefinedNameChar(look)) { sb.append(look); diff --git a/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java b/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java index 1ef08dd6d5..7a964912ad 100644 --- a/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java @@ -299,15 +299,6 @@ public final class WorkbookEvaluator { try { Ptg[] ptgs = _workbook.getFormulaTokens(srcCell); -// System.out.println("====="); -// XSSFCell c = ((XSSFEvaluationCell)srcCell).getXSSFCell(); -// System.out.println("Formula is "+ c); -// System.out.println("The cell is " + c.getSheet().getSheetName()+"!"+c.getReference()); -// System.out.println("Evaluation tokens : "); // TODO Dlivshen remove -// for (Ptg ptg : ptgs) { // TODO Dlivshen remove -// System.out.println(ptg); // TODO Dlivshen remove -// } // TODO Dlivshen remove -// System.out.println("======"); // TODO Dlivshen remove if (evalListener == null) { result = evaluateFormula(ec, ptgs); } else { @@ -319,9 +310,9 @@ public final class WorkbookEvaluator { tracker.updateCacheResult(result); } catch (NotImplementedException e) { - throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex); + throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex); } catch (RuntimeException re) { - if (re.getCause() instanceof WorkbookNotFoundException && _ignoreMissingWorkbooks) { + if (re.getCause() instanceof WorkbookNotFoundException && _ignoreMissingWorkbooks) { logInfo(re.getCause().getMessage() + " - Continuing with cached value!"); switch(srcCell.getCachedFormulaResultType()) { case Cell.CELL_TYPE_NUMERIC: diff --git a/src/java/org/apache/poi/ss/formula/functions/Indirect.java b/src/java/org/apache/poi/ss/formula/functions/Indirect.java index a5be765b68..1ea3dcd386 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Indirect.java +++ b/src/java/org/apache/poi/ss/formula/functions/Indirect.java @@ -96,9 +96,6 @@ public final class Indirect implements FreeRefFunction { private static ValueEval evaluateIndirect(final OperationEvaluationContext ec, String text, boolean isA1style) { - ec.getRowIndex(); - ec.getColumnIndex(); - // Search backwards for '!' because sheet names can contain '!' int plingPos = text.lastIndexOf('!'); @@ -119,17 +116,19 @@ public final class Indirect implements FreeRefFunction { refText = text.substring(plingPos + 1); } - String refStrPart1; - String refStrPart2; - if (Table.isStructuredReference.matcher(refText).matches()) { // The argument is structured reference + if (Table.isStructuredReference.matcher(refText).matches()) { + // The argument is structured reference Area3DPxg areaPtg = null; - try{ + try { areaPtg = FormulaParser.parseStructuredReference(refText, (FormulaParsingWorkbook) ec.getWorkbook(), ec.getRowIndex()); - } catch(FormulaParseException e) { + } catch (FormulaParseException e) { return ErrorEval.REF_INVALID; } return ec.getArea3DEval(areaPtg); - } else { // The argumnet is regular reference + } else { + // The argument is regular reference + String refStrPart1; + String refStrPart2; int colonPos = refText.indexOf(':'); if (colonPos < 0) { refStrPart1 = refText.trim(); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java index 8ef2c54392..28a9ecf7d3 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java @@ -315,6 +315,10 @@ public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWork return _uBook.createName(); } + private static String caseInsensitive(String s) { + return s.toUpperCase(Locale.ROOT); + } + /* * TODO: data tables are stored at the workbook level in XSSF, but are bound to a single sheet. * The current code structure has them hanging off XSSFSheet, but formulas reference them @@ -336,7 +340,7 @@ public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWork for (Sheet sheet : _uBook) { for (XSSFTable tbl : ((XSSFSheet)sheet).getTables()) { - String lname = tbl.getName().toLowerCase(Locale.ROOT); + String lname = caseInsensitive(tbl.getName()); _tableCache.put(lname, tbl); } } @@ -356,7 +360,7 @@ public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWork @Override public XSSFTable getTable(String name) { if (name == null) return null; - String lname = name.toLowerCase(Locale.ROOT); + String lname = caseInsensitive(name); return getTableCache().get(lname); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java index 923ca57c58..ef2a7d94e5 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -550,7 +550,7 @@ public final class XSSFCell implements Cell { XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); //validate through the FormulaParser - FormulaParser.parse(formula, fpb, formulaType, wb.getSheetIndex(getSheet()), -1); + FormulaParser.parse(formula, fpb, formulaType, wb.getSheetIndex(getSheet()), getRowIndex()); CTCellFormula f = CTCellFormula.Factory.newInstance(); f.setStringValue(formula); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java index 72e3d341ad..f6d3d91637 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Locale; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; @@ -33,6 +34,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.ss.usermodel.Table; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; +import org.apache.poi.util.StringUtil; import org.apache.xmlbeans.XmlException; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; @@ -121,20 +123,22 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { * @return true if the Table element contain mappings */ public boolean mapsTo(long id){ - boolean maps =false; - List pointers = getXmlColumnPrs(); for (XSSFXmlColumnPr pointer: pointers) { if (pointer.getMapId()==id) { - maps=true; - break; + return true; } } - return maps; + return false; } + /** + * caches table columns for performance. + * Updated via updateHeaders + * @since 3.15 beta 2 + */ private CTTableColumn[] getTableColumns() { if (ctColumns == null) { ctColumns = ctTable.getTableColumns().getTableColumnArray(); @@ -146,6 +150,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { * * Calculates the xpath of the root element for the table. This will be the common part * of all the mapping's xpaths + * Note: this function caches the result for performance. To flush the cache {@link #updateHeaders()} must be called. * * @return the xpath of the table's root element */ @@ -176,10 +181,8 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { } } - commonXPath = ""; - for (int i = 1 ; i< commonTokens.length;i++) { - commonXPath +="/"+commonTokens[i]; - } + commonTokens[0] = ""; + commonXPath = StringUtil.join(commonTokens, "/"); } return commonXPath; @@ -188,6 +191,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { /** * Note this list is static - once read, it does not notice later changes to the underlying column structures + * To clear the cache, call {@link #updateHeaders} * @return List of XSSFXmlColumnPr */ public List getXmlColumnPrs() { @@ -297,7 +301,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { * Headers must be in sync, otherwise Excel will display a * "Found unreadable content" message on startup. */ - public void updateHeaders(){ + public void updateHeaders() { XSSFSheet sheet = (XSSFSheet)getParent(); CellReference ref = getStartCellReference(); if(ref == null) return; @@ -317,43 +321,80 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { } ctColumns = null; columnMap = null; + xmlColumnPr = null; + commonXPath = null; } } + private static String caseInsensitive(String s) { + return s.toUpperCase(Locale.ROOT); + } + + /** + * Gets the relative column index of a column in this table having the header name column. + * The column index is relative to the left-most column in the table, 0-indexed. + * Returns -1 if column is not a header name in table. + * + * Note: this function caches column names for performance. To flush the cache (because columns + * have been moved or column headers have been changed), {@link #updateHeaders()} must be called. + * + * @since 3.15 beta 2 + */ public int findColumnIndex(String column) { if (columnMap == null) { - columnMap = new HashMap(getTableColumns().length); + // FIXME: replace with org.apache.commons.collections.map.CaseInsensitiveMap + int count = getTableColumns().length; + columnMap = new HashMap(count); - for (int i=0; i < getTableColumns().length; i++) { - columnMap.put(getTableColumns()[i].getName().toUpperCase(), Integer.valueOf(i)); + for (int i=0; i < count; i++) { + String columnName = getTableColumns()[i].getName(); + columnMap.put(caseInsensitive(columnName), i); } } // Table column names with special characters need a single quote escape // but the escape is not present in the column definition - Integer idx = columnMap.get(column.replace("'", "").toUpperCase()); + Integer idx = columnMap.get(caseInsensitive(column.replace("'", ""))); return idx == null ? -1 : idx.intValue(); } + /** + * @since 3.15 beta 2 + */ public String getSheetName() { return getXSSFSheet().getSheetName(); } + /** + * @since 3.15 beta 2 + */ public boolean isHasTotalsRow() { return ctTable.getTotalsRowShown(); } + /** + * @since 3.15 beta 2 + */ public int getStartColIndex() { return getStartCellReference().getCol(); } + /** + * @since 3.15 beta 2 + */ public int getStartRowIndex() { return getStartCellReference().getRow(); } + /** + * @since 3.15 beta 2 + */ public int getEndColIndex() { return getEndCellReference().getCol(); } + /** + * @since 3.15 beta 2 + */ public int getEndRowIndex() { return getEndCellReference().getRow(); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java index 50190b0a6b..8aa3de6014 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java @@ -113,7 +113,8 @@ public final class XSSFFormulaUtils { String formula = name.getRefersToFormula(); if (formula != null) { int sheetIndex = name.getSheetIndex(); - Ptg[] ptgs = FormulaParser.parse(formula, _fpwb, FormulaType.NAMEDRANGE, sheetIndex, -1); + int rowIndex = -1; //don't care + Ptg[] ptgs = FormulaParser.parse(formula, _fpwb, FormulaType.NAMEDRANGE, sheetIndex, rowIndex); for (Ptg ptg : ptgs) { updatePtg(ptg, oldName, newName); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java index 77236913b9..a1436cc643 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java @@ -134,8 +134,9 @@ public final class XSSFRowShifter { XSSFName name = wb.getNameAt(i); String formula = name.getRefersToFormula(); int sheetIndex = name.getSheetIndex(); + final int rowIndex = -1; //don't care, named ranges are not allowed to include structured references - Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.NAMEDRANGE, sheetIndex, -1); + Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.NAMEDRANGE, sheetIndex, rowIndex); if (shifter.adjustFormula(ptgs, sheetIndex)) { String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); name.setRefersToFormula(shiftedFmla); @@ -218,10 +219,11 @@ public final class XSSFRowShifter { XSSFSheet sheet = row.getSheet(); XSSFWorkbook wb = sheet.getWorkbook(); int sheetIndex = wb.getSheetIndex(sheet); + final int rowIndex = row.getRowNum(); XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); try { - Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, -1); + Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex); String shiftedFmla = null; if (shifter.adjustFormula(ptgs, sheetIndex)) { shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); @@ -238,6 +240,7 @@ public final class XSSFRowShifter { public void updateConditionalFormatting(FormulaShifter shifter) { XSSFWorkbook wb = sheet.getWorkbook(); int sheetIndex = wb.getSheetIndex(sheet); + final int rowIndex = -1; //don't care, structured references not allowed in conditional formatting XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); CTWorksheet ctWorksheet = sheet.getCTWorksheet(); @@ -283,7 +286,7 @@ public final class XSSFRowShifter { String[] formulaArray = cfRule.getFormulaArray(); for (int i = 0; i < formulaArray.length; i++) { String formula = formulaArray[i]; - Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, -1); + Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex); if (shifter.adjustFormula(ptgs, sheetIndex)) { String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); cfRule.setFormulaArray(i, shiftedFmla); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java index ac7f03a380..d6802d0fb9 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java @@ -42,7 +42,7 @@ import java.util.Arrays; public final class TestXSSFFormulaParser { private static Ptg[] parse(FormulaParsingWorkbook fpb, String fmla) { - return FormulaParser.parse(fmla, fpb, FormulaType.CELL, -1, -1); + return FormulaParser.parse(fmla, fpb, FormulaType.CELL, -1); } @Test diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java index 7337a1ad89..82153fe09e 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java @@ -1197,7 +1197,7 @@ public final class TestFormulaParser { 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), FormulaType.CELL, -1,-1); + Ptg[] ptgs = FormulaParser.parse(formula, HSSFEvaluationWorkbook.create(wb), FormulaType.CELL, -1); confirmTokenClasses(ptgs, // TODO - AttrPtg.class, // Excel prepends this @@ -1486,8 +1486,8 @@ public final class TestFormulaParser { confirmParseError(wb, "A1:ROUND(B1,1)", "The RHS of the range operator ':' at position 3 is not a proper reference."); - confirmParseError(wb, "Sheet1!!!", "Parse error near char 7 '!' in specified formula 'Sheet1!!!'. Expected number, string, defined name, or table"); - confirmParseError(wb, "Sheet1!.Name", "Parse error near char 7 '.' in specified formula 'Sheet1!.Name'. Expected number, string, defined name, or table"); + confirmParseError(wb, "Sheet1!!!", "Parse error near char 7 '!' in specified formula 'Sheet1!!!'. Expected number, string, defined name, or data table"); + confirmParseError(wb, "Sheet1!.Name", "Parse error near char 7 '.' in specified formula 'Sheet1!.Name'. Expected number, string, defined name, or data table"); confirmParseError(wb, "Sheet1!Sheet1", "Specified name 'Sheet1' for sheet Sheet1 not found"); confirmParseError(wb, "Sheet1!F:Sheet1!G", "'Sheet1!F' is not a proper reference."); confirmParseError(wb, "Sheet1!F..foobar", "Complete area reference expected after sheet name at index 11."); diff --git a/src/testcases/org/apache/poi/hssf/record/TestArrayRecord.java b/src/testcases/org/apache/poi/hssf/record/TestArrayRecord.java index 7affe462e6..ff5fe0ad9b 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestArrayRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestArrayRecord.java @@ -51,7 +51,7 @@ public final class TestArrayRecord extends TestCase { assertEquals("MAX(C1:C2-D1:D2)", FormulaRenderer.toFormulaString(null, ptg)); //construct a new ArrayRecord with the same contents as r1 - Ptg[] fmlaPtg = FormulaParser.parse("MAX(C1:C2-D1:D2)", null, FormulaType.ARRAY, 0, -1); + Ptg[] fmlaPtg = FormulaParser.parse("MAX(C1:C2-D1:D2)", null, FormulaType.ARRAY, 0); ArrayRecord r2 = new ArrayRecord(Formula.create(fmlaPtg), new CellRangeAddress8Bit(1, 1, 1, 1)); byte[] ser = r2.serialize(); //serialize and check that the data is the same as in r1 diff --git a/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java b/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java index cf49432ded..14de4bcdaf 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java @@ -107,7 +107,7 @@ public final class TestSharedFormulaRecord extends TestCase { SharedFormula sf = new SharedFormula(SpreadsheetVersion.EXCEL97); - sharedFormula = FormulaParser.parse("A2", fpb, FormulaType.CELL, -1, -1); + sharedFormula = FormulaParser.parse("A2", fpb, FormulaType.CELL, -1); convertedFormula = sf.convertSharedFormulas(sharedFormula, 0, 0); confirmOperandClasses(sharedFormula, convertedFormula); //conversion relative to [0,0] should return the original formula @@ -123,7 +123,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, FormulaType.CELL, -1, -1); + sharedFormula = FormulaParser.parse("SUM(A1:C1)", fpb, FormulaType.CELL, -1); convertedFormula = sf.convertSharedFormulas(sharedFormula, 0, 0); confirmOperandClasses(sharedFormula, convertedFormula); assertEquals("SUM(A1:C1)", FormulaRenderer.toFormulaString(fpb, convertedFormula)); -- 2.39.5