1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.client.utils;
28
29 import java.net.URI;
30 import java.net.URISyntaxException;
31 import java.nio.charset.Charset;
32 import java.util.ArrayList;
33 import java.util.Iterator;
34 import java.util.List;
35
36 import org.apache.http.Consts;
37 import org.apache.http.NameValuePair;
38 import org.apache.http.annotation.NotThreadSafe;
39 import org.apache.http.conn.util.InetAddressUtils;
40 import org.apache.http.message.BasicNameValuePair;
41
42
43
44
45
46
47 @NotThreadSafe
48 public class URIBuilder {
49
50 private String scheme;
51 private String encodedSchemeSpecificPart;
52 private String encodedAuthority;
53 private String userInfo;
54 private String encodedUserInfo;
55 private String host;
56 private int port;
57 private String path;
58 private String encodedPath;
59 private String encodedQuery;
60 private List<NameValuePair> queryParams;
61 private String fragment;
62 private String encodedFragment;
63
64
65
66
67 public URIBuilder() {
68 super();
69 this.port = -1;
70 }
71
72
73
74
75
76
77
78 public URIBuilder(final String string) throws URISyntaxException {
79 super();
80 digestURI(new URI(string));
81 }
82
83
84
85
86
87 public URIBuilder(final URI uri) {
88 super();
89 digestURI(uri);
90 }
91
92 private List <NameValuePair> parseQuery(final String query, final Charset charset) {
93 if (query != null && query.length() > 0) {
94 return URLEncodedUtils.parse(query, charset);
95 }
96 return null;
97 }
98
99
100
101
102 public URI build() throws URISyntaxException {
103 return new URI(buildString());
104 }
105
106 private String buildString() {
107 StringBuilder sb = new StringBuilder();
108 if (this.scheme != null) {
109 sb.append(this.scheme).append(':');
110 }
111 if (this.encodedSchemeSpecificPart != null) {
112 sb.append(this.encodedSchemeSpecificPart);
113 } else {
114 if (this.encodedAuthority != null) {
115 sb.append("//").append(this.encodedAuthority);
116 } else if (this.host != null) {
117 sb.append("//");
118 if (this.encodedUserInfo != null) {
119 sb.append(this.encodedUserInfo).append("@");
120 } else if (this.userInfo != null) {
121 sb.append(encodeUserInfo(this.userInfo)).append("@");
122 }
123 if (InetAddressUtils.isIPv6Address(this.host)) {
124 sb.append("[").append(this.host).append("]");
125 } else {
126 sb.append(this.host);
127 }
128 if (this.port >= 0) {
129 sb.append(":").append(this.port);
130 }
131 }
132 if (this.encodedPath != null) {
133 sb.append(normalizePath(this.encodedPath));
134 } else if (this.path != null) {
135 sb.append(encodePath(normalizePath(this.path)));
136 }
137 if (this.encodedQuery != null) {
138 sb.append("?").append(this.encodedQuery);
139 } else if (this.queryParams != null) {
140 sb.append("?").append(encodeQuery(this.queryParams));
141 }
142 }
143 if (this.encodedFragment != null) {
144 sb.append("#").append(this.encodedFragment);
145 } else if (this.fragment != null) {
146 sb.append("#").append(encodeFragment(this.fragment));
147 }
148 return sb.toString();
149 }
150
151 private void digestURI(final URI uri) {
152 this.scheme = uri.getScheme();
153 this.encodedSchemeSpecificPart = uri.getRawSchemeSpecificPart();
154 this.encodedAuthority = uri.getRawAuthority();
155 this.host = uri.getHost();
156 this.port = uri.getPort();
157 this.encodedUserInfo = uri.getRawUserInfo();
158 this.userInfo = uri.getUserInfo();
159 this.encodedPath = uri.getRawPath();
160 this.path = uri.getPath();
161 this.encodedQuery = uri.getRawQuery();
162 this.queryParams = parseQuery(uri.getRawQuery(), Consts.UTF_8);
163 this.encodedFragment = uri.getRawFragment();
164 this.fragment = uri.getFragment();
165 }
166
167 private String encodeUserInfo(final String userInfo) {
168 return URLEncodedUtils.encUserInfo(userInfo, Consts.UTF_8);
169 }
170
171 private String encodePath(final String path) {
172 return URLEncodedUtils.encPath(path, Consts.UTF_8);
173 }
174
175 private String encodeQuery(final List<NameValuePair> params) {
176 return URLEncodedUtils.format(params, Consts.UTF_8);
177 }
178
179 private String encodeFragment(final String fragment) {
180 return URLEncodedUtils.encFragment(fragment, Consts.UTF_8);
181 }
182
183
184
185
186 public URIBuilder setScheme(final String scheme) {
187 this.scheme = scheme;
188 return this;
189 }
190
191
192
193
194
195 public URIBuilder setUserInfo(final String userInfo) {
196 this.userInfo = userInfo;
197 this.encodedSchemeSpecificPart = null;
198 this.encodedAuthority = null;
199 this.encodedUserInfo = null;
200 return this;
201 }
202
203
204
205
206
207 public URIBuilder setUserInfo(final String username, final String password) {
208 return setUserInfo(username + ':' + password);
209 }
210
211
212
213
214 public URIBuilder setHost(final String host) {
215 this.host = host;
216 this.encodedSchemeSpecificPart = null;
217 this.encodedAuthority = null;
218 return this;
219 }
220
221
222
223
224 public URIBuilder setPort(final int port) {
225 this.port = port < 0 ? -1 : port;
226 this.encodedSchemeSpecificPart = null;
227 this.encodedAuthority = null;
228 return this;
229 }
230
231
232
233
234 public URIBuilder setPath(final String path) {
235 this.path = path;
236 this.encodedSchemeSpecificPart = null;
237 this.encodedPath = null;
238 return this;
239 }
240
241
242
243
244 public URIBuilder removeQuery() {
245 this.queryParams = null;
246 this.encodedQuery = null;
247 this.encodedSchemeSpecificPart = null;
248 return this;
249 }
250
251
252
253
254
255
256 public URIBuilder setQuery(final String query) {
257 this.queryParams = parseQuery(query, Consts.UTF_8);
258 this.encodedQuery = null;
259 this.encodedSchemeSpecificPart = null;
260 return this;
261 }
262
263
264
265
266
267 public URIBuilder addParameter(final String param, final String value) {
268 if (this.queryParams == null) {
269 this.queryParams = new ArrayList<NameValuePair>();
270 }
271 this.queryParams.add(new BasicNameValuePair(param, value));
272 this.encodedQuery = null;
273 this.encodedSchemeSpecificPart = null;
274 return this;
275 }
276
277
278
279
280
281 public URIBuilder setParameter(final String param, final String value) {
282 if (this.queryParams == null) {
283 this.queryParams = new ArrayList<NameValuePair>();
284 }
285 if (!this.queryParams.isEmpty()) {
286 for (Iterator<NameValuePair> it = this.queryParams.iterator(); it.hasNext(); ) {
287 NameValuePair nvp = it.next();
288 if (nvp.getName().equals(param)) {
289 it.remove();
290 }
291 }
292 }
293 this.queryParams.add(new BasicNameValuePair(param, value));
294 this.encodedQuery = null;
295 this.encodedSchemeSpecificPart = null;
296 return this;
297 }
298
299
300
301
302
303 public URIBuilder setFragment(final String fragment) {
304 this.fragment = fragment;
305 this.encodedFragment = null;
306 return this;
307 }
308
309 public String getScheme() {
310 return this.scheme;
311 }
312
313 public String getUserInfo() {
314 return this.userInfo;
315 }
316
317 public String getHost() {
318 return this.host;
319 }
320
321 public int getPort() {
322 return this.port;
323 }
324
325 public String getPath() {
326 return this.path;
327 }
328
329 public List<NameValuePair> getQueryParams() {
330 if (this.queryParams != null) {
331 return new ArrayList<NameValuePair>(this.queryParams);
332 } else {
333 return new ArrayList<NameValuePair>();
334 }
335 }
336
337 public String getFragment() {
338 return this.fragment;
339 }
340
341 @Override
342 public String toString() {
343 return buildString();
344 }
345
346 private static String normalizePath(String path) {
347 if (path == null) {
348 return null;
349 }
350 int n = 0;
351 for (; n < path.length(); n++) {
352 if (path.charAt(n) != '/') {
353 break;
354 }
355 }
356 if (n > 1) {
357 path = path.substring(n - 1);
358 }
359 return path;
360 }
361
362 }