Create android-common static library which gets included in frameworks.jar,
but can also be used by unbundled apps. Move android.text.util.Regex there as a starting example, renamed to a more sensible (?) com.android.common.Patterns. Set up a corresponding test package, and move RegexTest (to PatternsTest). Update clients.
This commit is contained in:
parent
526b33cda2
commit
a6f4698289
23
common/Android.mk
Normal file
23
common/Android.mk
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (C) 2009 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := android-common
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||
|
||||
# Include this library in the build server's output directory
|
||||
$(call dist-for-goals, droid, $(LOCAL_BUILT_MODULE):android-common.jar)
|
209
common/src/com/android/common/Patterns.java
Normal file
209
common/src/com/android/common/Patterns.java
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.common;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Commonly used regular expression patterns.
|
||||
*/
|
||||
public class Patterns {
|
||||
/**
|
||||
* Regular expression pattern to match all IANA top-level domains.
|
||||
* List accurate as of 2007/06/15. List taken from:
|
||||
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
|
||||
* This pattern is auto-generated by //device/tools/make-iana-tld-pattern.py
|
||||
*/
|
||||
public static final Pattern TOP_LEVEL_DOMAIN
|
||||
= Pattern.compile(
|
||||
"((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
|
||||
+ "|(biz|b[abdefghijmnorstvwyz])"
|
||||
+ "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
|
||||
+ "|d[ejkmoz]"
|
||||
+ "|(edu|e[cegrstu])"
|
||||
+ "|f[ijkmor]"
|
||||
+ "|(gov|g[abdefghilmnpqrstuwy])"
|
||||
+ "|h[kmnrtu]"
|
||||
+ "|(info|int|i[delmnoqrst])"
|
||||
+ "|(jobs|j[emop])"
|
||||
+ "|k[eghimnrwyz]"
|
||||
+ "|l[abcikrstuvy]"
|
||||
+ "|(mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
|
||||
+ "|(name|net|n[acefgilopruz])"
|
||||
+ "|(org|om)"
|
||||
+ "|(pro|p[aefghklmnrstwy])"
|
||||
+ "|qa"
|
||||
+ "|r[eouw]"
|
||||
+ "|s[abcdeghijklmnortuvyz]"
|
||||
+ "|(tel|travel|t[cdfghjklmnoprtvwz])"
|
||||
+ "|u[agkmsyz]"
|
||||
+ "|v[aceginu]"
|
||||
+ "|w[fs]"
|
||||
+ "|y[etu]"
|
||||
+ "|z[amw])");
|
||||
|
||||
/**
|
||||
* Regular expression pattern to match RFC 1738 URLs
|
||||
* List accurate as of 2007/06/15. List taken from:
|
||||
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
|
||||
* This pattern is auto-generated by //device/tools/make-iana-tld-pattern.py
|
||||
*/
|
||||
public static final Pattern WEB_URL
|
||||
= Pattern.compile(
|
||||
"((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
|
||||
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
|
||||
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
|
||||
+ "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+" // named host
|
||||
+ "(?:" // plus top level domain
|
||||
+ "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
|
||||
+ "|(?:biz|b[abdefghijmnorstvwyz])"
|
||||
+ "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
|
||||
+ "|d[ejkmoz]"
|
||||
+ "|(?:edu|e[cegrstu])"
|
||||
+ "|f[ijkmor]"
|
||||
+ "|(?:gov|g[abdefghilmnpqrstuwy])"
|
||||
+ "|h[kmnrtu]"
|
||||
+ "|(?:info|int|i[delmnoqrst])"
|
||||
+ "|(?:jobs|j[emop])"
|
||||
+ "|k[eghimnrwyz]"
|
||||
+ "|l[abcikrstuvy]"
|
||||
+ "|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
|
||||
+ "|(?:name|net|n[acefgilopruz])"
|
||||
+ "|(?:org|om)"
|
||||
+ "|(?:pro|p[aefghklmnrstwy])"
|
||||
+ "|qa"
|
||||
+ "|r[eouw]"
|
||||
+ "|s[abcdeghijklmnortuvyz]"
|
||||
+ "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
|
||||
+ "|u[agkmsyz]"
|
||||
+ "|v[aceginu]"
|
||||
+ "|w[fs]"
|
||||
+ "|y[etu]"
|
||||
+ "|z[amw]))"
|
||||
+ "|(?:(?:25[0-5]|2[0-4]" // or ip address
|
||||
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
|
||||
+ "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
|
||||
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
|
||||
+ "|[1-9][0-9]|[0-9])))"
|
||||
+ "(?:\\:\\d{1,5})?)" // plus option port number
|
||||
+ "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
|
||||
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
|
||||
+ "(?:\\b|$)"); // and finally, a word boundary or end of
|
||||
// input. This is to stop foo.sure from
|
||||
// matching as foo.su
|
||||
|
||||
public static final Pattern IP_ADDRESS
|
||||
= Pattern.compile(
|
||||
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
|
||||
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
|
||||
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
|
||||
+ "|[1-9][0-9]|[0-9]))");
|
||||
|
||||
public static final Pattern DOMAIN_NAME
|
||||
= Pattern.compile(
|
||||
"(((([a-zA-Z0-9][a-zA-Z0-9\\-]*)*[a-zA-Z0-9]\\.)+"
|
||||
+ TOP_LEVEL_DOMAIN + ")|"
|
||||
+ IP_ADDRESS + ")");
|
||||
|
||||
public static final Pattern EMAIL_ADDRESS
|
||||
= Pattern.compile(
|
||||
"[a-zA-Z0-9\\+\\.\\_\\%\\-]{1,256}" +
|
||||
"\\@" +
|
||||
"[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
|
||||
"(" +
|
||||
"\\." +
|
||||
"[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
|
||||
")+"
|
||||
);
|
||||
|
||||
/**
|
||||
* This pattern is intended for searching for things that look like they
|
||||
* might be phone numbers in arbitrary text, not for validating whether
|
||||
* something is in fact a phone number. It will miss many things that
|
||||
* are legitimate phone numbers.
|
||||
*
|
||||
* <p> The pattern matches the following:
|
||||
* <ul>
|
||||
* <li>Optionally, a + sign followed immediately by one or more digits. Spaces, dots, or dashes
|
||||
* may follow.
|
||||
* <li>Optionally, sets of digits in parentheses, separated by spaces, dots, or dashes.
|
||||
* <li>A string starting and ending with a digit, containing digits, spaces, dots, and/or dashes.
|
||||
* </ul>
|
||||
*/
|
||||
public static final Pattern PHONE
|
||||
= Pattern.compile( // sdd = space, dot, or dash
|
||||
"(\\+[0-9]+[\\- \\.]*)?" // +<digits><sdd>*
|
||||
+ "(\\([0-9]+\\)[\\- \\.]*)?" // (<digits>)<sdd>*
|
||||
+ "([0-9][0-9\\- \\.][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit>
|
||||
|
||||
/**
|
||||
* Convenience method to take all of the non-null matching groups in a
|
||||
* regex Matcher and return them as a concatenated string.
|
||||
*
|
||||
* @param matcher The Matcher object from which grouped text will
|
||||
* be extracted
|
||||
*
|
||||
* @return A String comprising all of the non-null matched
|
||||
* groups concatenated together
|
||||
*/
|
||||
public static final String concatGroups(Matcher matcher) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
final int numGroups = matcher.groupCount();
|
||||
|
||||
for (int i = 1; i <= numGroups; i++) {
|
||||
String s = matcher.group(i);
|
||||
|
||||
System.err.println("Group(" + i + ") : " + s);
|
||||
|
||||
if (s != null) {
|
||||
b.append(s);
|
||||
}
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to return only the digits and plus signs
|
||||
* in the matching string.
|
||||
*
|
||||
* @param matcher The Matcher object from which digits and plus will
|
||||
* be extracted
|
||||
*
|
||||
* @return A String comprising all of the digits and plus in
|
||||
* the match
|
||||
*/
|
||||
public static final String digitsAndPlusOnly(Matcher matcher) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
String matchingRegion = matcher.group();
|
||||
|
||||
for (int i = 0, size = matchingRegion.length(); i < size; i++) {
|
||||
char character = matchingRegion.charAt(i);
|
||||
|
||||
if (character == '+' || Character.isDigit(character)) {
|
||||
buffer.append(character);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not create this static utility class.
|
||||
*/
|
||||
private Patterns() {}
|
||||
}
|
26
common/tests/Android.mk
Normal file
26
common/tests/Android.mk
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (C) 2009 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_CERTIFICATE := platform
|
||||
LOCAL_JAVA_LIBRARIES := android.test.runner
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_PACKAGE_NAME := AndroidCommonTests
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := android-common
|
||||
|
||||
include $(BUILD_PACKAGE)
|
30
common/tests/AndroidManifest.xml
Normal file
30
common/tests/AndroidManifest.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||
|
||||
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.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.common.tests"
|
||||
android:sharedUserId="com.android.uid.test">
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
<!-- Run tests with "runtest common" -->
|
||||
<instrumentation android:name="android.test.InstrumentationTestRunner"
|
||||
android:targetPackage="com.android.common.tests"
|
||||
android:label="Android Common Library Tests" />
|
||||
|
||||
</manifest>
|
123
common/tests/src/com/android/common/PatternsTest.java
Normal file
123
common/tests/src/com/android/common/PatternsTest.java
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.common;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PatternsTest extends TestCase {
|
||||
|
||||
@SmallTest
|
||||
public void testTldPattern() throws Exception {
|
||||
boolean t;
|
||||
|
||||
t = Patterns.TOP_LEVEL_DOMAIN_PATTERN.matcher("com").matches();
|
||||
assertTrue("Missed valid TLD", t);
|
||||
|
||||
t = Patterns.TOP_LEVEL_DOMAIN_PATTERN.matcher("xer").matches();
|
||||
assertFalse("Matched invalid TLD!", t);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testUrlPattern() throws Exception {
|
||||
boolean t;
|
||||
|
||||
t = Patterns.WEB_URL_PATTERN.matcher("http://www.google.com").matches();
|
||||
assertTrue("Valid URL", t);
|
||||
|
||||
t = Patterns.WEB_URL_PATTERN.matcher("ftp://www.example.com").matches();
|
||||
assertFalse("Matched invalid protocol", t);
|
||||
|
||||
t = Patterns.WEB_URL_PATTERN.matcher("http://www.example.com:8080").matches();
|
||||
assertTrue("Didn't match valid URL with port", t);
|
||||
|
||||
t = Patterns.WEB_URL_PATTERN.matcher("http://www.example.com:8080/?foo=bar").matches();
|
||||
assertTrue("Didn't match valid URL with port and query args", t);
|
||||
|
||||
t = Patterns.WEB_URL_PATTERN.matcher("http://www.example.com:8080/~user/?foo=bar").matches();
|
||||
assertTrue("Didn't match valid URL with ~", t);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testIpPattern() throws Exception {
|
||||
boolean t;
|
||||
|
||||
t = Patterns.IP_ADDRESS_PATTERN.matcher("172.29.86.3").matches();
|
||||
assertTrue("Valid IP", t);
|
||||
|
||||
t = Patterns.IP_ADDRESS_PATTERN.matcher("1234.4321.9.9").matches();
|
||||
assertFalse("Invalid IP", t);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testDomainPattern() throws Exception {
|
||||
boolean t;
|
||||
|
||||
t = Patterns.DOMAIN_NAME_PATTERN.matcher("mail.example.com").matches();
|
||||
assertTrue("Valid domain", t);
|
||||
|
||||
t = Patterns.DOMAIN_NAME_PATTERN.matcher("__+&42.xer").matches();
|
||||
assertFalse("Invalid domain", t);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testPhonePattern() throws Exception {
|
||||
boolean t;
|
||||
|
||||
t = Patterns.PHONE_PATTERN.matcher("(919) 555-1212").matches();
|
||||
assertTrue("Valid phone", t);
|
||||
|
||||
t = Patterns.PHONE_PATTERN.matcher("2334 9323/54321").matches();
|
||||
assertFalse("Invalid phone", t);
|
||||
|
||||
String[] tests = {
|
||||
"Me: 16505551212 this\n",
|
||||
"Me: 6505551212 this\n",
|
||||
"Me: 5551212 this\n",
|
||||
|
||||
"Me: 1-650-555-1212 this\n",
|
||||
"Me: (650) 555-1212 this\n",
|
||||
"Me: +1 (650) 555-1212 this\n",
|
||||
"Me: +1-650-555-1212 this\n",
|
||||
"Me: 650-555-1212 this\n",
|
||||
"Me: 555-1212 this\n",
|
||||
|
||||
"Me: 1.650.555.1212 this\n",
|
||||
"Me: (650) 555.1212 this\n",
|
||||
"Me: +1 (650) 555.1212 this\n",
|
||||
"Me: +1.650.555.1212 this\n",
|
||||
"Me: 650.555.1212 this\n",
|
||||
"Me: 555.1212 this\n",
|
||||
|
||||
"Me: 1 650 555 1212 this\n",
|
||||
"Me: (650) 555 1212 this\n",
|
||||
"Me: +1 (650) 555 1212 this\n",
|
||||
"Me: +1 650 555 1212 this\n",
|
||||
"Me: 650 555 1212 this\n",
|
||||
"Me: 555 1212 this\n",
|
||||
};
|
||||
|
||||
for (String test : tests) {
|
||||
Matcher m = Patterns.PHONE_PATTERN.matcher(test);
|
||||
|
||||
assertTrue("Valid phone " + test, m.find());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user