Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.text.util;
     18 
     19 import android.annotation.Nullable;
     20 
     21 /**
     22  * This class stores an RFC 822-like name, address, and comment,
     23  * and provides methods to convert them to quoted strings.
     24  */
     25 public class Rfc822Token {
     26     @Nullable
     27     private String mName, mAddress, mComment;
     28 
     29     /**
     30      * Creates a new Rfc822Token with the specified name, address,
     31      * and comment.
     32      */
     33     public Rfc822Token(@Nullable String name, @Nullable String address, @Nullable String comment) {
     34         mName = name;
     35         mAddress = address;
     36         mComment = comment;
     37     }
     38 
     39     /**
     40      * Returns the name part.
     41      */
     42     @Nullable
     43     public String getName() {
     44         return mName;
     45     }
     46 
     47     /**
     48      * Returns the address part.
     49      */
     50     @Nullable
     51     public String getAddress() {
     52         return mAddress;
     53     }
     54 
     55     /**
     56      * Returns the comment part.
     57      */
     58     @Nullable
     59     public String getComment() {
     60         return mComment;
     61     }
     62 
     63     /**
     64      * Changes the name to the specified name.
     65      */
     66     public void setName(@Nullable String name) {
     67         mName = name;
     68     }
     69 
     70     /**
     71      * Changes the address to the specified address.
     72      */
     73     public void setAddress(@Nullable String address) {
     74         mAddress = address;
     75     }
     76 
     77     /**
     78      * Changes the comment to the specified comment.
     79      */
     80     public void setComment(@Nullable String comment) {
     81         mComment = comment;
     82     }
     83 
     84     /**
     85      * Returns the name (with quoting added if necessary),
     86      * the comment (in parentheses), and the address (in angle brackets).
     87      * This should be suitable for inclusion in an RFC 822 address list.
     88      */
     89     public String toString() {
     90         StringBuilder sb = new StringBuilder();
     91 
     92         if (mName != null && mName.length() != 0) {
     93             sb.append(quoteNameIfNecessary(mName));
     94             sb.append(' ');
     95         }
     96 
     97         if (mComment != null && mComment.length() != 0) {
     98             sb.append('(');
     99             sb.append(quoteComment(mComment));
    100             sb.append(") ");
    101         }
    102 
    103         if (mAddress != null && mAddress.length() != 0) {
    104             sb.append('<');
    105             sb.append(mAddress);
    106             sb.append('>');
    107         }
    108 
    109         return sb.toString();
    110     }
    111 
    112     /**
    113      * Returns the name, conservatively quoting it if there are any
    114      * characters that are likely to cause trouble outside of a
    115      * quoted string, or returning it literally if it seems safe.
    116      */
    117     public static String quoteNameIfNecessary(String name) {
    118         int len = name.length();
    119 
    120         for (int i = 0; i < len; i++) {
    121             char c = name.charAt(i);
    122 
    123             if (! ((c >= 'A' && c <= 'Z') ||
    124                    (c >= 'a' && c <= 'z') ||
    125                    (c == ' ') ||
    126                    (c >= '0' && c <= '9'))) {
    127                 return '"' + quoteName(name) + '"';
    128             }
    129         }
    130 
    131         return name;
    132     }
    133 
    134     /**
    135      * Returns the name, with internal backslashes and quotation marks
    136      * preceded by backslashes.  The outer quote marks themselves are not
    137      * added by this method.
    138      */
    139     public static String quoteName(String name) {
    140         StringBuilder sb = new StringBuilder();
    141 
    142         int len = name.length();
    143         for (int i = 0; i < len; i++) {
    144             char c = name.charAt(i);
    145 
    146             if (c == '\\' || c == '"') {
    147                 sb.append('\\');
    148             }
    149 
    150             sb.append(c);
    151         }
    152 
    153         return sb.toString();
    154     }
    155 
    156     /**
    157      * Returns the comment, with internal backslashes and parentheses
    158      * preceded by backslashes.  The outer parentheses themselves are
    159      * not added by this method.
    160      */
    161     public static String quoteComment(String comment) {
    162         int len = comment.length();
    163         StringBuilder sb = new StringBuilder();
    164 
    165         for (int i = 0; i < len; i++) {
    166             char c = comment.charAt(i);
    167 
    168             if (c == '(' || c == ')' || c == '\\') {
    169                 sb.append('\\');
    170             }
    171 
    172             sb.append(c);
    173         }
    174 
    175         return sb.toString();
    176     }
    177 
    178     public int hashCode() {
    179         int result = 17;
    180         if (mName != null) result = 31 * result + mName.hashCode();
    181         if (mAddress != null) result = 31 * result + mAddress.hashCode();
    182         if (mComment != null) result = 31 * result + mComment.hashCode();
    183         return result;
    184     }
    185 
    186     private static boolean stringEquals(String a, String b) {
    187         if (a == null) {
    188             return (b == null);
    189         } else {
    190             return (a.equals(b));
    191         }
    192     }
    193 
    194     public boolean equals(Object o) {
    195         if (!(o instanceof Rfc822Token)) {
    196             return false;
    197         }
    198         Rfc822Token other = (Rfc822Token) o;
    199         return (stringEquals(mName, other.mName) &&
    200                 stringEquals(mAddress, other.mAddress) &&
    201                 stringEquals(mComment, other.mComment));
    202     }
    203 }
    204 
    205