]> source.dussan.org Git - poi.git/commitdiff
#56737 Sometimes Excel writes an internal reference to a local name in an odd way...
authorNick Burch <nick@apache.org>
Fri, 18 Jul 2014 15:59:55 +0000 (15:59 +0000)
committerNick Burch <nick@apache.org>
Fri, 18 Jul 2014 15:59:55 +0000 (15:59 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1611681 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/model/InternalWorkbook.java
src/java/org/apache/poi/hssf/model/LinkTable.java
src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
src/testcases/org/apache/poi/hssf/model/TestLinkTable.java
src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java

index e54d6c5d8047c7f548cc149a54a91f66f619a95a..9ecbdb97b7410a67dcb6d749873a2f9cd24998e8 100644 (file)
@@ -26,8 +26,61 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.apache.poi.ddf.*;
-import org.apache.poi.hssf.record.*;
+import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherBoolProperty;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.ddf.EscherDggRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherRGBProperty;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.ddf.EscherSplitMenuColorsRecord;
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.BackupRecord;
+import org.apache.poi.hssf.record.BookBoolRecord;
+import org.apache.poi.hssf.record.BoundSheetRecord;
+import org.apache.poi.hssf.record.CodepageRecord;
+import org.apache.poi.hssf.record.CountryRecord;
+import org.apache.poi.hssf.record.DSFRecord;
+import org.apache.poi.hssf.record.DateWindow1904Record;
+import org.apache.poi.hssf.record.DrawingGroupRecord;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.EscherAggregate;
+import org.apache.poi.hssf.record.ExtSSTRecord;
+import org.apache.poi.hssf.record.ExtendedFormatRecord;
+import org.apache.poi.hssf.record.ExternSheetRecord;
+import org.apache.poi.hssf.record.FileSharingRecord;
+import org.apache.poi.hssf.record.FnGroupCountRecord;
+import org.apache.poi.hssf.record.FontRecord;
+import org.apache.poi.hssf.record.FormatRecord;
+import org.apache.poi.hssf.record.HideObjRecord;
+import org.apache.poi.hssf.record.HyperlinkRecord;
+import org.apache.poi.hssf.record.InterfaceEndRecord;
+import org.apache.poi.hssf.record.InterfaceHdrRecord;
+import org.apache.poi.hssf.record.MMSRecord;
+import org.apache.poi.hssf.record.NameCommentRecord;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.PaletteRecord;
+import org.apache.poi.hssf.record.PasswordRecord;
+import org.apache.poi.hssf.record.PasswordRev4Record;
+import org.apache.poi.hssf.record.PrecisionRecord;
+import org.apache.poi.hssf.record.ProtectRecord;
+import org.apache.poi.hssf.record.ProtectionRev4Record;
+import org.apache.poi.hssf.record.RecalcIdRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RefreshAllRecord;
+import org.apache.poi.hssf.record.SSTRecord;
+import org.apache.poi.hssf.record.StyleRecord;
+import org.apache.poi.hssf.record.SupBookRecord;
+import org.apache.poi.hssf.record.TabIdRecord;
+import org.apache.poi.hssf.record.UseSelFSRecord;
+import org.apache.poi.hssf.record.WindowOneRecord;
+import org.apache.poi.hssf.record.WindowProtectRecord;
+import org.apache.poi.hssf.record.WriteAccessRecord;
+import org.apache.poi.hssf.record.WriteProtectRecord;
 import org.apache.poi.hssf.record.common.UnicodeString;
 import org.apache.poi.hssf.util.HSSFColor;
 import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
@@ -1776,7 +1829,7 @@ public final class InternalWorkbook {
         return new ExternalSheet(extNames[0], extNames[1]);
     }
     public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
-       String nameName = linkTable.resolveNameXText(externSheetIndex, externNameIndex);
+       String nameName = linkTable.resolveNameXText(externSheetIndex, externNameIndex, this);
        if(nameName == null) {
           return null;
        }
@@ -2299,7 +2352,7 @@ public final class InternalWorkbook {
      * @return the string representation of the defined or external name
      */
     public String resolveNameXText(int refIndex, int definedNameIndex) {
-        return linkTable.resolveNameXText(refIndex, definedNameIndex);
+        return linkTable.resolveNameXText(refIndex, definedNameIndex, this);
     }
 
     /**
index 6e203ef1d16af55650f382b78a20bbf32986b99d..9735d61c8ae1e000aca5f29aaf3f72eb56ad67bb 100644 (file)
@@ -31,6 +31,7 @@ import org.apache.poi.hssf.record.NameCommentRecord;
 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.SheetNameFormatter;
 import org.apache.poi.ss.formula.ptg.Area3DPtg;
 import org.apache.poi.ss.formula.ptg.ErrPtg;
 import org.apache.poi.ss.formula.ptg.NameXPtg;
@@ -206,7 +207,7 @@ final class LinkTable {
                // collect zero or more DEFINEDNAMEs id=0x18,
                //  with their comments if present
                while(true) {
-                 Class nextClass = rs.peekNextClass();
+                 Class<? extends Record> nextClass = rs.peekNextClass();
                  if (nextClass == NameRecord.class) {
                    NameRecord nr = (NameRecord)rs.getNext();
                    _definedNames.add(nr);
@@ -280,10 +281,9 @@ final class LinkTable {
         * @param sheetNumber 1-based sheet number
         */
        public NameRecord getSpecificBuiltinRecord(byte builtInCode, int sheetNumber) {
-
-               Iterator iterator = _definedNames.iterator();
+               Iterator<NameRecord> iterator = _definedNames.iterator();
                while (iterator.hasNext()) {
-                       NameRecord record = ( NameRecord ) iterator.next();
+                       NameRecord record = iterator.next();
 
                        //print areas are one based
                        if (record.getBuiltInName() == builtInCode && record.getSheetNumber() == sheetNumber) {
@@ -471,10 +471,37 @@ final class LinkTable {
                }
                return -1;
        }
-
-       public String resolveNameXText(int refIndex, int definedNameIndex) {
-               int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex);
-               return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex);
+       
+       public String resolveNameXText(int refIndex, int definedNameIndex, InternalWorkbook workbook) {
+        int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex);
+        int firstTabIndex = _externSheetRecord.getFirstSheetIndexFromRefIndex(refIndex);
+               if (firstTabIndex == -1) {
+                   // The referenced sheet could not be found
+            throw new RuntimeException("Referenced sheet could not be found");
+               }
+               
+               // Does it exist via the external book block?
+               if (_externalBookBlocks.length > extBookIndex) {
+            return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex);
+               } else if (firstTabIndex == -2) {
+                   // Workbook scoped name, not actually external after all
+                   NameRecord nr = getNameRecord(definedNameIndex);
+                   int sheetNumber = nr.getSheetNumber();
+                   
+                   StringBuffer text = new StringBuffer();
+                   if (sheetNumber > 0) {
+                       String sheetName = workbook.getSheetName(sheetNumber-1);
+                       SheetNameFormatter.appendFormat(text, sheetName);
+                       text.append("!");
+                   }
+                   text.append(nr.getNameText());
+                   return text.toString();
+               } else {
+                   throw new ArrayIndexOutOfBoundsException(
+                           "Ext Book Index relative but beyond the supported length, was " +
+                           extBookIndex + " but maximum is " + _externalBookBlocks.length
+                   );
+               }
        }
        public int resolveNameXIx(int refIndex, int definedNameIndex) {
       int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex);
index 0ff062b088c6fea7cee8745e5f82eb9139144223..5d59b36c9badaf0531b5725e7acc62ac67129151 100644 (file)
@@ -200,9 +200,13 @@ public class ExternSheetRecord extends StandardRecord {
                return sid;
        }
 
-       public int getExtbookIndexFromRefIndex(int refIndex) {
-               return getRef(refIndex).getExtBookIndex();
-       }
+    /**
+     * Returns the index of the SupBookRecord for this index
+     */
+    public int getExtbookIndexFromRefIndex(int refIndex) {
+        RefSubRecord refRec = getRef(refIndex);
+        return refRec.getExtBookIndex();
+    }
 
        /**
         * @return -1 if not found
@@ -217,6 +221,11 @@ public class ExternSheetRecord extends StandardRecord {
                return -1;
        }
 
+    /**
+     * Returns the first sheet that the reference applies to, or
+     *  -1 if the referenced sheet can't be found, or -2 if the
+     *  reference is workbook scoped.
+     */
        public int getFirstSheetIndexFromRefIndex(int extRefIndex) {
                return getRef(extRefIndex).getFirstSheetIndex();
        }
index d62a80d72b3ddfca32405801779ab8866ee4c046..48c81ea0bbb91d63f07befa9c3df48202dea5c7b 100644 (file)
@@ -27,7 +27,16 @@ import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
-import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.CountryRecord;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.ExternSheetRecord;
+import org.apache.poi.hssf.record.ExternalNameRecord;
+import org.apache.poi.hssf.record.NameCommentRecord;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SSTRecord;
+import org.apache.poi.hssf.record.SupBookRecord;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.formula.ptg.NameXPtg;
@@ -230,7 +239,7 @@ public final class TestLinkTable extends TestCase {
 
         //check that
         assertEquals(0, tbl.resolveNameXIx(namex1.getSheetRefIndex(), namex1.getNameIndex()));
-        assertEquals("ISODD", tbl.resolveNameXText(namex1.getSheetRefIndex(), namex1.getNameIndex()));
+        assertEquals("ISODD", tbl.resolveNameXText(namex1.getSheetRefIndex(), namex1.getNameIndex(), null));
 
         assertNull(tbl.getNameXPtg("ISEVEN"));
         NameXPtg namex2 = tbl.addNameXPtg("ISEVEN");  // adds two new rercords
@@ -256,7 +265,7 @@ public final class TestLinkTable extends TestCase {
         assertTrue(wrl.get(7) instanceof EOFRecord);
 
         assertEquals(0, tbl.resolveNameXIx(namex2.getSheetRefIndex(), namex2.getNameIndex()));
-        assertEquals("ISEVEN", tbl.resolveNameXText(namex2.getSheetRefIndex(), namex2.getNameIndex()));
+        assertEquals("ISEVEN", tbl.resolveNameXText(namex2.getSheetRefIndex(), namex2.getNameIndex(), null));
 
     }
 }
index 5d03b45d3f8a1489fbb3f7591bc197fdc62ab836..f9fac83d80e0fe187106feaf2fff3ccf20bbe213 100644 (file)
@@ -2619,7 +2619,6 @@ public final class TestBugs extends BaseTestBugzillaIssues {
      * Currently failing with 
      * java.lang.RuntimeException: Unexpected eval class (org.apache.poi.ss.formula.eval.NameXEval)
      */
-    @Ignore
     @Test
     public void bug56737() throws IOException {
         Workbook wb = openSample("56737.xls");