]> source.dussan.org Git - poi.git/commitdiff
[bug-63998] Support commas, exclamation marks correctly in AreaReference. Thanks...
authorPJ Fanning <fanningpj@apache.org>
Thu, 9 Jan 2020 21:19:34 +0000 (21:19 +0000)
committerPJ Fanning <fanningpj@apache.org>
Thu, 9 Jan 2020 21:19:34 +0000 (21:19 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1872567 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/util/AreaReference.java
src/testcases/org/apache/poi/hssf/util/TestAreaReference.java

index 4dd4771be660e90e6145fca94a1c32afde06c048..a832fec6b4829195791f2473b693a484507b38e6 100644 (file)
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.StringTokenizer;
 
 import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.util.StringUtil;
 
 public class AreaReference {
 
@@ -166,14 +167,7 @@ public class AreaReference {
      *  {@link #generateContiguous(SpreadsheetVersion, String)})
      */
     public static boolean isContiguous(String reference) {
-       // If there's a sheet name, strip it off
-       int sheetRefEnd = reference.indexOf('!'); 
-       if(sheetRefEnd != -1) {
-          reference = reference.substring(sheetRefEnd);
-       }
-
-       // Check for the , as a sign of non-coniguous
-       return !reference.contains(",");
+        return splitAreaReferences(reference).length == 1;
     }
 
     public static AreaReference getWholeRow(SpreadsheetVersion version, String start, String end) {
@@ -220,11 +214,9 @@ public class AreaReference {
             version = DEFAULT_SPREADSHEET_VERSION; // how the code used to behave. 
         }
         List<AreaReference> refs = new ArrayList<>();
-        StringTokenizer st = new StringTokenizer(reference, ",");
-        while(st.hasMoreTokens()) {
-            refs.add(
-                    new AreaReference(st.nextToken(), version)
-            );
+        String[] splitReferences = splitAreaReferences(reference);
+        for (String ref : splitReferences) {
+            refs.add(new AreaReference(ref, version));
         }
         return refs.toArray(new AreaReference[0]);
     }
@@ -405,4 +397,31 @@ public class AreaReference {
         
         return new String [] { partA, sheetName + partB, };
     }
+
+    /**
+     * Splits a comma-separated area references string into an array of
+     * individual references
+     * @param reference Area references, i.e. A1:B2, 'Sheet1'!A1:B2
+     * @return Area references in an array, size >= 1
+     */
+    private static String[] splitAreaReferences(String reference) {
+        List<String> results = new ArrayList<>();
+        String currentSegment = "";
+        StringTokenizer st = new StringTokenizer(reference, ",");
+        while(st.hasMoreTokens()) {
+            if (currentSegment.length() > 0) {
+                currentSegment += ",";
+            }
+            currentSegment += st.nextToken();
+            int numSingleQuotes = StringUtil.countMatches(currentSegment, '\'');
+            if (numSingleQuotes == 0 || numSingleQuotes == 2) {
+                results.add(currentSegment);
+                currentSegment = "";
+            }
+        }
+        if (currentSegment.length() > 0) {
+            results.add(currentSegment);
+        }
+        return results.toArray(new String[0]);
+    }
 }
index 6c2c8829c60909b378ce60793dc45ba0125dd34f..b92b65adb75b7a228eb965acccfe4f4c803683a3 100644 (file)
@@ -55,15 +55,15 @@ public final class TestAreaReference {
         CellReference cf = ar.getFirstCell();
         assertEquals("row is 4", 0, cf.getRow());
         assertEquals("col is 1", 0, cf.getCol());
-        assertTrue("row is abs",cf.isRowAbsolute());
-        assertTrue("col is abs",cf.isColAbsolute());
+        assertTrue("row is abs", cf.isRowAbsolute());
+        assertTrue("col is abs", cf.isColAbsolute());
         assertEquals("string is $A$1", "$A$1", cf.formatAsString());
 
         cf = ar.getLastCell();
         assertEquals("row is 4", 1, cf.getRow());
         assertEquals("col is 1", 1, cf.getCol());
-        assertTrue("row is abs",cf.isRowAbsolute());
-        assertTrue("col is abs",cf.isColAbsolute());
+        assertTrue("row is abs", cf.isRowAbsolute());
+        assertTrue("col is abs", cf.isColAbsolute());
         assertEquals("string is $B$2", "$B$2", cf.formatAsString());
 
         CellReference[] refs = ar.getAllReferencedCells();
@@ -87,8 +87,8 @@ public final class TestAreaReference {
     }
 
     /**
-     * References failed when sheet names were being used
-     * Reported by Arne.Clauss@gedas.de
+     * References failed when sheet names were being used Reported by
+     * Arne.Clauss@gedas.de
      */
     @Test
     public void testReferenceWithSheet() {
@@ -100,7 +100,6 @@ public final class TestAreaReference {
 
         assertEquals(1, ar.getAllReferencedCells().length);
 
-
         ar = new AreaReference("Tabelle1!$B$5:$B$7", SpreadsheetVersion.EXCEL97);
         assertFalse(ar.isSingleCell());
 
@@ -122,6 +121,8 @@ public final class TestAreaReference {
         String refDCSimple = "$C$10:$C$10,$D$12:$D$12,$E$14:$E$14";
         String refDC2D = "$C$10:$C$11,$D$12:$D$12,$E$14:$E$20";
         String refDC3D = "Tabelle1!$C$10:$C$14,Tabelle1!$D$10:$D$12";
+        String refComma = "'A,Sheet'!$A$1:$A$1,'A,Sheet'!$A$4:$A$5";
+        String refCommaExp = "'!Sheet,Comma!'!$A$1:$B$1";
 
         // Check that we detect as contiguous properly
         assertTrue(AreaReference.isContiguous(refSimple));
@@ -129,6 +130,8 @@ public final class TestAreaReference {
         assertFalse(AreaReference.isContiguous(refDCSimple));
         assertFalse(AreaReference.isContiguous(refDC2D));
         assertFalse(AreaReference.isContiguous(refDC3D));
+        assertFalse(AreaReference.isContiguous(refComma));
+        assertTrue(AreaReference.isContiguous(refCommaExp));
 
         // Check we can only create contiguous entries
         new AreaReference(refSimple, SpreadsheetVersion.EXCEL97);
@@ -136,20 +139,20 @@ public final class TestAreaReference {
         try {
             new AreaReference(refDCSimple, SpreadsheetVersion.EXCEL97);
             fail("expected IllegalArgumentException");
-        } catch(IllegalArgumentException e) {
-               // expected during successful test
+        } catch (IllegalArgumentException e) {
+            // expected during successful test
         }
         try {
             new AreaReference(refDC2D, SpreadsheetVersion.EXCEL97);
             fail("expected IllegalArgumentException");
-        } catch(IllegalArgumentException e) {
-               // expected during successful test
+        } catch (IllegalArgumentException e) {
+            // expected during successful test
         }
         try {
             new AreaReference(refDC3D, SpreadsheetVersion.EXCEL97);
             fail("expected IllegalArgumentException");
-        } catch(IllegalArgumentException e) {
-               // expected during successful test
+        } catch (IllegalArgumentException e) {
+            // expected during successful test
         }
 
         // Test that we split as expected
@@ -193,6 +196,21 @@ public final class TestAreaReference {
         assertEquals("Tabelle1", refs[0].getLastCell().getSheetName());
         assertEquals("Tabelle1", refs[1].getFirstCell().getSheetName());
         assertEquals("Tabelle1", refs[1].getLastCell().getSheetName());
+
+        refs = AreaReference.generateContiguous(SpreadsheetVersion.EXCEL97, refComma);
+        assertEquals(2, refs.length);
+        System.out.println(refs[0].formatAsString());
+        assertTrue(refs[0].isSingleCell());
+        assertEquals("'A,Sheet'!$A$1", refs[0].formatAsString());
+        assertEquals("A,Sheet", refs[0].getLastCell().getSheetName());
+        assertEquals("'A,Sheet'!$A$4:$A$5", refs[1].formatAsString());
+        assertEquals("A,Sheet", refs[1].getLastCell().getSheetName());
+
+        refs = AreaReference.generateContiguous(SpreadsheetVersion.EXCEL97, refCommaExp);
+        assertEquals(1, refs.length);
+        assertFalse(refs[0].isSingleCell());
+        assertEquals("'!Sheet,Comma!'!$A$1:$B$1", refs[0].formatAsString());
+        assertEquals("!Sheet,Comma!", refs[0].getLastCell().getSheetName());
     }
 
     @Test
@@ -274,6 +292,9 @@ public final class TestAreaReference {
 
         ar = new AreaReference("'one:many'!A1:B2", SpreadsheetVersion.EXCEL97);
         confirmAreaSheetName(ar, "one:many", "'one:many'!A1:B2");
+
+        ar = new AreaReference("'O,Comma'!A1:B1", SpreadsheetVersion.EXCEL97);
+        confirmAreaSheetName(ar, "O,Comma", "'O,Comma'!A1:B1");
     }
 
     private static void confirmAreaSheetName(AreaReference ar, String sheetName, String expectedFullText) {