Author: centic Date: Sat Nov 2 10:01:01 2013 New Revision: 1538163 URL: http://svn.apache.org/r1538163 Log: Fix Bug 54400 by updating the index in the LinkTable whenever sheets are removed.
Added: poi/trunk/test-data/spreadsheet/54500.xls Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java?rev=1538163&r1=1538162&r2=1538163&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java Sat Nov 2 10:01:01 2013 @@ -716,6 +716,9 @@ public final class InternalWorkbook { // Bump down by one, so still points // at the same sheet nr.setSheetNumber(nr.getSheetNumber()-1); + + // also update the link-table as otherwise references might point at invalid sheets + linkTable.updateIndexToInternalSheet(i, -1); } } } Modified: poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java?rev=1538163&r1=1538162&r2=1538163&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java Sat Nov 2 10:01:01 2013 @@ -31,13 +31,17 @@ import org.apache.poi.hssf.record.NameCo import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.SupBookRecord; -import org.apache.poi.ss.formula.ptg.*; +import org.apache.poi.ss.formula.ptg.Area3DPtg; +import org.apache.poi.ss.formula.ptg.ErrPtg; +import org.apache.poi.ss.formula.ptg.NameXPtg; +import org.apache.poi.ss.formula.ptg.Ptg; +import org.apache.poi.ss.formula.ptg.Ref3DPtg; /** * Link Table (OOO pdf reference: 4.10.3 ) <p/> * * The main data of all types of references is stored in the Link Table inside the Workbook Globals - * Substream (4.2.5). The Link Table itself is optional and occurs only, if there are any + * Substream (4.2.5). The Link Table itself is optional and occurs only if there are any * references in the document. * <p/> * @@ -63,9 +67,7 @@ import org.apache.poi.ss.formula.ptg.*; */ final class LinkTable { - // TODO make this class into a record aggregate - private static final class CRNBlock { private final CRNCountRecord _countRecord; @@ -174,7 +176,7 @@ final class LinkTable { private final int _recordCount; private final WorkbookRecordList _workbookRecordList; // TODO - would be nice to remove this - public LinkTable(List inputList, int startIndex, WorkbookRecordList workbookRecordList, Map<String, NameCommentRecord> commentRecords) { + public LinkTable(List<Record> inputList, int startIndex, WorkbookRecordList workbookRecordList, Map<String, NameCommentRecord> commentRecords) { _workbookRecordList = workbookRecordList; RecordStream rs = new RecordStream(inputList, startIndex); @@ -412,6 +414,10 @@ final class LinkTable { public int getIndexToInternalSheet(int extRefIndex) { return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex); } + + public void updateIndexToInternalSheet(int extRefIndex, int offset) { + _externSheetRecord.adjustIndex(extRefIndex, offset); + } public int getSheetIndexFromExternSheetIndex(int extRefIndex) { if (extRefIndex >= _externSheetRecord.getNumOfRefs() || extRefIndex < 0) { @@ -442,7 +448,6 @@ final class LinkTable { return _externSheetRecord.addRef(thisWbIndex, sheetIndex, sheetIndex); } - /** * copied from Workbook */ @@ -533,8 +538,8 @@ final class LinkTable { int supLinkIndex = 0; // find the posistion of the Add-In SupBookRecord in the workbook stream, // the created ExternalNameRecord will be appended to it - for (Iterator iterator = _workbookRecordList.iterator(); iterator.hasNext(); supLinkIndex++) { - Record record = (Record) iterator.next(); + for (Iterator<Record> iterator = _workbookRecordList.iterator(); iterator.hasNext(); supLinkIndex++) { + Record record = iterator.next(); if (record instanceof SupBookRecord) { if (((SupBookRecord) record).isAddInFunctions()) break; } Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java?rev=1538163&r1=1538162&r2=1538163&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java Sat Nov 2 10:01:01 2013 @@ -41,6 +41,10 @@ public class ExternSheetRecord extends S private int _firstSheetIndex; // may be -1 (0xFFFF) private int _lastSheetIndex; // may be -1 (0xFFFF) + public void adjustIndex(int offset) { + _firstSheetIndex += offset; + _lastSheetIndex += offset; + } /** a Constructor for making new sub record */ @@ -66,6 +70,7 @@ public class ExternSheetRecord extends S return _lastSheetIndex; } + @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("extBook=").append(_extBookIndex); @@ -122,6 +127,7 @@ public class ExternSheetRecord extends S } + @Override public String toString() { StringBuffer sb = new StringBuffer(); int nItems = _list.size(); @@ -138,10 +144,12 @@ public class ExternSheetRecord extends S return sb.toString(); } + @Override protected int getDataSize() { return 2 + _list.size() * RefSubRecord.ENCODED_SIZE; } + @Override public void serialize(LittleEndianOutput out) { int nItems = _list.size(); @@ -156,9 +164,14 @@ public class ExternSheetRecord extends S return _list.get(i); } + public void adjustIndex(int extRefIndex, int offset) { + getRef(extRefIndex).adjustIndex(offset); + } + /** * return the non static version of the id for this record. */ + @Override public short getSid() { return sid; } Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java?rev=1538163&r1=1538162&r2=1538163&view=diff ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java (original) +++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java Sat Nov 2 10:01:01 2013 @@ -48,6 +48,7 @@ import org.apache.poi.poifs.filesystem.N import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.formula.ptg.Area3DPtg; import org.apache.poi.ss.usermodel.BaseTestWorkbook; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.TempFile; @@ -965,4 +966,53 @@ public final class TestHSSFWorkbook exte HSSFWorkbook read = HSSFTestDataSamples.writeOutAndReadBack(wb); assertSheetOrder(read, "Invoice", "Deferred", "Received", "Digest"); } + + public void testBug54500() throws Exception { + String nameName = "AName"; + String sheetName = "ASheet"; + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("54500.xls"); + + assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3"); + + wb.createSheet(sheetName); + + assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3", "ASheet"); + + Name n = wb.createName(); + n.setNameName(nameName); + n.setSheetIndex(3); + n.setRefersToFormula(sheetName + "!A1"); + + assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3", "ASheet"); + assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula()); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + wb.write(stream); + + assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3", "ASheet"); + assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula()); + + wb.removeSheetAt(1); + + assertSheetOrder(wb, "Sheet1", "Sheet3", "ASheet"); + assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula()); + + ByteArrayOutputStream stream2 = new ByteArrayOutputStream(); + wb.write(stream2); + + assertSheetOrder(wb, "Sheet1", "Sheet3", "ASheet"); + assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula()); + + expectName( + new HSSFWorkbook(new ByteArrayInputStream(stream.toByteArray())), + nameName, "ASheet!A1"); + expectName( + new HSSFWorkbook( + new ByteArrayInputStream(stream2.toByteArray())), + nameName, "ASheet!A1"); + } + + private void expectName(HSSFWorkbook wb, String name, String expect) { + assertEquals(expect, wb.getName(name).getRefersToFormula()); + } } Added: poi/trunk/test-data/spreadsheet/54500.xls URL: http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/54500.xls?rev=1538163&view=auto ============================================================================== Files poi/trunk/test-data/spreadsheet/54500.xls (added) and poi/trunk/test-data/spreadsheet/54500.xls Sat Nov 2 10:01:01 2013 differ --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org