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  * @deprecated Please use {@link java.net.URL#openConnection} instead.
53  *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
54  *     for further details.
55  */
56 @Deprecated
57 public class URLEncodedUtils {
58 
59     public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
60     private static final String PARAMETER_SEPARATOR = "&";
61     private static final String NAME_VALUE_SEPARATOR = "=";
62 
63     /**
64      * Returns a list of {@link NameValuePair NameValuePairs} as built from the
65      * URI's query portion. For example, a URI of
66      * http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three
67      * NameValuePairs, one for a=1, one for b=2, and one for c=3.
68      * <p>
69      * This is typically useful while parsing an HTTP PUT.
70      *
71      * @param uri
72      *            uri to parse
73      * @param encoding
74      *            encoding to use while parsing the query
75      */
76     public static List <NameValuePair> parse (final URI uri, final String encoding) {
77         List <NameValuePair> result = Collections.emptyList();
78         final String query = uri.getRawQuery();
79         if (query != null && query.length() > 0) {
80             result = new ArrayList <NameValuePair>();
81             parse(result, new Scanner(query), encoding);
82         }
83         return result;
84     }
85 
86     /**
87      * Returns a list of {@link NameValuePair NameValuePairs} as parsed from an
88      * {@link HttpEntity}. The encoding is taken from the entity's
89      * Content-Encoding header.
90      * <p>
91      * This is typically used while parsing an HTTP POST.
92      *
93      * @param entity
94      *            The entity to parse
95      * @throws IOException
96      *             If there was an exception getting the entity's data.
97      */
98     public static List <NameValuePair> parse (
99             final HttpEntity entity) throws IOException {
100         List <NameValuePair> result = Collections.emptyList();
101         if (isEncoded(entity)) {
102             final String content = EntityUtils.toString(entity);
103             final Header encoding = entity.getContentEncoding();
104             if (content != null && content.length() > 0) {
105                 result = new ArrayList <NameValuePair>();
106                 parse(result, new Scanner(content),
107                         encoding != null ? encoding.getValue() : null);
108             }
109         }
110         return result;
111     }
112 
113     /**
114      * Returns true if the entity's Content-Type header is
115      * <code>application/x-www-form-urlencoded</code>.
116      */
117     public static boolean isEncoded (final HttpEntity entity) {
118         final Header contentType = entity.getContentType();
119         return (contentType != null && contentType.getValue().equalsIgnoreCase(CONTENT_TYPE));
120     }
121 
122     /**
123      * Adds all parameters within the Scanner to the list of
124      * <code>parameters</code>, as encoded by <code>encoding</code>. For
125      * example, a scanner containing the string <code>a=1&b=2&c=3</code> would
126      * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the
127      * list of parameters.
128      *
129      * @param parameters
130      *            List to add parameters to.
131      * @param scanner
132      *            Input that contains the parameters to parse.
133      * @param encoding
134      *            Encoding to use when decoding the parameters.
135      */
136     public static void parse (
137             final List <NameValuePair> parameters,
138             final Scanner scanner,
139             final String encoding) {
140         scanner.useDelimiter(PARAMETER_SEPARATOR);
141         while (scanner.hasNext()) {
142             final String[] nameValue = scanner.next().split(NAME_VALUE_SEPARATOR);
143             if (nameValue.length == 0 || nameValue.length > 2)
144                 throw new IllegalArgumentException("bad parameter");
145 
146             final String name = decode(nameValue[0], encoding);
147             String value = null;
148             if (nameValue.length == 2)
149                 value = decode(nameValue[1], encoding);
150             parameters.add(new BasicNameValuePair(name, value));
151         }
152     }
153 
154     /**
155      * Returns a String that is suitable for use as an <code>application/x-www-form-urlencoded</code>
156      * list of parameters in an HTTP PUT or HTTP POST.
157      *
158      * @param parameters  The parameters to include.
159      * @param encoding The encoding to use.
160      */
161     public static String format (
162             final List <? extends NameValuePair> parameters,
163             final String encoding) {
164         final StringBuilder result = new StringBuilder();
165         for (final NameValuePair parameter : parameters) {
166             final String encodedName = encode(parameter.getName(), encoding);
167             final String value = parameter.getValue();
168             final String encodedValue = value != null ? encode(value, encoding) : "";
169             if (result.length() > 0)
170                 result.append(PARAMETER_SEPARATOR);
171             result.append(encodedName);
172             result.append(NAME_VALUE_SEPARATOR);
173             result.append(encodedValue);
174         }
175         return result.toString();
176     }
177 
178     private static String decode (final String content, final String encoding) {
179         try {
180             return URLDecoder.decode(content,
181                     encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET);
182         } catch (UnsupportedEncodingException problem) {
183             throw new IllegalArgumentException(problem);
184         }
185     }
186 
187     private static String encode (final String content, final String encoding) {
188         try {
189             return URLEncoder.encode(content,
190                     encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET);
191         } catch (UnsupportedEncodingException problem) {
192             throw new IllegalArgumentException(problem);
193         }
194     }
195 
196 }
197