FileDocCategorySizeDatePackage
JspServletWrapper.javaAPI DocApache Tomcat 6.0.1419403Fri Jul 20 04:20:32 BST 2007org.apache.jasper.servlet

JspServletWrapper

public class JspServletWrapper extends Object
The JSP engine (a.k.a Jasper). The servlet container is responsible for providing a URLClassLoader for the web application context Jasper is being used in. Jasper will try get the Tomcat ServletContext attribute for its ServletContext class loader, if that fails, it uses the parent class loader. In either case, it must be a URLClassLoader.
author
Anil K. Vijendran
author
Harish Prabandham
author
Remy Maucherat
author
Kin-man Chung
author
Glenn Nielsen
author
Tim Fennell

Fields Summary
private org.apache.juli.logging.Log
log
private Servlet
theServlet
private String
jspUri
private Class
servletClass
private Class
tagHandlerClass
private org.apache.jasper.JspCompilationContext
ctxt
private long
available
private ServletConfig
config
private org.apache.jasper.Options
options
private boolean
firstTime
private boolean
reload
private boolean
isTagFile
private int
tripCount
private org.apache.jasper.JasperException
compileException
private long
servletClassLastModifiedTime
private long
lastModificationTest
Constructors Summary
public JspServletWrapper(ServletConfig config, org.apache.jasper.Options options, String jspUri, boolean isErrorPage, org.apache.jasper.compiler.JspRuntimeContext rctxt)


    /*
     * JspServletWrapper for JSP pages.
     */
          
                         
              

	this.isTagFile = false;
        this.config = config;
        this.options = options;
        this.jspUri = jspUri;
        ctxt = new JspCompilationContext(jspUri, isErrorPage, options,
					 config.getServletContext(),
					 this, rctxt);
    
public JspServletWrapper(ServletContext servletContext, org.apache.jasper.Options options, String tagFilePath, javax.servlet.jsp.tagext.TagInfo tagInfo, org.apache.jasper.compiler.JspRuntimeContext rctxt, URL tagFileJarUrl)


	this.isTagFile = true;
        this.config = null;	// not used
        this.options = options;
	this.jspUri = tagFilePath;
	this.tripCount = 0;
        ctxt = new JspCompilationContext(jspUri, tagInfo, options,
					 servletContext, this, rctxt,
					 tagFileJarUrl);
    
Methods Summary
public intdecTripCount()

	return tripCount--;
    
public voiddestroy()

        if (theServlet != null) {
            theServlet.destroy();
            AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
            if (annotationProcessor != null) {
                try {
                    annotationProcessor.preDestroy(theServlet);
                } catch (Exception e) {
                    // Log any exception, since it can't be passed along
                    log.error(Localizer.getMessage("jsp.error.file.not.found",
                           e.getMessage()), e);
                }
            }
        }
    
public java.util.ListgetDependants()
Get a list of files that the current page has source dependency on.

        try {
            Object target;
            if (isTagFile) {
                if (reload) {
                    tagHandlerClass = ctxt.load();
                    reload = false;
                }
                target = tagHandlerClass.newInstance();
            } else {
                target = getServlet();
            }
            if (target != null && target instanceof JspSourceDependent) {
                return ((java.util.List) ((JspSourceDependent) target).getDependants());
            }
        } catch (Throwable ex) {
        }
        return null;
    
public org.apache.jasper.JspCompilationContextgetJspEngineContext()

        return ctxt;
    
public longgetLastModificationTest()

return
Returns the lastModificationTest.

        return lastModificationTest;
    
public javax.servlet.ServletgetServlet()

        if (reload) {
            synchronized (this) {
                // Synchronizing on jsw enables simultaneous loading
                // of different pages, but not the same page.
                if (reload) {
                    // This is to maintain the original protocol.
                    destroy();
                    
                    Servlet servlet = null;
                    
                    try {
                        servletClass = ctxt.load();
                        servlet = (Servlet) servletClass.newInstance();
                        AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
                        if (annotationProcessor != null) {
                           annotationProcessor.processAnnotations(servlet);
                           annotationProcessor.postConstruct(servlet);
                        }
                    } catch (IllegalAccessException e) {
                        throw new JasperException(e);
                    } catch (InstantiationException e) {
                        throw new JasperException(e);
                    } catch (Exception e) {
                        throw new JasperException(e);
                    }
                    
                    servlet.init(config);

                    if (!firstTime) {
                        ctxt.getRuntimeContext().incrementJspReloadCount();
                    }

                    theServlet = servlet;
                    reload = false;
                }
            }    
        }
        return theServlet;
    
public javax.servlet.ServletContextgetServletContext()

        return config.getServletContext();
    
protected org.apache.jasper.JasperExceptionhandleJspException(java.lang.Exception ex)

Attempts to construct a JasperException that contains helpful information about what went wrong. Uses the JSP compiler system to translate the line number in the generated servlet that originated the exception to a line number in the JSP. Then constructs an exception containing that information, and a snippet of the JSP to help debugging. Please see http://issues.apache.org/bugzilla/show_bug.cgi?id=37062 and http://www.tfenne.com/jasper/ for more details.

param
ex the exception that was the cause of the problem.
return
a JasperException with more detailed information

        try {
            Throwable realException = ex;
            if (ex instanceof ServletException) {
                realException = ((ServletException) ex).getRootCause();
            }

            // First identify the stack frame in the trace that represents the JSP
            StackTraceElement[] frames = realException.getStackTrace();
            StackTraceElement jspFrame = null;

            for (int i=0; i<frames.length; ++i) {
                if ( frames[i].getClassName().equals(this.getServlet().getClass().getName()) ) {
                    jspFrame = frames[i];
                    break;
                }
            }

            if (jspFrame == null) {
                // If we couldn't find a frame in the stack trace corresponding
                // to the generated servlet class, we can't really add anything
                return new JasperException(ex);
            }
            else {
                int javaLineNumber = jspFrame.getLineNumber();
                JavacErrorDetail detail = ErrorDispatcher.createJavacError(
                        jspFrame.getMethodName(),
                        this.ctxt.getCompiler().getPageNodes(),
                        null,
                        javaLineNumber,
                        ctxt);

                // If the line number is less than one we couldn't find out
                // where in the JSP things went wrong
                int jspLineNumber = detail.getJspBeginLineNumber();
                if (jspLineNumber < 1) {
                    throw new JasperException(ex);
                }

                if (options.getDisplaySourceFragment()) {
                    return new JasperException(Localizer.getMessage
                            ("jsp.exception", detail.getJspFileName(),
                                    "" + jspLineNumber) +
                                    "\n\n" + detail.getJspExtract() +
                                    "\n\nStacktrace:", ex);
                    
                } else {
                    return new JasperException(Localizer.getMessage
                            ("jsp.exception", detail.getJspFileName(),
                                    "" + jspLineNumber), ex);
                }
            }
        } catch (Exception je) {
            // If anything goes wrong, just revert to the original behaviour
            if (ex instanceof JasperException) {
                return (JasperException) ex;
            } else {
                return new JasperException(ex);
            }
        }
    
public intincTripCount()

	return tripCount++;
    
public booleanisTagFile()

	return this.isTagFile;
    
public java.lang.ClassloadTagFile()
Compile (if needed) and load a tag file


        try {
            if (ctxt.isRemoved()) {
                throw new FileNotFoundException(jspUri);
            }
            if (options.getDevelopment() || firstTime ) {
                synchronized (this) {
                    firstTime = false;
                    ctxt.compile();
                }
            } else {
                if (compileException != null) {
                    throw compileException;
                }
            }

            if (reload) {
                tagHandlerClass = ctxt.load();
                reload = false;
            }
        } catch (FileNotFoundException ex) {
            throw new JasperException(ex);
	}

	return tagHandlerClass;
    
public java.lang.ClassloadTagFilePrototype()
Compile and load a prototype for the Tag file. This is needed when compiling tag files with circular dependencies. A prototpe (skeleton) with no dependencies on other other tag files is generated and compiled.


	ctxt.setPrototypeMode(true);
	try {
	    return loadTagFile();
	} finally {
	    ctxt.setPrototypeMode(false);
	}
    
public voidservice(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, boolean precompile)

        
        try {

            if (ctxt.isRemoved()) {
                throw new FileNotFoundException(jspUri);
            }

            if ((available > 0L) && (available < Long.MAX_VALUE)) {
                if (available > System.currentTimeMillis()) {
                    response.setDateHeader("Retry-After", available);
                    response.sendError
                        (HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                         Localizer.getMessage("jsp.error.unavailable"));
                    return;
                } else {
                    // Wait period has expired. Reset.
                    available = 0;
                }
            }

            /*
             * (1) Compile
             */
            if (options.getDevelopment() || firstTime ) {
                synchronized (this) {
                    firstTime = false;

                    // The following sets reload to true, if necessary
                    ctxt.compile();
                }
            } else {
                if (compileException != null) {
                    // Throw cached compilation exception
                    throw compileException;
                }
            }

            /*
             * (2) (Re)load servlet class file
             */
            getServlet();

            // If a page is to be precompiled only, return.
            if (precompile) {
                return;
            }

        } catch (FileNotFoundException ex) {
            ctxt.incrementRemoved();
            String includeRequestUri = (String)
                request.getAttribute("javax.servlet.include.request_uri");
            if (includeRequestUri != null) {
                // This file was included. Throw an exception as
                // a response.sendError() will be ignored by the
                // servlet engine.
                throw new ServletException(ex);
            } else {
                try {
                    response.sendError(HttpServletResponse.SC_NOT_FOUND, 
                                      ex.getMessage());
                } catch (IllegalStateException ise) {
                    log.error(Localizer.getMessage("jsp.error.file.not.found",
                           ex.getMessage()),
                  ex);
                }
            }
        } catch (ServletException ex) {
            if (options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw ex;
            }
        } catch (IOException ex) {
            if (options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw ex;
            }
        } catch (IllegalStateException ex) {
            if (options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw ex;
            }
        } catch (Exception ex) {
            if (options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw new JasperException(ex);
            }
        }

        try {
            
            /*
             * (3) Service request
             */
            if (theServlet instanceof SingleThreadModel) {
               // sync on the wrapper so that the freshness
               // of the page is determined right before servicing
               synchronized (this) {
                   theServlet.service(request, response);
                }
            } else {
                theServlet.service(request, response);
            }

        } catch (UnavailableException ex) {
            String includeRequestUri = (String)
                request.getAttribute("javax.servlet.include.request_uri");
            if (includeRequestUri != null) {
                // This file was included. Throw an exception as
                // a response.sendError() will be ignored by the
                // servlet engine.
                throw ex;
            } else {
                int unavailableSeconds = ex.getUnavailableSeconds();
                if (unavailableSeconds <= 0) {
                    unavailableSeconds = 60;        // Arbitrary default
                }
                available = System.currentTimeMillis() +
                    (unavailableSeconds * 1000L);
                response.sendError
                    (HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
                     ex.getMessage());
            }
        } catch (ServletException ex) {
            if(options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw ex;
            }
        } catch (IOException ex) {
            if(options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw ex;
            }
        } catch (IllegalStateException ex) {
            if(options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw ex;
            }
        } catch (Exception ex) {
            if(options.getDevelopment()) {
                throw handleJspException(ex);
            } else {
                throw new JasperException(ex);
            }
        }
    
public voidsetCompilationException(org.apache.jasper.JasperException je)
Sets the compilation exception for this JspServletWrapper.

param
je The compilation exception

        this.compileException = je;
    
public voidsetLastModificationTest(long lastModificationTest)

param
lastModificationTest The lastModificationTest to set.

        this.lastModificationTest = lastModificationTest;
    
public voidsetReload(boolean reload)

        this.reload = reload;
    
public voidsetServletClassLastModifiedTime(long lastModified)
Sets the last-modified time of the servlet class file associated with this JspServletWrapper.

param
lastModified Last-modified time of servlet class

        if (this.servletClassLastModifiedTime < lastModified) {
            synchronized (this) {
                if (this.servletClassLastModifiedTime < lastModified) {
                    this.servletClassLastModifiedTime = lastModified;
                    reload = true;
                }
            }
        }