commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nia...@apache.org
Subject svn commit: r661822 - in /commons/proper/io/trunk/src: java/org/apache/commons/io/FilenameUtils.java java/org/apache/commons/io/IOCase.java test/org/apache/commons/io/FilenameUtilsWildcardTestCase.java test/org/apache/commons/io/IOCaseTestCase.java
Date Fri, 30 May 2008 19:12:01 GMT
Author: niallp
Date: Fri May 30 12:12:01 2008
New Revision: 661822

URL: http://svn.apache.org/viewvc?rev=661822&view=rev
Log:
IO-167 Fix case-insensitive string handling - thanks to Benjamin Bentmann

Modified:
    commons/proper/io/trunk/src/java/org/apache/commons/io/FilenameUtils.java
    commons/proper/io/trunk/src/java/org/apache/commons/io/IOCase.java
    commons/proper/io/trunk/src/test/org/apache/commons/io/FilenameUtilsWildcardTestCase.java
    commons/proper/io/trunk/src/test/org/apache/commons/io/IOCaseTestCase.java

Modified: commons/proper/io/trunk/src/java/org/apache/commons/io/FilenameUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/java/org/apache/commons/io/FilenameUtils.java?rev=661822&r1=661821&r2=661822&view=diff
==============================================================================
--- commons/proper/io/trunk/src/java/org/apache/commons/io/FilenameUtils.java (original)
+++ commons/proper/io/trunk/src/java/org/apache/commons/io/FilenameUtils.java Fri May 30 12:12:01
2008
@@ -1146,8 +1146,6 @@
         if (caseSensitivity == null) {
             caseSensitivity = IOCase.SENSITIVE;
         }
-        filename = caseSensitivity.convertCase(filename);
-        wildcardMatcher = caseSensitivity.convertCase(wildcardMatcher);
         String[] wcs = splitOnTokens(wildcardMatcher);
         boolean anyChars = false;
         int textIdx = 0;
@@ -1182,18 +1180,18 @@
                     // matching text token
                     if (anyChars) {
                         // any chars then try to locate text token
-                        textIdx = filename.indexOf(wcs[wcsIdx], textIdx);
+                        textIdx = caseSensitivity.checkIndexOf(filename, textIdx, wcs[wcsIdx]);
                         if (textIdx == -1) {
                             // token not found
                             break;
                         }
-                        int repeat = filename.indexOf(wcs[wcsIdx], textIdx + 1);
+                        int repeat = caseSensitivity.checkIndexOf(filename, textIdx + 1,
wcs[wcsIdx]);
                         if (repeat >= 0) {
                             backtrack.push(new int[] {wcsIdx, repeat});
                         }
                     } else {
                         // matching from current position
-                        if (!filename.startsWith(wcs[wcsIdx], textIdx)) {
+                        if (!caseSensitivity.checkRegionMatches(filename, textIdx, wcs[wcsIdx]))
{
                             // couldnt match token
                             break;
                         }

Modified: commons/proper/io/trunk/src/java/org/apache/commons/io/IOCase.java
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/java/org/apache/commons/io/IOCase.java?rev=661822&r1=661821&r2=661822&view=diff
==============================================================================
--- commons/proper/io/trunk/src/java/org/apache/commons/io/IOCase.java (original)
+++ commons/proper/io/trunk/src/java/org/apache/commons/io/IOCase.java Fri May 30 12:12:01
2008
@@ -196,33 +196,46 @@
     }
 
     /**
-     * Checks if one string contains another at a specific index using the case-sensitivity
rule.
+     * Checks if one string contains another starting at a specific index using the
+     * case-sensitivity rule.
      * <p>
-     * This method mimics parts of {@link String#regionMatches(boolean, int, String, int,
int)} 
+     * This method mimics parts of {@link String#indexOf(String, int)} 
      * but takes case-sensitivity into account.
      * 
      * @param str  the string to check, not null
      * @param strStartIndex  the index to start at in str
      * @param search  the start to search for, not null
-     * @return true if equal using the case rules
+     * @return the first index of the search String,
+     *  -1 if no match or <code>null</code> string input
      * @throws NullPointerException if either string is null
+     * @since 2.0
      */
-    public boolean checkRegionMatches(String str, int strStartIndex, String search) {
-        return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
+    public int checkIndexOf(String str, int strStartIndex, String search) {
+        int endIndex = str.length() - search.length();
+        if (endIndex >= strStartIndex) {
+            for (int i = strStartIndex; i <= endIndex; i++) {
+                if (checkRegionMatches(str, i, search)) {
+                    return i;
+                }
+            }
+        }
+        return -1;
     }
 
     /**
-     * Converts the case of the input String to a standard format.
-     * Subsequent operations can then use standard String methods.
+     * Checks if one string contains another at a specific index using the case-sensitivity
rule.
+     * <p>
+     * This method mimics parts of {@link String#regionMatches(boolean, int, String, int,
int)} 
+     * but takes case-sensitivity into account.
      * 
-     * @param str  the string to convert, null returns null
-     * @return the lower-case version if case-insensitive
+     * @param str  the string to check, not null
+     * @param strStartIndex  the index to start at in str
+     * @param search  the start to search for, not null
+     * @return true if equal using the case rules
+     * @throws NullPointerException if either string is null
      */
-    String convertCase(String str) {
-        if (str == null) {
-            return null;
-        }
-        return sensitive ? str : str.toLowerCase();
+    public boolean checkRegionMatches(String str, int strStartIndex, String search) {
+        return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
     }
 
     //-----------------------------------------------------------------------

Modified: commons/proper/io/trunk/src/test/org/apache/commons/io/FilenameUtilsWildcardTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/org/apache/commons/io/FilenameUtilsWildcardTestCase.java?rev=661822&r1=661821&r2=661822&view=diff
==============================================================================
--- commons/proper/io/trunk/src/test/org/apache/commons/io/FilenameUtilsWildcardTestCase.java
(original)
+++ commons/proper/io/trunk/src/test/org/apache/commons/io/FilenameUtilsWildcardTestCase.java
Fri May 30 12:12:01 2008
@@ -17,6 +17,7 @@
 package org.apache.commons.io;
 
 import java.io.File;
+import java.util.Locale;
 
 import junit.framework.TestCase;
 
@@ -181,4 +182,33 @@
         assertMatch("log.log.abc.log.abc.d", "*log?abc?d", true);
     }
 
+    public void testLocaleIndependence() {
+        Locale orig = Locale.getDefault();
+
+        Locale[] locales = Locale.getAvailableLocales();
+
+        String[][] data = {
+            { "I", "i"},
+            { "i", "I"},
+            { "i", "\u0130"},
+            { "i", "\u0131"},
+            { "\u03A3", "\u03C2"},
+            { "\u03A3", "\u03C3"},
+            { "\u03C2", "\u03C3"},
+        };
+
+        try {
+            for (int i = 0; i < data.length; i++) {
+                for (int j = 0; j < locales.length; j++) {
+                    Locale.setDefault(locales[j]);
+                    assertTrue("Test data corrupt: " + i, data[i][0].equalsIgnoreCase(data[i][1]));
+                    boolean match = FilenameUtils.wildcardMatch(data[i][0], data[i][1], IOCase.INSENSITIVE);
+                    assertTrue(Locale.getDefault().toString() + ": " + i, match);
+                }
+            }
+        } finally {
+            Locale.setDefault(orig);
+        }
+    }
+
 }

Modified: commons/proper/io/trunk/src/test/org/apache/commons/io/IOCaseTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/org/apache/commons/io/IOCaseTestCase.java?rev=661822&r1=661821&r2=661822&view=diff
==============================================================================
--- commons/proper/io/trunk/src/test/org/apache/commons/io/IOCaseTestCase.java (original)
+++ commons/proper/io/trunk/src/test/org/apache/commons/io/IOCaseTestCase.java Fri May 30
12:12:01 2008
@@ -246,6 +246,70 @@
     }
 
     //-----------------------------------------------------------------------
+    public void test_checkIndexOf_functionality() throws Exception {
+
+        // start
+        assertEquals(0,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "A"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 1, "A"));
+        assertEquals(0,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "AB"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 1, "AB"));
+        assertEquals(0,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "ABC"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 1, "ABC"));
+
+        // middle
+        assertEquals(3,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "D"));
+        assertEquals(3,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 3, "D"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 4, "D"));
+        assertEquals(3,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "DE"));
+        assertEquals(3,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 3, "DE"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 4, "DE"));
+        assertEquals(3,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "DEF"));
+        assertEquals(3,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 3, "DEF"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 4, "DEF"));
+
+        // end
+        assertEquals(9,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "J"));
+        assertEquals(9,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 8, "J"));
+        assertEquals(9,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 9, "J"));
+        assertEquals(8,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "IJ"));
+        assertEquals(8,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 8, "IJ"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 9, "IJ"));
+        assertEquals(7,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 6, "HIJ"));
+        assertEquals(7,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 7, "HIJ"));
+        assertEquals(-1,  IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 8, "HIJ"));
+
+        // not found
+        assertEquals(-1,   IOCase.SENSITIVE.checkIndexOf("ABCDEFGHIJ", 0, "DED"));
+
+        // too long
+        assertEquals(-1,   IOCase.SENSITIVE.checkIndexOf("DEF", 0, "ABCDEFGHIJ"));
+
+        try {
+            IOCase.SENSITIVE.checkIndexOf("ABC", 0, null);
+            fail();
+        } catch (NullPointerException ex) {}
+        try {
+            IOCase.SENSITIVE.checkIndexOf(null, 0, "ABC");
+            fail();
+        } catch (NullPointerException ex) {}
+        try {
+            IOCase.SENSITIVE.checkIndexOf(null, 0, null);
+            fail();
+        } catch (NullPointerException ex) {}
+    }
+
+    public void test_checkIndexOf_case() throws Exception {
+        assertEquals(1,  IOCase.SENSITIVE.checkIndexOf("ABC", 0, "BC"));
+        assertEquals(-1, IOCase.SENSITIVE.checkIndexOf("ABC", 0, "Bc"));
+        
+        assertEquals(1, IOCase.INSENSITIVE.checkIndexOf("ABC", 0, "BC"));
+        assertEquals(1, IOCase.INSENSITIVE.checkIndexOf("ABC", 0, "Bc"));
+        
+        assertEquals(1, IOCase.SYSTEM.checkIndexOf("ABC", 0, "BC"));
+        assertEquals(WINDOWS ? 1 : -1, IOCase.SYSTEM.checkIndexOf("ABC", 0, "Bc"));
+    }
+
+    //-----------------------------------------------------------------------
     public void test_checkRegionMatches_functionality() throws Exception {
         assertEquals(true, IOCase.SENSITIVE.checkRegionMatches("ABC", 0, ""));
         assertEquals(true, IOCase.SENSITIVE.checkRegionMatches("ABC", 0, "A"));



Mime
View raw message