ImportSupportpublic abstract class ImportSupport extends javax.servlet.jsp.tagext.BodyTagSupport implements ParamParent, javax.servlet.jsp.tagext.TryCatchFinallySupport for tag handlers for <import>, the general-purpose
text-importing mechanism for JSTL 1.0. The rtexprvalue and expression-
evaluating libraries each have handlers that extend this class. |
Fields Summary |
---|
public static final String | VALID_SCHEME_CHARS Valid characters in a scheme.
RFC 1738 says the following:
Scheme names consist of a sequence of characters. The lower
case letters "a"--"z", digits, and the characters plus ("+"),
period ("."), and hyphen ("-") are allowed. For resiliency,
programs interpreting URLs should treat upper case letters as
equivalent to lower case in scheme names (e.g., allow "HTTP" as
well as "http").
We treat as absolute any URL that begins with such a scheme name,
followed by a colon. | public static final String | DEFAULT_ENCODINGDefault character encoding for response. | protected String | url | protected String | context | protected String | charEncoding | private String | var | private int | scope | private String | varReader | private Reader | r | private boolean | isAbsoluteUrl | private ParamSupport.ParamManager | params | private String | urlWithParams |
Constructors Summary |
---|
public ImportSupport() // URL with parameters, if applicable
//*********************************************************************
// Constructor and initialization
super();
init();
|
Methods Summary |
---|
private java.io.Reader | acquireReader()
if (!isAbsoluteUrl) {
// for relative URLs, delegate to our peer
return new StringReader(acquireString());
} else {
// absolute URL
String target = targetUrl();
try {
// handle absolute URLs ourselves, using java.net.URL
URL u = new URL(target);
URLConnection uc = u.openConnection();
InputStream i = uc.getInputStream();
// okay, we've got a stream; encode it appropriately
Reader r = null;
String charSet;
if (charEncoding != null && !charEncoding.equals("")) {
charSet = charEncoding;
} else {
// charSet extracted according to RFC 2045, section 5.1
String contentType = uc.getContentType();
if (contentType != null) {
charSet = Util.getContentTypeAttribute(contentType, "charset");
if (charSet == null) charSet = DEFAULT_ENCODING;
} else {
charSet = DEFAULT_ENCODING;
}
}
try {
r = new InputStreamReader(i, charSet);
} catch (Exception ex) {
r = new InputStreamReader(i, DEFAULT_ENCODING);
}
// check response code for HTTP URLs before returning, per spec,
// before returning
if (uc instanceof HttpURLConnection) {
int status = ((HttpURLConnection) uc).getResponseCode();
if (status < 200 || status > 299)
throw new JspTagException(status + " " + target);
}
return r;
} catch (IOException ex) {
throw new JspException(
Resources.getMessage("IMPORT_ABS_ERROR", target, ex), ex);
} catch (RuntimeException ex) { // because the spec makes us
throw new JspException(
Resources.getMessage("IMPORT_ABS_ERROR", target, ex), ex);
}
}
| private java.lang.String | acquireString()
if (isAbsoluteUrl) {
// for absolute URLs, delegate to our peer
BufferedReader r = new BufferedReader(acquireReader());
StringBuffer sb = new StringBuffer();
int i;
// under JIT, testing seems to show this simple loop is as fast
// as any of the alternatives
//
// gmurray71 : putting in try/catch/finally block to make sure the
// reader is closed to fix a bug with file descriptors being left open
try {
while ((i = r.read()) != -1)
sb.append((char)i);
} catch (IOException iox) {
throw iox;
} finally {
r.close();
}
return sb.toString();
} else {
// handle relative URLs ourselves
// URL is relative, so we must be an HTTP request
if (!(pageContext.getRequest() instanceof HttpServletRequest
&& pageContext.getResponse() instanceof HttpServletResponse))
throw new JspTagException(
Resources.getMessage("IMPORT_REL_WITHOUT_HTTP"));
// retrieve an appropriate ServletContext
ServletContext c = null;
String targetUrl = targetUrl();
if (context != null)
c = pageContext.getServletContext().getContext(context);
else {
c = pageContext.getServletContext();
// normalize the URL if we have an HttpServletRequest
if (!targetUrl.startsWith("/")) {
String sp = ((HttpServletRequest)
pageContext.getRequest()).getServletPath();
targetUrl = sp.substring(0, sp.lastIndexOf('/"))
+ '/" + targetUrl;
}
}
if (c == null) {
throw new JspTagException(
Resources.getMessage(
"IMPORT_REL_WITHOUT_DISPATCHER", context, targetUrl));
}
// from this context, get a dispatcher
RequestDispatcher rd =
c.getRequestDispatcher(stripSession(targetUrl));
if (rd == null)
throw new JspTagException(stripSession(targetUrl));
// include the resource, using our custom wrapper
ImportResponseWrapper irw =
new ImportResponseWrapper(pageContext);
// spec mandates specific error handling form include()
try {
rd.include(pageContext.getRequest(), irw);
} catch (IOException ex) {
throw new JspException(ex);
} catch (RuntimeException ex) {
throw new JspException(ex);
} catch (ServletException ex) {
Throwable rc = ex.getRootCause();
if (rc == null)
throw new JspException(ex);
else
throw new JspException(rc);
}
// disallow inappropriate response codes per JSTL spec
if (irw.getStatus() < 200 || irw.getStatus() > 299) {
throw new JspTagException(irw.getStatus() + " " +
stripSession(targetUrl));
}
// recover the response String from our wrapper
return irw.getString();
}
| public void | addParameter(java.lang.String name, java.lang.String value)
params.addParameter(name, value);
| public void | doCatch(java.lang.Throwable t)
throw t;
| public int | doEndTag()
try {
// If we didn't expose a Reader earlier...
if (varReader == null) {
// ... store it in 'var', if available ...
if (var != null)
pageContext.setAttribute(var, acquireString(), scope);
// ... or simply output it, if we have nowhere to expose it
else
pageContext.getOut().print(acquireString());
}
return EVAL_PAGE;
} catch (IOException ex) {
throw new JspTagException(ex.toString(), ex);
}
| public void | doFinally()
try {
// If we exposed a Reader in doStartTag(), close it.
if (varReader != null) {
// 'r' can be null if an exception was thrown...
if (r != null)
r.close();
pageContext.removeAttribute(varReader, PageContext.PAGE_SCOPE);
}
} catch (IOException ex) {
// ignore it; close() failed, but there's nothing more we can do
}
| public int | doStartTag()
// Sanity check
if (context != null
&& (!context.startsWith("/") || !url.startsWith("/"))) {
throw new JspTagException(
Resources.getMessage("IMPORT_BAD_RELATIVE"));
}
// reset parameter-related state
urlWithParams = null;
params = new ParamSupport.ParamManager();
// check the URL
if (url == null || url.equals(""))
throw new NullAttributeException("import", "url");
// Record whether our URL is absolute or relative
isAbsoluteUrl = isAbsoluteUrl();
try {
// If we need to expose a Reader, we've got to do it right away
if (varReader != null) {
r = acquireReader();
pageContext.setAttribute(varReader, r);
}
} catch (IOException ex) {
throw new JspTagException(ex.toString(), ex);
}
return EVAL_BODY_INCLUDE;
| private void | init()
url = var = varReader = context = charEncoding = urlWithParams = null;
params = null;
scope = PageContext.PAGE_SCOPE;
| private boolean | isAbsoluteUrl()Returns true if our current URL is absolute,
false otherwise.
return isAbsoluteUrl(url);
| public static boolean | isAbsoluteUrl(java.lang.String url)Returns true if our current URL is absolute,
false otherwise.
// a null URL is not absolute, by our definition
if (url == null)
return false;
// do a fast, simple check first
int colonPos;
if ((colonPos = url.indexOf(":")) == -1)
return false;
// if we DO have a colon, make sure that every character
// leading up to it is a valid scheme character
for (int i = 0; i < colonPos; i++)
if (VALID_SCHEME_CHARS.indexOf(url.charAt(i)) == -1)
return false;
// if so, we've got an absolute url
return true;
| public void | release()
init();
super.release();
| public void | setScope(java.lang.String scope)
this.scope = Util.getScope(scope);
| public void | setVar(java.lang.String var)
this.var = var;
| public void | setVarReader(java.lang.String varReader)
this.varReader = varReader;
| public static java.lang.String | stripSession(java.lang.String url)Strips a servlet session ID from url. The session ID
is encoded as a URL "path parameter" beginning with "jsessionid=".
We thus remove anything we find between ";jsessionid=" (inclusive)
and either EOS or a subsequent ';' (exclusive).
StringBuffer u = new StringBuffer(url);
int sessionStart;
while ((sessionStart = u.toString().indexOf(";jsessionid=")) != -1) {
int sessionEnd = u.toString().indexOf(";", sessionStart + 1);
if (sessionEnd == -1)
sessionEnd = u.toString().indexOf("?", sessionStart + 1);
if (sessionEnd == -1) // still
sessionEnd = u.length();
u.delete(sessionStart, sessionEnd);
}
return u.toString();
| private java.lang.String | targetUrl()Returns our URL (potentially with parameters)
if (urlWithParams == null)
urlWithParams = params.aggregateParams(url);
return urlWithParams;
|
|