From 5e4f1c38724927d7d41713e9e9ff073041d92d73 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Mon, 28 Mar 2011 16:21:15 -0700 Subject: [PATCH] Allow globals in the providers.xml There are two ways globals can be specified. There can be only one global character ['*'] and/or multiple wildcard characters ['?']. The global will match zero or more characters. The wildcard will match any character. bug 4090086 Change-Id: I07e3edebd1fe989094c68cf047ce5bc9fb91aba0 --- res/xml/providers.xml | 255 ++++-------------- .../activity/setup/AccountSettingsUtils.java | 99 ++++++- tests/res/xml/test_providers.xml | 2 +- .../setup/AccountSettingsUtilsTests.java | 35 ++- 4 files changed, 170 insertions(+), 221 deletions(-) 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(