Home | History | Annotate | Download | only in utils
      1 /*
      2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/utils/URLEncodedUtils.java $
      3  * $Revision: 655107 $
      4  * $Date: 2008-05-10 08:20:42 -0700 (Sat, 10 May 2008) $
      5  * ====================================================================
      6  * Licensed to the Apache Software Foundation (ASF) under one
      7  * or more contributor license agreements.  See the NOTICE file
      8  * distributed with this work for additional information
      9  * regarding copyright ownership.  The ASF licenses this file
     10  * to you under the Apache License, Version 2.0 (the
     11  * "License"); you may not use this file except in compliance
     12  * with the License.  You may obtain a copy of the License at
     13  *
     14  *   http://www.apache.org/licenses/LICENSE-2.0
     15  *
     16  * Unless required by applicable law or agreed to in writing,
     17  * software distributed under the License is distributed on an
     18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     19  * KIND, either express or implied.  See the License for the
     20  * specific language governing permissions and limitations
     21  * under the License.
     22  * ====================================================================
     23  *
     24  * This software consists of voluntary contributions made by many
     25  * individuals on behalf of the Apache Software Foundation.  For more
     26  * information on the Apache Software Foundation, please see
     27  * <http://www.apache.org/>.
     28  *
     29  */
     30 
     31 package org.apache.http.client.utils;
     32 
     33 import java.io.IOException;
     34 import java.io.UnsupportedEncodingException;
     35 import java.net.URI;
     36 import java.net.URLDecoder;
     37 import java.net.URLEncoder;
     38 import java.util.ArrayList;
     39 import java.util.Collections;
     40 import java.util.List;
     41 import java.util.Scanner;
     42 import org.apache.http.Header;
     43 import org.apache.http.HttpEntity;
     44 import org.apache.http.NameValuePair;
     45 import org.apache.http.message.BasicNameValuePair;
     46 import org.apache.http.protocol.HTTP;
     47 import org.apache.http.util.EntityUtils;
     48 
     49 /**
     50  * A collection of utilities for encoding URLs.
     51  */
     52 public class URLEncodedUtils {
     53 
     54     public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
     55     private static final String PARAMETER_SEPARATOR = "&";
     56     private static final String NAME_VALUE_SEPARATOR = "=";
     57 
     58     /**
     59      * Returns a list of {@link NameValuePair NameValuePairs} as built from the
     60      * URI's query portion. For example, a URI of
     61      * http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three
     62      * NameValuePairs, one for a=1, one for b=2, and one for c=3.
     63      * <p>
     64      * This is typically useful while parsing an HTTP PUT.
     65      *
     66      * @param uri
     67      *            uri to parse
     68      * @param encoding
     69      *            encoding to use while parsing the query
     70      */
     71     public static List <NameValuePair> parse (final URI uri, final String encoding) {
     72         List <NameValuePair> result = Collections.emptyList();
     73         final String query = uri.getRawQuery();
     74         if (query != null && query.length() > 0) {
     75             result = new ArrayList <NameValuePair>();
     76             parse(result, new Scanner(query), encoding);
     77         }
     78         return result;
     79     }
     80 
     81     /**
     82      * Returns a list of {@link NameValuePair NameValuePairs} as parsed from an
     83      * {@link HttpEntity}. The encoding is taken from the entity's
     84      * Content-Encoding header.
     85      * <p>
     86      * This is typically used while parsing an HTTP POST.
     87      *
     88      * @param entity
     89      *            The entity to parse
     90      * @throws IOException
     91      *             If there was an exception getting the entity's data.
     92      */
     93     public static List <NameValuePair> parse (
     94             final HttpEntity entity) throws IOException {
     95         List <NameValuePair> result = Collections.emptyList();
     96         if (isEncoded(entity)) {
     97             final String content = EntityUtils.toString(entity);
     98             final Header encoding = entity.getContentEncoding();
     99             if (content != null && content.length() > 0) {
    100                 result = new ArrayList <NameValuePair>();
    101                 parse(result, new Scanner(content),
    102                         encoding != null ? encoding.getValue() : null);
    103             }
    104         }
    105         return result;
    106     }
    107 
    108     /**
    109      * Returns true if the entity's Content-Type header is
    110      * <code>application/x-www-form-urlencoded</code>.
    111      */
    112     public static boolean isEncoded (final HttpEntity entity) {
    113         final Header contentType = entity.getContentType();
    114         return (contentType != null && contentType.getValue().equalsIgnoreCase(CONTENT_TYPE));
    115     }
    116 
    117     /**
    118      * Adds all parameters within the Scanner to the list of
    119      * <code>parameters</code>, as encoded by <code>encoding</code>. For
    120      * example, a scanner containing the string <code>a=1&b=2&c=3</code> would
    121      * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the
    122      * list of parameters.
    123      *
    124      * @param parameters
    125      *            List to add parameters to.
    126      * @param scanner
    127      *            Input that contains the parameters to parse.
    128      * @param encoding
    129      *            Encoding to use when decoding the parameters.
    130      */
    131     public static void parse (
    132             final List <NameValuePair> parameters,
    133             final Scanner scanner,
    134             final String encoding) {
    135         scanner.useDelimiter(PARAMETER_SEPARATOR);
    136         while (scanner.hasNext()) {
    137             final String[] nameValue = scanner.next().split(NAME_VALUE_SEPARATOR);
    138             if (nameValue.length == 0 || nameValue.length > 2)
    139                 throw new IllegalArgumentException("bad parameter");
    140 
    141             final String name = decode(nameValue[0], encoding);
    142             String value = null;
    143             if (nameValue.length == 2)
    144                 value = decode(nameValue[1], encoding);
    145             parameters.add(new BasicNameValuePair(name, value));
    146         }
    147     }
    148 
    149     /**
    150      * Returns a String that is suitable for use as an <code>application/x-www-form-urlencoded</code>
    151      * list of parameters in an HTTP PUT or HTTP POST.
    152      *
    153      * @param parameters  The parameters to include.
    154      * @param encoding The encoding to use.
    155      */
    156     public static String format (
    157             final List <? extends NameValuePair> parameters,
    158             final String encoding) {
    159         final StringBuilder result = new StringBuilder();
    160         for (final NameValuePair parameter : parameters) {
    161             final String encodedName = encode(parameter.getName(), encoding);
    162             final String value = parameter.getValue();
    163             final String encodedValue = value != null ? encode(value, encoding) : "";
    164             if (result.length() > 0)
    165                 result.append(PARAMETER_SEPARATOR);
    166             result.append(encodedName);
    167             result.append(NAME_VALUE_SEPARATOR);
    168             result.append(encodedValue);
    169         }
    170         return result.toString();
    171     }
    172 
    173     private static String decode (final String content, final String encoding) {
    174         try {
    175             return URLDecoder.decode(content,
    176                     encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET);
    177         } catch (UnsupportedEncodingException problem) {
    178             throw new IllegalArgumentException(problem);
    179         }
    180     }
    181 
    182     private static String encode (final String content, final String encoding) {
    183         try {
    184             return URLEncoder.encode(content,
    185                     encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET);
    186         } catch (UnsupportedEncodingException problem) {
    187             throw new IllegalArgumentException(problem);
    188         }
    189     }
    190 
    191 }
    192