diff --git a/res/xml/providers.xml b/res/xml/providers.xml index ed8637125..4d607d74a 100644 --- a/res/xml/providers.xml +++ b/res/xml/providers.xml @@ -4,9 +4,9 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,20 +16,20 @@ @@ -269,13 +292,13 @@ - + - + @@ -285,7 +308,7 @@ - @@ -357,99 +380,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -463,107 +398,15 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/src/com/android/email/activity/setup/AccountSettingsUtils.java b/src/com/android/email/activity/setup/AccountSettingsUtils.java index 99fff64ba..3cadc45e9 100644 --- a/src/com/android/email/activity/setup/AccountSettingsUtils.java +++ b/src/com/android/email/activity/setup/AccountSettingsUtils.java @@ -31,9 +31,15 @@ import android.util.Log; import android.widget.EditText; import java.io.Serializable; +import java.util.regex.Pattern; public class AccountSettingsUtils { + /** Pattern to match globals in the domain */ + private final static Pattern DOMAIN_GLOB_PATTERN = Pattern.compile("\\*"); + /** Will match any, single character */ + private final static char WILD_CHARACTER = '?'; + /** * Commits the UI-related settings of an account to the provider. This is static so that it * can be used by the various account activities. If the account has never been saved, this @@ -149,32 +155,34 @@ public class AccountSettingsUtils { } /** - * Compares the two strings. glob may have at most a single global character ('*') that - * will match any number of characters in the input string. - * @return true if the strings match. otherwise, false. - * @throws IllegalArgumentException if the strings are null or glob has multiple globals. + * Returns if the string s1 matches the string s2. The string + * s2 may contain any number of wildcards -- a '?' character -- and/or a + * single global character -- a '*' character. Wildcards match any, single character + * while a global character matches zero or more characters. + * @throws IllegalArgumentException if either string is null or s2 has + * multiple globals. */ - /*package*/ static boolean globMatchIgnoreCase(String in, String glob) + /*package*/ static boolean globMatchIgnoreCase(String s1, String s2) throws IllegalArgumentException { - if (in == null || glob == null) { + if (s1 == null || s2 == null) { throw new IllegalArgumentException("one or both strings are null"); } // Handle the possible global in the domain name - String[] globParts = glob.split("\\*"); - String inLower = in.toLowerCase(); + String[] globParts = DOMAIN_GLOB_PATTERN.split(s2); switch (globParts.length) { case 1: // No globals; test for simple equality - if (!inLower.equals(globParts[0].toLowerCase())) { + if (!wildEqualsIgnoreCase(s1, globParts[0])) { return false; } break; case 2: // Global; test the front & end parts of the domain - String d1 = globParts[0].toLowerCase(); - String d2 = globParts[1].toLowerCase(); - if (!inLower.startsWith(d1) || !inLower.substring(d1.length()).endsWith(d2)) { + String d1 = globParts[0]; + String d2 = globParts[1]; + if (!wildStartsWithIgnoreCase(s1, d1) || + !wildEndsWithIgnoreCase(s1.substring(d1.length()), d2)) { return false; } break; @@ -184,6 +192,62 @@ public class AccountSettingsUtils { return true; } + /** + * Returns if the string s1 equals the string s2. The string + * s2 may contain zero or more wildcards -- a '?' character. + * @throws IllegalArgumentException if the strings are null. + */ + /*package*/ static boolean wildEqualsIgnoreCase(String s1, String s2) + throws IllegalArgumentException { + if (s1 == null || s2 == null) { + throw new IllegalArgumentException("one or both strings are null"); + } + if (s1.length() != s2.length()) { + return false; + } + char[] charArray1 = s1.toLowerCase().toCharArray(); + char[] charArray2 = s2.toLowerCase().toCharArray(); + for (int i = 0; i < charArray2.length; i++) { + if (charArray2[i] == WILD_CHARACTER || charArray1[i] == charArray2[i]) continue; + return false; + } + return true; + } + + /** + * Returns if the string s1 starts with the string s2. The string + * s2 may contain zero or more wildcards -- a '?' character. + * @throws IllegalArgumentException if the strings are null. + */ + /*package*/ static boolean wildStartsWithIgnoreCase(String s1, String s2) + throws IllegalArgumentException { + if (s1 == null || s2 == null) { + throw new IllegalArgumentException("one or both strings are null"); + } + if (s1.length() < s2.length()) { + return false; + } + s1 = s1.substring(0, s2.length()); + return wildEqualsIgnoreCase(s1, s2); + } + + /** + * Returns if the string s1 ends with the string s2. The string + * s2 may contain zero or more wildcards -- a '?' character. + * @throws IllegalArgumentException if the strings are null. + */ + /*package*/ static boolean wildEndsWithIgnoreCase(String s1, String s2) + throws IllegalArgumentException { + if (s1 == null || s2 == null) { + throw new IllegalArgumentException("one or both strings are null"); + } + if (s1.length() < s2.length()) { + return false; + } + s1 = s1.substring(s1.length() - s2.length(), s1.length()); + return wildEqualsIgnoreCase(s1, s2); + } + /** * Attempts to get the given attribute as a String resource first, and if it fails * returns the attribute as a simple String value. @@ -216,6 +280,12 @@ public class AccountSettingsUtils { public String outgoingUri; public String outgoingUsername; public String note; + + /** + * Expands templates in all of the provider fields that support them. Currently, + * templates are used in 4 fields -- incoming and outgoing URI and user name. + * @param email user-specified data used to replace template values + */ public void expandTemplates(String email) { String[] emailParts = email.split("@"); String user = emailParts[0]; @@ -225,6 +295,11 @@ public class AccountSettingsUtils { outgoingUri = expandTemplate(outgoingUriTemplate, email, user); outgoingUsername = expandTemplate(outgoingUsernameTemplate, email, user); } + + /** + * Replaces all parameterized values in the given template. The values replaced are + * $domain, $user and $email. + */ private String expandTemplate(String template, String email, String user) { String returnString = template; returnString = returnString.replaceAll("\\$email", email); diff --git a/tests/res/xml/test_providers.xml b/tests/res/xml/test_providers.xml index 02642026e..2ed04ff4c 100644 --- a/tests/res/xml/test_providers.xml +++ b/tests/res/xml/test_providers.xml @@ -50,7 +50,7 @@ - + diff --git a/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java b/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java index 86a4fb192..583ec7849 100644 --- a/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java @@ -99,9 +99,40 @@ public class AccountSettingsUtilsTests extends AndroidTestCase { assertNull(testProvider); } - public void testGlobMatchIgnoreCase() { - boolean testMatch; + public void testGlobEndsWithIgnoreCase() { + assertTrue(AccountSettingsUtils.wildEndsWithIgnoreCase( + "yahoo.com.tw", ".??")); + assertTrue(AccountSettingsUtils.wildEndsWithIgnoreCase( + "abcd", "a??d")); + assertFalse(AccountSettingsUtils.wildEndsWithIgnoreCase( + "yahoo.com.tw.foo.com", ".??")); + assertFalse(AccountSettingsUtils.wildEndsWithIgnoreCase( + "abc", "a??d")); + } + public void testGlobStartsWithIgnoreCase() { + assertTrue(AccountSettingsUtils.wildStartsWithIgnoreCase( + "tw.yahoo.com", "??.")); + assertTrue(AccountSettingsUtils.wildStartsWithIgnoreCase( + "abcdxyz", "a??d")); + assertFalse(AccountSettingsUtils.wildStartsWithIgnoreCase( + "abc", "a??d")); + } + + public void testGlobEqualsIgnoreCase() { + assertTrue(AccountSettingsUtils.wildEqualsIgnoreCase( + "tw.yahoo.com", "??.yahoo.com")); + assertTrue(AccountSettingsUtils.wildEqualsIgnoreCase( + "yahoo.com.tw", "yahoo.com.??")); + assertTrue(AccountSettingsUtils.wildEqualsIgnoreCase( + "abcdxyz", "a??dxyz")); + assertFalse(AccountSettingsUtils.wildEqualsIgnoreCase( + "abc", "a??d")); + assertFalse(AccountSettingsUtils.wildEqualsIgnoreCase( + "abccxyz", "a??d")); + } + + public void testGlobMatchIgnoreCase() { assertTrue(AccountSettingsUtils.globMatchIgnoreCase( "mail.yahoo.com", "mail*yahoo.com")); assertTrue(AccountSettingsUtils.globMatchIgnoreCase(