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