KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cactus > ServletURL


1 /*
2  * ========================================================================
3  *
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * ========================================================================
19  */

20 package org.apache.cactus;
21
22 import javax.servlet.http.HttpServletRequest JavaDoc;
23
24 import org.apache.cactus.internal.server.ServletUtil;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 /**
29  * Simulate an HTTP URL by breaking it into its different parts.
30  * <br><code><pre><b>
31  * URL = "http://" + serverName (including port) + requestURI ? queryString<br>
32  * requestURI = contextPath + servletPath + pathInfo
33  * </b></pre></code>
34  * From the Servlet 2.2 specification :<br>
35  * <code><pre><ul><li><b>Context Path</b>: The path prefix associated with the
36  * ServletContext that this servlet is a part of. If this context is the
37  * default context rooted at the base of the web server's URL namespace, this
38  * path will be an empty string. Otherwise, this path starts with a "/"
39  * character but does not end with a "/" character.</li>
40  * <li><b>Servlet Path</b>: The path section that directly corresponds to the
41  * mapping which activated this request. This path starts with a "/"
42  * character.</li>
43  * <li><b>PathInfo</b>: The part of the request path that is not part of the
44  * Context Path or the Servlet Path.</li></ul></pre></code>
45  * From the Servlet 2.3 specification :<br>
46  * <code><pre><ul><li><b>Context Path</b>: The path prefix associated with the
47  * ServletContext that this servlet is a part of. If this context is the
48  * default context rooted at the base of the web server's URL namespace, this
49  * path will be an empty string. Otherwise, this path starts with a "/"
50  * character but does not end with a "/" character.</li>
51  * <li><b>Servlet Path</b>: The path section that directly corresponds to the
52  * mapping which activated this request. This path starts with a "/"
53  * character <b>except in the case where the request is matched with the
54  * "/*" pattern, in which case it is the empty string</b>.</li>
55  * <li><b>PathInfo</b>: The part of the request path that is not part of the
56  * Context Path or the Servlet Path. <b>It is either null if there is no
57  * extra path, or is a string with a leading "/"</b>.</li></ul></pre></code>
58  *
59  * @version $Id: ServletURL.java,v 1.1 2004/05/22 11:34:45 vmassol Exp $
60  */

61 public class ServletURL
62 {
63     /**
64      * Name of the parameter in the HTTP request that represents the protocol
65      * (HTTP, HTTPS, etc) in the URL to simulate. The name is voluntarily long
66      * so that it will not clash with a user-defined parameter.
67      */

68     public static final String JavaDoc URL_PROTOCOL_PARAM = "Cactus_URL_Protocol";
69
70     /**
71      * Name of the parameter in the HTTP request that represents the Server
72      * name (+ port) in the URL to simulate. The name is voluntarily long so
73      * that it will not clash with a user-defined parameter.
74      */

75     public static final String JavaDoc URL_SERVER_NAME_PARAM = "Cactus_URL_Server";
76
77     /**
78      * Name of the parameter in the HTTP request that represents the context
79      * path in the URL to simulate. The name is voluntarily long so that it
80      * will not clash with a user-defined parameter.
81      */

82     public static final String JavaDoc URL_CONTEXT_PATH_PARAM =
83         "Cactus_URL_ContextPath";
84
85     /**
86      * Name of the parameter in the HTTP request that represents the Servlet
87      * Path in the URL to simulate. The name is voluntarily long so that it
88      * will not clash with a user-defined parameter.
89      */

90     public static final String JavaDoc URL_SERVLET_PATH_PARAM =
91         "Cactus_URL_ServletPath";
92
93     /**
94      * Name of the parameter in the HTTP request that represents the Path Info
95      * in the URL to simulate. The name is voluntarily long so that it will not
96      * clash with a user-defined parameter.
97      */

98     public static final String JavaDoc URL_PATH_INFO_PARAM = "Cactus_URL_PathInfo";
99
100     /**
101      * Name of the parameter in the HTTP request that represents the Query
102      * String in the URL to simulate. The name is voluntarily long so that it
103      * will not clash with a user-defined parameter.
104      */

105     public static final String JavaDoc URL_QUERY_STRING_PARAM =
106         "Cactus_URL_QueryString";
107
108     /**
109      * Http protocol.
110      */

111     public static final String JavaDoc PROTOCOL_HTTP = "http";
112
113     /**
114      * Https protocol.
115      */

116     public static final String JavaDoc PROTOCOL_HTTPS = "https";
117
118     /**
119      * Default port of the HTTP protocol.
120      */

121     private static final int DEFAULT_PORT_HTTP = 80;
122
123     /**
124      * Default port of HTTP over SSL.
125      */

126     private static final int DEFAULT_PORT_HTTPS = 443;
127
128     /**
129      * The logger
130      */

131     private static final Log LOGGER = LogFactory.getLog(ServletURL.class);
132
133     /**
134      * The server name to simulate (including port number)
135      */

136     private String JavaDoc serverName;
137
138     /**
139      * The context path to simulate
140      */

141     private String JavaDoc contextPath;
142
143     /**
144      * The servlet path to simulate
145      */

146     private String JavaDoc servletPath;
147
148     /**
149      * The Path Info to simulate
150      */

151     private String JavaDoc pathInfo;
152
153     /**
154      * The Query string
155      */

156     private String JavaDoc queryString;
157
158     /**
159      * The protocol to use. Default to HTTP.
160      */

161     private String JavaDoc protocol = PROTOCOL_HTTP;
162
163     /**
164      * Default constructor. Need to call the different setters to make this
165      * a valid object.
166      */

167     public ServletURL()
168     {
169     }
170
171     /**
172      * Creates the URL to simulate.
173      *
174      * @param theProtocol the protocol to simulate (either
175      * <code>ServletURL.PROTOCOL_HTTP</code> or
176      * <code>ServletURL.PROTOCOL_HTTPS</code>.
177      * @param theServerName the server name (and port) in the URL to simulate,
178      * i.e. this is the name that will be returned by the
179      * <code>HttpServletRequest.getServerName()</code> and
180      * <code>HttpServletRequest.getServerPort()</code>. Can
181      * be null. If null, then the server name and port from
182      * the Servlet Redirector will be returned.
183      * @param theContextPath the webapp context path in the URL to simulate,
184      * i.e. this is the name that will be returned by the
185      * <code>HttpServletRequest.getContextPath()</code>.
186      * Can be null. If null, then the context from the
187      * Servlet Redirector will be used.
188      * Format: "/" + name or an empty string for the
189      * default context. Must not end with a "/" character.
190      * @param theServletPath the servlet path in the URL to simulate,
191      * i.e. this is the name that will be returned by the
192      * <code>HttpServletRequest.getServletPath()</code>.
193      * Can be null. If null, then the servlet path from
194      * the Servlet Redirector will be used.
195      * Format : "/" + name or an empty string.
196      * @param thePathInfo the path info in the URL to simulate, i.e. this is
197      * the name that will be returned by the
198      * <code>HttpServletRequest.getPathInfo()</code>. Can
199      * be null. Format : "/" + name.
200      * @param theQueryString the Query string in the URL to simulate, i.e. this
201      * is the string that will be returned by the
202      * <code>HttpServletResquest.getQueryString()</code>.
203      * Can be null.
204      */

205     public ServletURL(String JavaDoc theProtocol, String JavaDoc theServerName,
206         String JavaDoc theContextPath, String JavaDoc theServletPath, String JavaDoc thePathInfo,
207         String JavaDoc theQueryString)
208     {
209         setProtocol(theProtocol);
210         setServerName(theServerName);
211         setContextPath(theContextPath);
212         setServletPath(theServletPath);
213         setPathInfo(thePathInfo);
214         setQueryString(theQueryString);
215     }
216
217     /**
218      * Creates the URL to simulate, using the default HTTP protocol.
219      *
220      * @param theServerName the server name (and port) in the URL to simulate,
221      * i.e. this is the name that will be returned by the
222      * <code>HttpServletRequest.getServerName()</code> and
223      * <code>HttpServletRequest.getServerPort()</code>. Can
224      * be null. If null, then the server name and port from
225      * the Servlet Redirector will be returned.
226      * @param theContextPath the webapp context path in the URL to simulate,
227      * i.e. this is the name that will be returned by the
228      * <code>HttpServletRequest.getContextPath()</code>.
229      * Can be null. If null, then the context from the
230      * Servlet Redirector will be used.
231      * Format: "/" + name or an empty string for the
232      * default context. Must not end with a "/" character.
233      * @param theServletPath the servlet path in the URL to simulate,
234      * i.e. this is the name that will be returned by the
235      * <code>HttpServletRequest.getServletPath()</code>.
236      * Can be null. If null, then the servlet path from
237      * the Servlet Redirector will be used.
238      * Format : "/" + name or an empty string.
239      * @param thePathInfo the path info in the URL to simulate, i.e. this is
240      * the name that will be returned by the
241      * <code>HttpServletRequest.getPathInfo()</code>. Can
242      * be null. Format : "/" + name.
243      * @param theQueryString the Query string in the URL to simulate, i.e. this
244      * is the string that will be returned by the
245      * <code>HttpServletResquest.getQueryString()</code>.
246      * Can be null.
247      */

248     public ServletURL(String JavaDoc theServerName, String JavaDoc theContextPath,
249         String JavaDoc theServletPath, String JavaDoc thePathInfo, String JavaDoc theQueryString)
250     {
251         this(PROTOCOL_HTTP, theServerName, theContextPath, theServletPath,
252             thePathInfo, theQueryString);
253     }
254
255     /**
256      * @return the protocol used to connect to the URL (HTTP, HTTPS, etc).
257      */

258     public String JavaDoc getProtocol()
259     {
260         return this.protocol;
261     }
262
263     /**
264      * Sets the protocol to simulate (either
265      * <code>ServletURL.PROTOCOL_HTTP</code> or
266      * <code>ServletURL.PROTOCOL_HTTPS</code>. If parameter is null then
267      * PROTOCOL_HTTP is assumed.
268      *
269      * @param theProtocol the protocol to simulate
270      */

271     public void setProtocol(String JavaDoc theProtocol)
272     {
273         // Only HTTP and HTTPS are currently supported.
274
if ((!theProtocol.equals(PROTOCOL_HTTP))
275             && (!theProtocol.equals(PROTOCOL_HTTPS)))
276         {
277             throw new RuntimeException JavaDoc("Invalid protocol [" + theProtocol
278                 + "]. Currently supported protocols are ["
279                 + PROTOCOL_HTTP + "] and ["
280                 + PROTOCOL_HTTPS + "].");
281         }
282
283         this.protocol = theProtocol;
284     }
285
286     /**
287      * @return the simulated URL server name (including the port number)
288      */

289     public String JavaDoc getServerName()
290     {
291         return this.serverName;
292     }
293
294     /**
295      * Sets the server name (and port) in the URL to simulate, ie this is the
296      * name that will be returned by the
297      * <code>HttpServletRequest.getServerName()</code> and
298      * <code>HttpServletRequest.getServerPort()</code>. Does not need to be
299      * set. If not set or null, then the server name and port from the Servlet
300      * Redirector will be returned.
301      *
302      * @param theServerName the server name and port (ex:
303      * "jakarta.apache.org:80")
304      */

305     public void setServerName(String JavaDoc theServerName)
306     {
307         this.serverName = theServerName;
308     }
309
310     /**
311      * Returns the host name.
312      *
313      * <p>
314      * The host name is extracted from the specified server name (as in
315      * <code><strong>jakarta.apache.org</strong>:80</code>). If the server
316      * name has not been set, this method will return <code>null</code>.
317      * </p>
318      *
319      * @return the simulated URL server name (excluding the port number)
320      */

321     public String JavaDoc getHost()
322     {
323         String JavaDoc host = getServerName();
324
325         if (host != null)
326         {
327             int pos = host.indexOf(":");
328
329             if (pos > 0)
330             {
331                 host = host.substring(0, pos);
332             }
333         }
334
335         return host;
336     }
337
338     /**
339      * Returns the port.
340      *
341      * <p>
342      * The port is extracted from the specified server name (as in
343      * <code>jakarta.apache.org:<strong>80</strong></code>). If the server
344      * name doesn't contain a port number, the default port number is returned
345      * (80 for HTTP, 443 for HTTP over SSL). If a port number is specified but
346      * illegal, or the server name has not been set, this method will return
347      * -1.
348      * </p>
349      *
350      * @return the simulated port number or -1 if an illegal port has been
351      * specified
352      */

353     public int getPort()
354     {
355         int port = -1;
356
357         if (getServerName() != null)
358         {
359             int pos = getServerName().indexOf(":");
360
361             if (pos < 0)
362             {
363                 // the server name doesn't contain a port specification, so use
364
// the default port for the protocol
365
port = getDefaultPort();
366             }
367             else
368             {
369                 // parse the port encoded in the server name
370
try
371                 {
372                     port = Integer.parseInt(getServerName().substring(pos + 1));
373                     if (port < 0)
374                     {
375                         port = -1;
376                     }
377                 }
378                 catch (NumberFormatException JavaDoc e)
379                 {
380                     port = -1;
381                 }
382             }
383         }
384
385         return port;
386     }
387
388     /**
389      * @return the simulated URL context path
390      */

391     public String JavaDoc getContextPath()
392     {
393         return this.contextPath;
394     }
395
396     /**
397      * Sets the webapp context path in the URL to simulate, ie this is the
398      * name that will be returned by the
399      * <code>HttpServletRequest.getContextPath()</code>. If not set, the
400      * context from the Servlet Redirector will be returned. Format: "/" +
401      * name or an empty string for the default context. If not an empty
402      * string the last character must not be "/".
403      *
404      * @param theContextPath the context path to simulate
405      */

406     public void setContextPath(String JavaDoc theContextPath)
407     {
408         if ((theContextPath != null) && (theContextPath.length() > 0))
409         {
410             if (!theContextPath.startsWith("/"))
411             {
412                 throw new IllegalArgumentException JavaDoc("The Context Path must"
413                     + " start with a \"/\" character.");
414             }
415             if (theContextPath.endsWith("/"))
416             {
417                 throw new IllegalArgumentException JavaDoc("The Context Path must not"
418                     + " end with a \"/\" character.");
419             }
420         }
421
422         this.contextPath = theContextPath;
423     }
424
425     /**
426      * @return the simulated URL servlet path
427      */

428     public String JavaDoc getServletPath()
429     {
430         return this.servletPath;
431     }
432
433     /**
434      * Sets the servlet path in the URL to simulate, ie this is the name that
435      * will be returned by the <code>HttpServletRequest.getServletPath()</code>.
436      * If null then the servlet path from the Servlet Redirector will be
437      * returned. Format : "/" + name or an empty string.
438      *
439      * @param theServletPath the servlet path to simulate
440      */

441     public void setServletPath(String JavaDoc theServletPath)
442     {
443         if ((theServletPath != null) && (theServletPath.length() > 0))
444         {
445             if (!theServletPath.startsWith("/"))
446             {
447                 throw new IllegalArgumentException JavaDoc("The Servlet Path must"
448                     + " start with a \"/\" character.");
449             }
450         }
451
452         this.servletPath = theServletPath;
453     }
454
455     /**
456      * @return the simulated URL path info
457      */

458     public String JavaDoc getPathInfo()
459     {
460         return this.pathInfo;
461     }
462
463     /**
464      * Sets the path info in the URL to simulate, ie this is the name that will
465      * be returned by the <code>HttpServletRequest.getPathInfo()</code>.
466      * If null then no path info will be set (and the Path Info from the
467      * Servlet Redirector will <b>not</b> be used).
468      * Format : "/" + name.
469      *
470      * @param thePathInfo the path info to simulate
471      */

472     public void setPathInfo(String JavaDoc thePathInfo)
473     {
474         if ((thePathInfo != null) && (thePathInfo.length() == 0))
475         {
476             throw new IllegalArgumentException JavaDoc("The Path Info must"
477                 + " not be an empty string. Use null if you don't"
478                 + " want to have a path info.");
479         }
480         else if (thePathInfo != null)
481         {
482             if (!thePathInfo.startsWith("/"))
483             {
484                 throw new IllegalArgumentException JavaDoc("The Path Info must"
485                     + " start with a \"/\" character.");
486             }
487         }
488
489         this.pathInfo = thePathInfo;
490     }
491
492     /**
493      * @return the simulated Query String
494      */

495     public String JavaDoc getQueryString()
496     {
497         return this.queryString;
498     }
499
500     /**
501      * Sets the Query string in the URL to simulate, ie this is the string that
502      * will be returned by the
503      * <code>HttpServletResquest.getQueryString()</code>. If not set, the
504      * query string from the Servlet Redirector will be returned.
505      *
506      * @param theQueryString the query string to simulate
507      */

508     public void setQueryString(String JavaDoc theQueryString)
509     {
510         this.queryString = theQueryString;
511     }
512
513     /**
514      * @return the path (contextPath + servletPath + pathInfo) or null if
515      * not set
516      */

517     public String JavaDoc getPath()
518     {
519         String JavaDoc path;
520
521         path = (getContextPath() == null) ? "" : getContextPath();
522         path += ((getServletPath() == null) ? "" : getServletPath());
523         path += ((getPathInfo() == null) ? "" : getPathInfo());
524
525         if (path.length() == 0)
526         {
527             path = null;
528         }
529
530         return path;
531     }
532
533     /**
534      * Saves the current URL to a <code>WebRequest</code> object.
535      *
536      * @param theRequest the object to which the current URL should be saved to
537      */

538     public void saveToRequest(WebRequest theRequest)
539     {
540         // Note: All these pareameters are passed in the URL. This is to allow
541
// the user to send whatever he wants in the request body. For example
542
// a file, ...
543
theRequest.addParameter(URL_PROTOCOL_PARAM, getProtocol(),
544             WebRequest.GET_METHOD);
545
546         if (getServerName() != null)
547         {
548             theRequest.addParameter(URL_SERVER_NAME_PARAM, getServerName(),
549                 WebRequest.GET_METHOD);
550         }
551
552         if (getContextPath() != null)
553         {
554             theRequest.addParameter(URL_CONTEXT_PATH_PARAM, getContextPath(),
555                 WebRequest.GET_METHOD);
556         }
557
558         if (getServletPath() != null)
559         {
560             theRequest.addParameter(URL_SERVLET_PATH_PARAM, getServletPath(),
561                 WebRequest.GET_METHOD);
562         }
563
564         if (getPathInfo() != null)
565         {
566             theRequest.addParameter(URL_PATH_INFO_PARAM, getPathInfo(),
567                 WebRequest.GET_METHOD);
568         }
569
570         if (getQueryString() != null)
571         {
572             theRequest.addParameter(URL_QUERY_STRING_PARAM, getQueryString(),
573                 WebRequest.GET_METHOD);
574         }
575     }
576
577     /**
578      * Creates a <code>ServletURL</code> object by loading it's values from the
579      * HTTP request.
580      *
581      * @param theRequest the incoming HTTP request.
582      * @return the <code>ServletURL</code> object unserialized from the HTTP
583      * request
584      */

585     public static ServletURL loadFromRequest(HttpServletRequest JavaDoc theRequest)
586     {
587         String JavaDoc qString = theRequest.getQueryString();
588         boolean isDefined = false;
589
590         ServletURL url = new ServletURL();
591
592         String JavaDoc protocol = ServletUtil.getQueryStringParameter(qString,
593             URL_PROTOCOL_PARAM);
594
595         if (protocol != null)
596         {
597             isDefined = true;
598             url.setProtocol(protocol);
599         }
600
601         String JavaDoc serverName = ServletUtil.getQueryStringParameter(qString,
602             URL_SERVER_NAME_PARAM);
603
604         if (serverName != null)
605         {
606             isDefined = true;
607             url.setServerName(serverName);
608         }
609
610         String JavaDoc contextPath = ServletUtil.getQueryStringParameter(qString,
611             URL_CONTEXT_PATH_PARAM);
612
613         if (contextPath != null)
614         {
615             isDefined = true;
616             url.setContextPath(contextPath);
617         }
618
619         String JavaDoc servletPath = ServletUtil.getQueryStringParameter(qString,
620             URL_SERVLET_PATH_PARAM);
621
622         if (servletPath != null)
623         {
624             isDefined = true;
625             url.setServletPath(servletPath);
626         }
627
628         String JavaDoc pathInfo = ServletUtil.getQueryStringParameter(qString,
629             URL_PATH_INFO_PARAM);
630
631         if (pathInfo != null)
632         {
633             isDefined = true;
634             url.setPathInfo(pathInfo);
635         }
636
637         String JavaDoc queryString = ServletUtil.getQueryStringParameter(qString,
638             URL_QUERY_STRING_PARAM);
639
640         if (queryString != null)
641         {
642             isDefined = true;
643             url.setQueryString(queryString);
644         }
645
646         if (!isDefined)
647         {
648             LOGGER.debug("Undefined simulation URL");
649             url = null;
650         }
651         else
652         {
653             LOGGER.debug("Simulation URL = [" + url + "]");
654         }
655
656         return url;
657     }
658
659     /**
660      * @return a string representation
661      */

662     public String JavaDoc toString()
663     {
664         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
665
666         buffer.append("protocol = [" + getProtocol() + "], ");
667         buffer.append("host name = [" + getHost() + "], ");
668         buffer.append("port = [" + getPort() + "], ");
669         buffer.append("context path = [" + getContextPath() + "], ");
670         buffer.append("servlet path = [" + getServletPath() + "], ");
671         buffer.append("path info = [" + getPathInfo() + "], ");
672         buffer.append("query string = [" + getQueryString() + "]");
673
674         return buffer.toString();
675     }
676
677     /**
678      * Returns the default port for the protocol.
679      *
680      * @return the default port (80 for HTTP, 443 for HTTP over SSL)
681      */

682     private int getDefaultPort()
683     {
684         if (PROTOCOL_HTTPS.equals(getProtocol()))
685         {
686             return DEFAULT_PORT_HTTPS;
687         }
688         else
689         {
690             return DEFAULT_PORT_HTTP;
691         }
692     }
693
694 }
695
Popular Tags