View Javadoc

1   /*
2    * Copyright [2006] [University Corporation for Advanced Internet Development, Inc.]
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 org.opensaml.util;
18  
19  import java.net.MalformedURLException;
20  import java.net.URL;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.opensaml.ws.transport.http.HTTPTransportUtils;
25  import org.opensaml.xml.util.DatatypeHelper;
26  import org.opensaml.xml.util.Pair;
27  
28  /**
29   * Utility class for building URLs. May also be used to parse a URL into its invidual components. All components will be
30   * converted UTF-8 encoding and then application/x-www-form-urlencoded when built.
31   * 
32   * This class is not thread-safe.
33   */
34  public class URLBuilder {
35  
36      /** URL schema (http, https, etc). */
37      private String scheme;
38  
39      /** User name in the URL. */
40      private String username;
41  
42      /** Password in the URL. */
43      private String password;
44  
45      /** Host for the URL. */
46      private String host;
47  
48      /** URL port number. */
49      private int port;
50  
51      /** URL path. */
52      private String path;
53  
54      /** Parameters in the query string. */
55      private List<Pair<String, String>> queryParams;
56  
57      /** URL fragment. */
58      private String fragement;
59  
60      /**
61       * Constructor.
62       */
63      public URLBuilder() {
64          queryParams = new ArrayList<Pair<String, String>>();
65      }
66  
67      /**
68       * Constructor.
69       * 
70       * @param baseURL URL to parse and use as basis for creating other URLs
71       * 
72       * @throws IllegalArgumentException thrown if the given base URL is not well formed
73       */
74      public URLBuilder(String baseURL) {
75          try {
76              URL url = new URL(baseURL);
77  
78              setScheme(url.getProtocol());
79  
80              String userInfo = url.getUserInfo();
81              if (!DatatypeHelper.isEmpty(userInfo)) {
82                  if (userInfo.contains(":")) {
83                      String[] userInfoComps = userInfo.split(":");
84                      setUsername(HTTPTransportUtils.urlDecode(userInfoComps[0]));
85                      setPassword(HTTPTransportUtils.urlDecode(userInfoComps[1]));
86                  } else {
87                      setUsername(userInfo);
88                  }
89              }
90  
91              setHost(url.getHost());
92              setPort(url.getPort());
93              setPath(url.getPath());
94  
95              queryParams = new ArrayList<Pair<String, String>>();
96              String queryString = url.getQuery();
97              if (!DatatypeHelper.isEmpty(queryString)) {
98                  String[] queryComps = queryString.split("&");
99                  String queryComp;
100                 String[] paramComps;
101                 String paramName;
102                 String paramValue;
103                 for (int i = 0; i < queryComps.length; i++) {
104                     queryComp = queryComps[i];
105                     if (!queryComp.contains("=")) {
106                         paramName = HTTPTransportUtils.urlDecode(queryComp);
107                         queryParams.add(new Pair<String, String>(paramName, null));
108                     } else {
109                         paramComps = queryComp.split("=");
110                         paramName = HTTPTransportUtils.urlDecode(paramComps[0]);
111                         paramValue = HTTPTransportUtils.urlDecode(paramComps[1]);
112                         queryParams.add(new Pair<String, String>(paramName, paramValue));
113                     }
114                 }
115             }
116 
117             setFragment(url.getRef());
118         } catch (MalformedURLException e) {
119             throw new IllegalArgumentException("Given URL is not well formed", e);
120         }
121     }
122 
123     /**
124      * Gets the URL fragment in its decoded form.
125      * 
126      * @return URL fragment in its decoded form
127      */
128     public String getFragment() {
129         return fragement;
130     }
131 
132     /**
133      * Sets the URL fragment in its decoded form.
134      * 
135      * @param newFragment URL fragment in its decoded form
136      */
137     public void setFragment(String newFragment) {
138         fragement = DatatypeHelper.safeTrimOrNullString(newFragment);
139     }
140 
141     /**
142      * Gets the host component of the URL.
143      * 
144      * @return host component of the URL
145      */
146     public String getHost() {
147         return host;
148     }
149 
150     /**
151      * Sets the host component of the URL.
152      * 
153      * @param newHost host component of the URL
154      */
155     public void setHost(String newHost) {
156         host = DatatypeHelper.safeTrimOrNullString(newHost);
157     }
158 
159     /**
160      * Gets the user's password in the URL.
161      * 
162      * @return user's password in the URL
163      */
164     public String getPassword() {
165         return password;
166     }
167 
168     /**
169      * Sets the user's password in the URL.
170      * 
171      * @param newPassword user's password in the URL
172      */
173     public void setPassword(String newPassword) {
174         password = DatatypeHelper.safeTrimOrNullString(newPassword);
175     }
176 
177     /**
178      * Gets the path component of the URL.
179      * 
180      * @return path component of the URL
181      */
182     public String getPath() {
183         return path;
184     }
185 
186     /**
187      * Sets the path component of the URL.
188      * 
189      * @param newPath path component of the URL
190      */
191     public void setPath(String newPath) {
192         path = DatatypeHelper.safeTrimOrNullString(newPath);
193     }
194 
195     /**
196      * Gets the port component of the URL.
197      * 
198      * @return port component of the URL
199      */
200     public int getPort() {
201         return port;
202     }
203 
204     /**
205      * Sets the port component of the URL.
206      * 
207      * @param newPort port component of the URL
208      */
209     public void setPort(int newPort) {
210         port = newPort;
211     }
212 
213     /**
214      * Gets the query string parameters for the URL. Params may be added and removed through the map interface.
215      * 
216      * @return query string parameters for the URL
217      */
218     public List<Pair<String, String>> getQueryParams() {
219         return queryParams;
220     }
221 
222     /**
223      * Gets the URL scheme (http, https, etc).
224      * 
225      * @return URL scheme (http, https, etc)
226      */
227     public String getScheme() {
228         return scheme;
229     }
230 
231     /**
232      * Sets the URL scheme (http, https, etc).
233      * 
234      * @param newScheme URL scheme (http, https, etc)
235      */
236     public void setScheme(String newScheme) {
237         scheme = DatatypeHelper.safeTrimOrNullString(newScheme);
238     }
239 
240     /**
241      * Gets the user name component of the URL.
242      * 
243      * @return user name component of the URL
244      */
245     public String getUsername() {
246         return username;
247     }
248 
249     /**
250      * Sets the user name component of the URL.
251      * 
252      * @param newUsername user name component of the URL
253      */
254     public void setUsername(String newUsername) {
255         username = DatatypeHelper.safeTrimOrNullString(newUsername);
256     }
257 
258     /**
259      * Builds a URL from the given data. The constructured URL may not be valid if sufficient information is not
260      * provided. The returned URL will be appropriately encoded using application/x-www-form-urlencoded with appropriate
261      * encoding of UTF-8 characters.
262      * 
263      * @return URL built from the given data
264      */
265     public String buildURL() {
266         StringBuilder builder = new StringBuilder();
267 
268         if (!DatatypeHelper.isEmpty(scheme)) {
269             builder.append(scheme);
270             builder.append("://");
271         }
272 
273         if (!DatatypeHelper.isEmpty(username)) {
274             builder.append(username);
275             if (!DatatypeHelper.isEmpty(password)) {
276                 builder.append(":");
277                 builder.append(password);
278             }
279 
280             builder.append("@");
281         }
282 
283         if (!DatatypeHelper.isEmpty(host)) {
284             builder.append(host);
285             if (port > 0) {
286                 builder.append(":");
287                 builder.append(Integer.toString(port));
288             }
289         }
290 
291         if (!DatatypeHelper.isEmpty(path)) {
292             if (!path.startsWith("/")) {
293                 builder.append("/");
294             }
295             builder.append(path);
296         }
297 
298         String queryString = buildQueryString();
299         if (!DatatypeHelper.isEmpty(queryString)) {
300             builder.append("?");
301             builder.append(queryString);
302         }
303 
304         if (!DatatypeHelper.isEmpty(fragement)) {
305             builder.append("#");
306             builder.append(fragement);
307         }
308 
309         return builder.toString();
310     }
311 
312     /**
313      * Builds the query string for the URL.
314      * 
315      * @return query string for the URL or null if there are now query parameters
316      */
317     public String buildQueryString() {
318         StringBuilder builder = new StringBuilder();
319         if (queryParams.size() > 0) {
320             String name;
321             String value;
322 
323             Pair<String, String> param;
324             for (int i = 0; i < queryParams.size(); i++) {
325                 param = queryParams.get(i);
326                 name = DatatypeHelper.safeTrimOrNullString(param.getFirst());
327 
328                 if (name != null) {
329                     builder.append(HTTPTransportUtils.urlEncode(name));
330                     value = DatatypeHelper.safeTrimOrNullString(param.getSecond());
331                     if (value != null) {
332                         builder.append("=");
333                         builder.append(HTTPTransportUtils.urlEncode(value));
334                     }
335                     if (i < queryParams.size() - 1) {
336                         builder.append("&");
337                     }
338                 }
339             }
340             return builder.toString();
341         }
342 
343         return null;
344     }
345 }