<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45978 - Fixed IOOBE in Ref3DPtg.toFormulaString() due eager initialisation of SheetReferences</action>
<action dev="POI-DEVELOPERS" type="add">Made HSSFFormulaEvaluator no longer require initialisation with sheet or row</action>
<action dev="POI-DEVELOPERS" type="add">Extended support for cached results of formula cells</action>
<action dev="POI-DEVELOPERS" type="fix">45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate</action>
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45978 - Fixed IOOBE in Ref3DPtg.toFormulaString() due eager initialisation of SheetReferences</action>
<action dev="POI-DEVELOPERS" type="add">Made HSSFFormulaEvaluator no longer require initialisation with sheet or row</action>
<action dev="POI-DEVELOPERS" type="add">Extended support for cached results of formula cells</action>
<action dev="POI-DEVELOPERS" type="fix">45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate</action>
return -1;
}
- public int getNumberOfREFStructures() {
- return _externSheetRecord.getNumOfRefs();
- }
-
public String resolveNameXText(int refIndex, int definedNameIndex) {
int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex);
return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex);
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.util.HSSFColor;
-import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
return linkTable;
}
- public SheetReferences getSheetReferences() {
- SheetReferences refs = new SheetReferences();
-
- if (linkTable != null) {
- int numRefStructures = linkTable.getNumberOfREFStructures();
- for (short k = 0; k < numRefStructures; k++) {
-
- String sheetName = findSheetNameFromExternSheet(k);
- refs.addSheetReference(sheetName, k);
-
- }
- }
- return refs;
- }
-
/** finds the sheet name by his extern sheet index
- * @param num extern sheet index
- * @return sheet name
+ * @param externSheetIndex extern sheet index
+ * @return sheet name.
*/
- public String findSheetNameFromExternSheet(short num){
+ public String findSheetNameFromExternSheet(int externSheetIndex){
- int indexToSheet = linkTable.getIndexToSheet(num);
+ int indexToSheet = linkTable.getIndexToSheet(externSheetIndex);
if (indexToSheet < 0) {
// TODO - what does '-1' mean here?
//error check, bail out gracefully!
return "";
}
+ if (indexToSheet >= boundsheets.size()) {
+ // Not sure if this can ever happen (See bug 45798)
+ return ""; // Seems to be what excel would do in this case
+ }
return getSheetName(indexToSheet);
}
public String toFormulaString(HSSFWorkbook book) {
// First do the sheet name
StringBuffer retval = new StringBuffer();
- String sheetName = Ref3DPtg.getSheetName(book, field_1_index_extern_sheet);
+ String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet);
if(sheetName != null) {
if(sheetName.length() == 0) {
// What excel does if sheet has been deleted
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.hssf.util.RangeAddress;
-import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndian;
}
- // TODO - find a home for this method
- // There is already a method on HSSFWorkbook called getSheetName but it seems to do something different.
- static String getSheetName(HSSFWorkbook book, int externSheetIndex) {
- // TODO - there are 3 ways this method can return null. Is each valid?
- if (book == null) {
- return null;
- }
-
- SheetReferences refs = book.getSheetReferences();
- if (refs == null) {
- return null;
- }
- return refs.getSheetName(externSheetIndex);
- }
/**
* @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(HSSFWorkbook book)
{
StringBuffer retval = new StringBuffer();
- String sheetName = getSheetName(book, field_1_index_extern_sheet);
+ String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet);
if(sheetName != null) {
SheetNameFormatter.appendFormat(retval, sheetName);
retval.append( '!' );
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
-import org.apache.poi.hssf.model.DrawingManager2;
import org.apache.poi.hssf.record.AbstractEscherHolderRecord;
import org.apache.poi.hssf.record.BackupRecord;
import org.apache.poi.hssf.record.DrawingGroupRecord;
import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.usermodel.HSSFRow.MissingCellPolicy;
import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.POILogFactory;
return retval;
}
- public SheetReferences getSheetReferences() {
- return workbook.getSheetReferences();
+ /**
+ * @deprecated for POI internal use only (formula rendering). This method is likely to
+ * be removed in future versions of POI.
+ */
+ public String findSheetNameFromExternSheet(int externSheetIndex){
+ // TODO - don't expose internal ugliness like externSheet indexes to the user model API
+ return workbook.findSheetNameFromExternSheet(externSheetIndex);
}
/**
}
/**
- * TODO - make this less cryptic / move elsewhere
+ * @deprecated for POI internal use only (formula rendering). This method is likely to
+ * be removed in future versions of POI.
+ *
* @param refIndex Index to REF entry in EXTERNSHEET record in the Link Table
* @param definedNameIndex zero-based to DEFINEDNAME or EXTERNALNAME record
* @return the string representation of the defined or external name
*/
public String resolveNameXText(int refIndex, int definedNameIndex) {
+ // TODO - make this less cryptic / move elsewhere
return workbook.resolveNameXText(refIndex, definedNameIndex);
}
+++ /dev/null
-/* ====================================================================
- 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.hssf.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Holds a collection of Sheet names and their associated
- * reference numbers.
- *
- * @author Andrew C. Oliver (acoliver at apache dot org)
- *
- */
-public class SheetReferences
-{
- Map map;
- public SheetReferences()
- {
- map = new HashMap(5);
- }
-
- public void addSheetReference(String sheetName, int number) {
- map.put(new Integer(number), sheetName);
- }
-
- public String getSheetName(int number) {
- return (String)map.get(new Integer(number));
- }
-
-}
import org.apache.poi.hssf.eventmodel.TestEventRecordFactory;
import org.apache.poi.hssf.eventmodel.TestModelFactory;
import org.apache.poi.hssf.eventusermodel.AllEventUserModelTests;
+import org.apache.poi.hssf.extractor.TestExcelExtractor;
import org.apache.poi.hssf.model.AllModelTests;
import org.apache.poi.hssf.record.AllRecordTests;
import org.apache.poi.hssf.usermodel.AllUserModelTests;
-import org.apache.poi.hssf.util.TestAreaReference;
-import org.apache.poi.hssf.util.TestCellReference;
-import org.apache.poi.hssf.util.TestRKUtil;
-import org.apache.poi.hssf.util.TestRangeAddress;
-import org.apache.poi.hssf.util.TestSheetReferences;
+import org.apache.poi.hssf.util.AllHSSFUtilTests;
/**
* Test Suite for all sub-packages of org.apache.poi.hssf<br/>
*/
public final class HSSFTests {
- public static void main(String[] args) {
- junit.textui.TestRunner.run(suite());
- }
-
public static Test suite() {
- TestSuite suite = new TestSuite("Tests for org.apache.poi.hssf");
- // $JUnit-BEGIN$
+ TestSuite suite = new TestSuite(HSSFTests.class.getName());
suite.addTest(AllEventUserModelTests.suite());
suite.addTest(AllModelTests.suite());
suite.addTest(AllUserModelTests.suite());
suite.addTest(AllRecordTests.suite());
+ suite.addTest(AllHSSFUtilTests.suite());
- suite.addTest(new TestSuite(TestAreaReference.class));
- suite.addTest(new TestSuite(TestCellReference.class));
- suite.addTest(new TestSuite(TestRangeAddress.class));
- suite.addTest(new TestSuite(TestRKUtil.class));
- suite.addTest(new TestSuite(TestSheetReferences.class));
+ if (false) { // TODO - hook this test up
+ suite.addTest(new TestSuite(TestExcelExtractor.class));
+ }
suite.addTest(new TestSuite(TestEventRecordFactory.class));
suite.addTest(new TestSuite(TestModelFactory.class));
- // $JUnit-END$
return suite;
}
}
==================================================================== */
package org.apache.poi.hssf.eventusermodel;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
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;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
/**
* Tests for {@link EventWorkbookBuilder}
public void testGetStubWorkbooks() {
assertNotNull(listener.getStubWorkbook());
assertNotNull(listener.getStubHSSFWorkbook());
-
- assertNotNull(listener.getStubWorkbook().getSheetReferences());
- assertNotNull(listener.getStubHSSFWorkbook().getSheetReferences());
}
public void testContents() {
assertEquals(3, listener.getStubWorkbook().getNumSheets());
- SheetReferences ref = listener.getStubWorkbook().getSheetReferences();
- assertEquals("Sh3", ref.getSheetName(0));
- assertEquals("Sheet1", ref.getSheetName(1));
- assertEquals("S2", ref.getSheetName(2));
+ Workbook ref = listener.getStubWorkbook();
+ assertEquals("Sh3", ref.findSheetNameFromExternSheet(0));
+ assertEquals("Sheet1", ref.findSheetNameFromExternSheet(1));
+ assertEquals("S2", ref.findSheetNameFromExternSheet(2));
}
public void testFormulas() {
import org.apache.poi.hssf.HSSFTestDataSamples;
/**
* Tests for LinkTable
- *
+ *
* @author Josh Micich
*/
public final class TestLinkTable extends TestCase {
/**
* The example file attached to bugzilla 45046 is a clear example of Name records being present
* without an External Book (SupBook) record. Excel has no trouble reading this file.<br/>
- * TODO get OOO documentation updated to reflect this (that EXTERNALBOOK is optional).
- *
- * It's not clear what exact steps need to be taken in Excel to create such a workbook
+ * TODO get OOO documentation updated to reflect this (that EXTERNALBOOK is optional).
+ *
+ * It's not clear what exact steps need to be taken in Excel to create such a workbook
*/
public void testLinkTableWithoutExternalBookRecord_bug45046() {
HSSFWorkbook wb;
// some other sanity checks
assertEquals(3, wb.getNumberOfSheets());
String formula = wb.getSheetAt(0).getRow(4).getCell(13).getCellFormula();
-
+
if ("ipcSummenproduktIntern($P5,N$6,$A$9,N$5)".equals(formula)) {
- // The reported symptom of this bugzilla is an earlier bug (already fixed)
- throw new AssertionFailedError("Identified bug 41726");
+ // The reported symptom of this bugzilla is an earlier bug (already fixed)
+ throw new AssertionFailedError("Identified bug 41726");
// This is observable in version 3.0
}
-
+
assertEquals("ipcSummenproduktIntern($C5,N$2,$A$9,N$1)", formula);
}
-
+
public void testMultipleExternSheetRecords_bug45698() {
HSSFWorkbook wb;
// some other sanity checks
assertEquals(7, wb.getNumberOfSheets());
}
+
+ public void testExtraSheetRefs_bug45978() {
+ HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("ex45978-extraLinkTableSheets.xls");
+ /*
+ ex45978-extraLinkTableSheets.xls is a cut-down version of attachment 22561.
+ The original file produces the same error.
+
+ This bug was caused by a combination of invalid sheet indexes in the EXTERNSHEET
+ record, and eager initialisation of the extern sheet references. Note - the worbook
+ has 2 sheets, but the EXTERNSHEET record refers to sheet indexes 0, 1 and 2.
+
+ Offset 0x3954 (14676)
+ recordid = 0x17, size = 32
+ [EXTERNSHEET]
+ numOfRefs = 5
+ refrec #0: extBook=0 firstSheet=0 lastSheet=0
+ refrec #1: extBook=1 firstSheet=2 lastSheet=2
+ refrec #2: extBook=2 firstSheet=1 lastSheet=1
+ refrec #3: extBook=0 firstSheet=-1 lastSheet=-1
+ refrec #4: extBook=0 firstSheet=1 lastSheet=1
+ [/EXTERNSHEET]
+
+ As it turns out, the formula in question doesn't even use externSheetIndex #1 - it
+ uses #4, which resolves to sheetIndex 1 -> 'Data'.
+
+ It is not clear exactly what externSheetIndex #4 would refer to. Excel seems to
+ display such a formula as "''!$A2", but then complains of broken link errors.
+ */
+
+ HSSFCell cell = wb.getSheetAt(0).getRow(1).getCell(1);
+ String cellFormula;
+ try {
+ cellFormula = cell.getCellFormula();
+ } catch (IndexOutOfBoundsException e) {
+ if (e.getMessage().equals("Index: 2, Size: 2")) {
+ throw new AssertionFailedError("Identified bug 45798");
+ }
+ throw e;
+ }
+ assertEquals("Data!$A2", cellFormula);
+ }
}
result.addTestSuite(TestHSSFColor.class);
result.addTestSuite(TestRangeAddress.class);
result.addTestSuite(TestRKUtil.class);
- result.addTestSuite(TestSheetReferences.class);
return result;
}
}
+++ /dev/null
-
-/* ====================================================================
- 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.hssf.util;
-
-import junit.framework.TestCase;
-
-/**
- * Tests the SheetReferences class.
- * @author Andrew C. Oliver (acoliver at apache dot org)
- */
-public class TestSheetReferences
- extends TestCase
-{
- public TestSheetReferences(String s)
- {
- super(s);
- }
-
- /**
- * Test that the SheetReferences class can add references and give them
- * out
- */
- public void testSheetRefs()
- throws Exception
- {
- SheetReferences refs = new SheetReferences();
- refs.addSheetReference("A", 0);
- refs.addSheetReference("B", 1);
- refs.addSheetReference("C", 3);
- assertTrue("ref 0 == A", refs.getSheetName(0).equals("A"));
- assertTrue("ref 1 == B", refs.getSheetName(1).equals("B"));
- assertTrue("ref 3 == C", refs.getSheetName(3).equals("C"));
- }
-}