001: /*
002: * Created on Dec 9, 2004
003: */
004: package uk.org.ponder.servletutil;
005:
006: import java.net.MalformedURLException;
007: import java.net.URL;
008:
009: import javax.servlet.ServletContext;
010: import javax.servlet.http.HttpServletRequest;
011:
012: import uk.org.ponder.stringutil.URLUtil;
013: import uk.org.ponder.util.UniversalRuntimeException;
014:
015: /**
016: * A collection of primitive utilities for working with Servlets, in particular
017: * for inferring various parts of path components. This link is particularly
018: * useful in sorting out the various meanings of HttpServletRequest returns: <a
019: * href="http://javaalmanac.com/egs/javax.servlet/GetReqUrl.html?l=new">
020: * http://javaalmanac.com/egs/javax.servlet/GetReqUrl.html?l=new</a>
021: *
022: * @author Antranig Basman (antranig@caret.cam.ac.uk)
023: *
024: */
025: public class ServletUtil {
026: /**
027: * The "Base URL" is the full URL of this servlet, ignoring any extra path due
028: * to the particular request.
029: */
030: // TODO: It might well be more reliable to do this by simply knocking
031: // off "PathInfo" from RequestURL. Note that RequestURL can be the
032: // ORIGINAL url (before a dispatch) and hence not agree with a URL that
033: // could be used to invoke the current request.
034: // public static String getBaseURL(HttpServletRequest hsr) {
035: // String requestURL = hsr.getRequestURL().toString();
036: // String requestpath = hsr.getServletPath();
037: // int embedpoint = requestURL.indexOf(requestpath);
038: // if (embedpoint == -1) {
039: // throw new UniversalRuntimeException("Cannot locate request path of "
040: // + requestpath + " within request URL of " + requestURL);
041: // }
042: // String baseURL = requestURL.substring(0, embedpoint + requestpath.length()
043: // + 1);
044: // return baseURL;
045: // }
046: /**
047: * Computes the "Base URL" of this servlet, defined as the complete request
048: * path, with any trailing string agreeing with the "PathInfo" removed. With
049: * the exception that the trailing slash IS reappended.
050: */
051: public static String getBaseURL2(HttpServletRequest hsr) {
052: String requestURL = hsr.getRequestURL().toString();
053: // In some totally unspecced way, javax implementation provides the URL
054: // ENCODED, whereas the PathInfo UNENCODED.
055: requestURL = URLUtil.decodeURL(requestURL);
056: String extrapath = hsr.getPathInfo();
057: String togo;
058: if (extrapath == null || extrapath.equals("")
059: || extrapath.equals("/")) {
060: togo = requestURL;
061: } else {
062: int embedpoint = requestURL.lastIndexOf(extrapath);
063: if (embedpoint == -1) {
064: throw new UniversalRuntimeException(
065: "Cannot locate path info of " + extrapath
066: + " within request URL of "
067: + requestURL);
068: }
069: togo = requestURL.substring(0, embedpoint);
070: }
071: // I don't trust the Servlet API further than I can throw it.
072: if (togo.charAt(togo.length() - 1) != '/') {
073: togo += '/';
074: }
075: return togo;
076: }
077:
078: /*****************************************************************************
079: * Computes the "Context Base URL" of this servlet, which will include the
080: * extra stub of the path that refers to the mapping for the specific servlet.
081: */
082: public static String getContextBaseURL2(HttpServletRequest hsr) {
083: String baseurl = getBaseURL2(hsr);
084: String servletpath = hsr.getServletPath();
085: if (servletpath == null || servletpath == "") {
086: return baseurl;
087: }
088: int embedpoint = baseurl.lastIndexOf(servletpath);
089: if (embedpoint == -1) {
090: throw new UniversalRuntimeException(
091: "Cannot locate servlet path of " + servletpath
092: + " within base url of of " + baseurl);
093: }
094: String togo = baseurl.substring(0, embedpoint);
095: if (togo.charAt(togo.length() - 1) != '/') {
096: togo += '/';
097: }
098: return togo;
099: }
100:
101: //
102: // public static String getExtraPath(HttpServletRequest hsr) {
103: // String baseURL = getBaseURL(hsr);
104: // return hsr.getRequestURL().substring(baseURL.length());
105: // }
106: public static final String TEST_RESOURCE = "/WEB-INF/web.xml";
107:
108: /** Returns the context name of this ServletContext, using an algorithm
109: * based on using the context's web.xml file as a "test resource". This
110: * name will include both leading and trailing slash.
111: */
112: public static String computeContextName(ServletContext context) {
113: try {
114: URL weburl = context.getResource(TEST_RESOURCE);
115: String weburls = weburl.toExternalForm();
116: // plus one to include trailing slash
117: int backhack = 1 + weburls.length()
118: - TEST_RESOURCE.length();
119: int protpos = weburls.indexOf(":");
120: if (protpos == -1) {
121: throw new MalformedURLException(
122: "Could not find protocol in URL " + weburls);
123: }
124: ++protpos;
125: while (true) {
126: if (weburls.charAt(protpos) == '/')
127: ++protpos;
128: else
129: break;
130: }
131: int endhostpos = weburls.indexOf('/', protpos + 3);
132: if (endhostpos == -1) {
133: throw new MalformedURLException(
134: "Could not find host and protocol in URL "
135: + weburls);
136: }
137: return weburls.substring(endhostpos, backhack);
138: } catch (Exception e) {
139: throw UniversalRuntimeException.accumulate(e,
140: "Error computing context name");
141: }
142: }
143:
144: }
|