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

Reply via email to