Home | History | Annotate | Download | only in net
      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.net;
     18 
     19 import java.util.HashMap;
     20 import java.util.Locale;
     21 import java.util.Map;
     22 import java.util.Set;
     23 
     24 /**
     25  *
     26  * MailTo URL parser
     27  *
     28  * This class parses a mailto scheme URL and then can be queried for
     29  * the parsed parameters. This implements RFC 2368.
     30  *
     31  */
     32 public class MailTo {
     33 
     34     static public final String MAILTO_SCHEME = "mailto:";
     35 
     36     // All the parsed content is added to the headers.
     37     private HashMap<String, String> mHeaders;
     38 
     39     // Well known headers
     40     static private final String TO = "to";
     41     static private final String BODY = "body";
     42     static private final String CC = "cc";
     43     static private final String SUBJECT = "subject";
     44 
     45 
     46     /**
     47      * Test to see if the given string is a mailto URL
     48      * @param url string to be tested
     49      * @return true if the string is a mailto URL
     50      */
     51     public static boolean isMailTo(String url) {
     52         if (url != null && url.startsWith(MAILTO_SCHEME)) {
     53             return true;
     54         }
     55         return false;
     56     }
     57 
     58     /**
     59      * Parse and decode a mailto scheme string. This parser implements
     60      * RFC 2368. The returned object can be queried for the parsed parameters.
     61      * @param url String containing a mailto URL
     62      * @return MailTo object
     63      * @exception ParseException if the scheme is not a mailto URL
     64      */
     65     public static MailTo parse(String url) throws ParseException {
     66         if (url == null) {
     67             throw new NullPointerException();
     68         }
     69         if (!isMailTo(url)) {
     70              throw new ParseException("Not a mailto scheme");
     71         }
     72         // Strip the scheme as the Uri parser can't cope with it.
     73         String noScheme = url.substring(MAILTO_SCHEME.length());
     74         Uri email = Uri.parse(noScheme);
     75         MailTo m = new MailTo();
     76 
     77         // Parse out the query parameters
     78         String query = email.getQuery();
     79         if (query != null ) {
     80             String[] queries = query.split("&");
     81             for (String q : queries) {
     82                 String[] nameval = q.split("=");
     83                 if (nameval.length == 0) {
     84                     continue;
     85                 }
     86                 // insert the headers with the name in lowercase so that
     87                 // we can easily find common headers
     88                 m.mHeaders.put(Uri.decode(nameval[0]).toLowerCase(Locale.ROOT),
     89                         nameval.length > 1 ? Uri.decode(nameval[1]) : null);
     90             }
     91         }
     92 
     93         // Address can be specified in both the headers and just after the
     94         // mailto line. Join the two together.
     95         String address = email.getPath();
     96         if (address != null) {
     97             String addr = m.getTo();
     98             if (addr != null) {
     99                 address += ", " + addr;
    100             }
    101             m.mHeaders.put(TO, address);
    102         }
    103 
    104         return m;
    105     }
    106 
    107     /**
    108      * Retrieve the To address line from the parsed mailto URL. This could be
    109      * several email address that are comma-space delimited.
    110      * If no To line was specified, then null is return
    111      * @return comma delimited email addresses or null
    112      */
    113     public String getTo() {
    114         return mHeaders.get(TO);
    115     }
    116 
    117     /**
    118      * Retrieve the CC address line from the parsed mailto URL. This could be
    119      * several email address that are comma-space delimited.
    120      * If no CC line was specified, then null is return
    121      * @return comma delimited email addresses or null
    122      */
    123     public String getCc() {
    124         return mHeaders.get(CC);
    125     }
    126 
    127     /**
    128      * Retrieve the subject line from the parsed mailto URL.
    129      * If no subject line was specified, then null is return
    130      * @return subject or null
    131      */
    132     public String getSubject() {
    133         return mHeaders.get(SUBJECT);
    134     }
    135 
    136     /**
    137      * Retrieve the body line from the parsed mailto URL.
    138      * If no body line was specified, then null is return
    139      * @return body or null
    140      */
    141     public String getBody() {
    142         return mHeaders.get(BODY);
    143     }
    144 
    145     /**
    146      * Retrieve all the parsed email headers from the mailto URL
    147      * @return map containing all parsed values
    148      */
    149     public Map<String, String> getHeaders() {
    150         return mHeaders;
    151     }
    152 
    153     @Override
    154     public String toString() {
    155         StringBuilder sb = new StringBuilder(MAILTO_SCHEME);
    156         sb.append('?');
    157         for (Map.Entry<String,String> header : mHeaders.entrySet()) {
    158             sb.append(Uri.encode(header.getKey()));
    159             sb.append('=');
    160             sb.append(Uri.encode(header.getValue()));
    161             sb.append('&');
    162         }
    163         return sb.toString();
    164     }
    165 
    166     /**
    167      * Private constructor. The only way to build a Mailto object is through
    168      * the parse() method.
    169      */
    170     private MailTo() {
    171         mHeaders = new HashMap<String, String>();
    172     }
    173 }
    174