| /* |
| * Copyright (C) 2008 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.text.TextUtils; |
| import android.text.util.Rfc822Token; |
| import android.text.util.Rfc822Tokenizer; |
| import android.widget.AutoCompleteTextView; |
| |
| import java.util.regex.Pattern; |
| |
| /** |
| * This class works as a Validator for AutoCompleteTextView for |
| * email addresses. If a token does not appear to be a valid address, |
| * it is trimmed of characters that cannot legitimately appear in one |
| * and has the specified domain name added. It is meant for use with |
| * {@link Rfc822Token} and {@link Rfc822Tokenizer}. |
| * |
| * @deprecated In the future make sure we don't quietly alter the user's |
| * text in ways they did not intend. Meanwhile, hide this |
| * class from the public API because it does not even have |
| * a full understanding of the syntax it claims to correct. |
| * @hide |
| */ |
| public class Rfc822Validator implements AutoCompleteTextView.Validator { |
| /* |
| * Regex.EMAIL_ADDRESS_PATTERN hardcodes the TLD that we accept, but we |
| * want to make sure we will keep accepting email addresses with TLD's |
| * that don't exist at the time of this writing, so this regexp relaxes |
| * that constraint by accepting any kind of top level domain, not just |
| * ".com", ".fr", etc... |
| */ |
| private static final Pattern EMAIL_ADDRESS_PATTERN = |
| Pattern.compile("[^\\s@]+@([^\\s@\\.]+\\.)+[a-zA-z][a-zA-Z][a-zA-Z]*"); |
| |
| private String mDomain; |
| |
| /** |
| * Constructs a new validator that uses the specified domain name as |
| * the default when none is specified. |
| */ |
| public Rfc822Validator(String domain) { |
| mDomain = domain; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isValid(CharSequence text) { |
| Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(text); |
| |
| return tokens.length == 1 && |
| EMAIL_ADDRESS_PATTERN. |
| matcher(tokens[0].getAddress()).matches(); |
| } |
| |
| /** |
| * @return a string in which all the characters that are illegal for the username |
| * or the domain name part of the email address have been removed. |
| */ |
| private String removeIllegalCharacters(String s) { |
| StringBuilder result = new StringBuilder(); |
| int length = s.length(); |
| for (int i = 0; i < length; i++) { |
| char c = s.charAt(i); |
| |
| /* |
| * An RFC822 atom can contain any ASCII printing character |
| * except for periods and any of the following punctuation. |
| * A local-part can contain multiple atoms, concatenated by |
| * periods, so do allow periods here. |
| */ |
| |
| if (c <= ' ' || c > '~') { |
| continue; |
| } |
| |
| if (c == '(' || c == ')' || c == '<' || c == '>' || |
| c == '@' || c == ',' || c == ';' || c == ':' || |
| c == '\\' || c == '"' || c == '[' || c == ']') { |
| continue; |
| } |
| |
| result.append(c); |
| } |
| return result.toString(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public CharSequence fixText(CharSequence cs) { |
| // Return an empty string if the email address only contains spaces, \n or \t |
| if (TextUtils.getTrimmedLength(cs) == 0) return ""; |
| |
| Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(cs); |
| StringBuilder sb = new StringBuilder(); |
| |
| for (int i = 0; i < tokens.length; i++) { |
| String text = tokens[i].getAddress(); |
| int index = text.indexOf('@'); |
| if (index < 0) { |
| // If there is no @, just append the domain of the account |
| tokens[i].setAddress(removeIllegalCharacters(text) + "@" + mDomain); |
| } else { |
| // Otherwise, remove the illegal characters on both sides of the '@' |
| String fix = removeIllegalCharacters(text.substring(0, index)); |
| String domain = removeIllegalCharacters(text.substring(index + 1)); |
| tokens[i].setAddress(fix + "@" + (domain.length() != 0 ? domain : mDomain)); |
| } |
| |
| sb.append(tokens[i].toString()); |
| if (i + 1 < tokens.length) { |
| sb.append(", "); |
| } |
| } |
| |
| return sb; |
| } |
| } |