FileDocCategorySizeDatePackage
ImportSupport.javaAPI DocGlassfish v2 API21960Sat May 05 19:17:52 BST 2007org.apache.taglibs.standard.tag.common.core

ImportSupport

public abstract class ImportSupport extends javax.servlet.jsp.tagext.BodyTagSupport implements ParamParent, javax.servlet.jsp.tagext.TryCatchFinally

Support 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.

author
Shawn Bayern

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_ENCODING
Default 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.ReaderacquireReader()

        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.StringacquireString()

        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 voidaddParameter(java.lang.String name, java.lang.String value)

	params.addParameter(name, value);
    
public voiddoCatch(java.lang.Throwable t)

	throw t;
    
public intdoEndTag()

        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 voiddoFinally()

 
        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 intdoStartTag()

	// 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 voidinit()

	url = var = varReader = context = charEncoding = urlWithParams = null;
	params = null;
        scope = PageContext.PAGE_SCOPE;
    
private booleanisAbsoluteUrl()
Returns true if our current URL is absolute, false otherwise.

        return isAbsoluteUrl(url);
    
public static booleanisAbsoluteUrl(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 voidrelease()

	init();
        super.release();
    
public voidsetScope(java.lang.String scope)

	this.scope = Util.getScope(scope);
    
public voidsetVar(java.lang.String var)

	this.var = var;
    
public voidsetVarReader(java.lang.String varReader)

	this.varReader = varReader;
    
public static java.lang.StringstripSession(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.StringtargetUrl()
Returns our URL (potentially with parameters)

	if (urlWithParams == null)
	    urlWithParams = params.aggregateParams(url);
	return urlWithParams;