You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by gl...@apache.org on 2002/05/01 03:33:42 UTC

cvs commit: jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper JspEngineContext.java

glenn       02/04/30 18:33:42

  Modified:    jasper2/src/share/org/apache/jasper/servlet JspServlet.java
               jasper2  build.xml
               jasper2/src/share/org/apache/jasper JspEngineContext.java
  Added:       jasper2/src/share/org/apache/jasper/servlet
                        JspServletWrapper.java
  Log:
  Refactor JspServlet, JspServletWrapper, and JspEngineContext
  prior to implementing new features.  There was alot of intimacy
  and some code duplication between these three.
  
  JspServletWrapper had been an inner class of JspServlet,
  refactored out of JspServlet into its own class.
  
  Removed unneeded imports.
  
  Removed some unused code.
  
  Removed use of an HttpServletRequest and HttpServletResponse
  from JspEngineContext in preparation for doing background
  compiles.
  
  Switched JspServlet over to using the Jakarta-Commons
  collections FastHashMap instead of a Hashtable, this
  should improve performance while remaining thread safe.
  
  Passes all jsp watchdog tests except for the broken test case.
  
  Revision  Changes    Path
  1.9       +31 -322   jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/servlet/JspServlet.java
  
  Index: JspServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/servlet/JspServlet.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- JspServlet.java	30 Apr 2002 13:28:24 -0000	1.8
  +++ JspServlet.java	1 May 2002 01:33:42 -0000	1.9
  @@ -59,18 +59,12 @@
   import javax.servlet.ServletContext;
   import javax.servlet.ServletConfig;
   import javax.servlet.ServletException;
  -import javax.servlet.SingleThreadModel;
  -import javax.servlet.UnavailableException;
   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
  -import javax.servlet.jsp.HttpJspPage;
   import javax.servlet.jsp.JspFactory;
   
  -import java.util.Hashtable;
  -import java.util.Enumeration;
   import java.io.File;
  -import java.io.PrintWriter;
   import java.io.IOException;
   import java.io.FileNotFoundException;
   import java.io.FilePermission;
  @@ -78,24 +72,21 @@
   import java.net.URL;
   import java.net.URLClassLoader;
   import java.net.MalformedURLException;
  -import java.security.AccessController;
   import java.security.CodeSource;
   import java.security.PermissionCollection;
   import java.security.Policy;
  -import java.security.PrivilegedAction;
  +import java.util.Enumeration;
  +import java.util.Iterator;
  +import java.util.Map;
  +
  +import org.apache.commons.collections.FastHashMap;
   
   import org.apache.jasper.JasperException;
   import org.apache.jasper.Constants;
   import org.apache.jasper.Options;
   import org.apache.jasper.EmbededServletOptions;
  -import org.apache.jasper.JspCompilationContext;
  -import org.apache.jasper.JspEngineContext;
  -import org.apache.jasper.compiler.Mangler;
   import org.apache.jasper.runtime.*;
   
  -import org.apache.jasper.compiler.Compiler;
  -import org.apache.jasper.compiler.TldLocationsCache;
  -
   import org.apache.jasper.logging.Logger;
   import org.apache.jasper.logging.DefaultLogger;
   import org.apache.jasper.logging.JasperLogger;
  @@ -114,155 +105,23 @@
    * @author Harish Prabandham
    * @author Remy Maucherat
    * @author Kin-man Chung
  + * @author Glenn Nielsen
    */
   public class JspServlet extends HttpServlet {
   
  -    Logger.Helper loghelper;
  -
  -    class JspServletWrapper {
  -        Servlet theServlet;
  -	String jspUri;
  -	boolean isErrorPage;
  -	// ServletWrapper will set this 
  -	Class servletClass;
  -	URLClassLoader loader = null;
  -        JspCompilationContext ctxt = null;
  -        String outDir = null;
  -        long available = 0L;
  -	
  -	JspServletWrapper(String jspUri, boolean isErrorPage) {
  -	    this.jspUri = jspUri;
  -	    this.isErrorPage = isErrorPage;
  -	    this.theServlet = null;
  -            createOutdir();
  -	}
  -	
  -        private void createOutdir() {
  -            File outDir = null;
  -            try {
  -                URL outURL = options.getScratchDir().toURL();
  -                String outURI = outURL.toString();
  -                if( outURI.endsWith("/") )
  -                    outURI = outURI + jspUri.substring(1,jspUri.lastIndexOf("/")+1);
  -                else
  -                    outURI = outURI + jspUri.substring(0,jspUri.lastIndexOf("/")+1);;
  -                outURL = new URL(outURI);
  -                outDir = new File(outURL.getFile());
  -                if( !outDir.exists() ) {
  -                    outDir.mkdirs();
  -                }
  -                this.outDir = outDir.toString() + File.separator;
  -            } catch(Exception e) {
  -                throw new IllegalStateException("No output directory: " + e.getMessage());
  -            }
  -        }
  -
  -	private void load() throws JasperException, ServletException {
  -	    try {
  -		// This is to maintain the original protocol.
  -		destroy();
  -
  -		theServlet = (Servlet) servletClass.newInstance();
  -	    } catch (Exception ex) {
  -		throw new JasperException(ex);
  -	    }
  -	    theServlet.init(JspServlet.this.config);
  -	}
  -
  -	public void service(HttpServletRequest request, 
  -			    HttpServletResponse response,
  -			    boolean precompile)
  -	    throws ServletException, IOException, FileNotFoundException 
  -	{
  -            try {
  -
  -                if ((available > 0L) && (available < Long.MAX_VALUE)) {
  -                    response.setDateHeader("Retry-After", available);
  -                    response.sendError
  -                        (HttpServletResponse.SC_SERVICE_UNAVAILABLE,
  -                         Constants.getString("jsp.error.unavailable"));
  -                }
  -
  -                if (loadJSP(this, jspUri, classpath,
  -                            isErrorPage, request, response)
  -                        || theServlet == null) {
  -                    load();
  -                }
  -
  -		// If a page is to only to be precompiled return.
  -		if (precompile)
  -		    return;
  -
  -		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 (FileNotFoundException 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 new ServletException(ex);
  -                } else {
  -                    try {
  -			response.sendError(HttpServletResponse.SC_NOT_FOUND, 
  -					   ex.getMessage());
  -		    } catch (IllegalStateException ise) {
  -			Constants.jasperLog.log(Constants.getString
  -						("jsp.error.file.not.found",
  -						 new Object[] {
  -						     ex.getMessage()
  -						 }), ex,
  -						Logger.ERROR);
  -		    }
  -		    return;
  -		}
  -	    }
  -	}
  +    private Logger.Helper loghelper;
   
  -	public void destroy() {
  -	    if (theServlet != null)
  -		theServlet.destroy();
  -	}
  -    }
  -	
  -	
  -    protected ServletContext context = null;
  -    protected Hashtable jsps = new Hashtable();
  -    protected ServletConfig config;
  -    protected Options options;
  -    protected URLClassLoader parentClassLoader;
  -    protected ServletEngine engine;
  -    protected String serverInfo;
  +    private ServletContext context = null;
  +    private Map jsps = new FastHashMap();
  +    private ServletConfig config;
  +    private Options options;
  +    private URLClassLoader parentClassLoader;
  +    private ServletEngine engine;
  +    private String serverInfo;
       private PermissionCollection permissionCollection;
       private CodeSource codeSource;
       private String classpath;
  +
       static boolean firstTime = true;
   
       public void init(ServletConfig config)
  @@ -284,6 +143,8 @@
   
   	options = new EmbededServletOptions(config, context);
   
  +        ((FastHashMap)jsps).setFast(true);
  +
           // Get the classpath to use for compiling
           classpath = (String) context.getAttribute(Constants.SERVLET_CLASSPATH);
   
  @@ -376,7 +237,7 @@
                       parentClassLoader.loadClass( basePackage +
   			"runtime.ServletResponseWrapperInclude");
   		    this.getClass().getClassLoader().loadClass( basePackage +
  -                        "servlet.JspServlet$JspServletWrapper");
  +                        "servlet.JspServletWrapper");
   		} catch (ClassNotFoundException ex) {
   		    System.out.println(
   			"Jasper JspServlet preload of class failed: " +
  @@ -398,18 +259,20 @@
   	throws ServletException, IOException
       {
   
  -	// First check if the requested JSP page exists, to avoid creating
  -	// unnecessary directories and files.
  -	if (context.getResourceAsStream(jspUri) == null)
  -	    throw new FileNotFoundException(jspUri);
  -
  -	boolean isErrorPage = exception != null;
  -	
   	JspServletWrapper wrapper;
   	synchronized (this) {
   	    wrapper = (JspServletWrapper) jsps.get(jspUri);
   	    if (wrapper == null) {
  -		wrapper = new JspServletWrapper(jspUri, isErrorPage);
  +                // First check if the requested JSP page exists, to avoid
  +                // creating unnecessary directories and files.
  +                if (context.getResourceAsStream(jspUri) == null)
  +                    throw new FileNotFoundException(jspUri);
  +                boolean isErrorPage = exception != null;
  +		wrapper = new JspServletWrapper(config, options, jspUri,
  +                                                isErrorPage, classpath,
  +                                                parentClassLoader,
  +                                                permissionCollection,
  +                                                codeSource);
   		jsps.put(jspUri, wrapper);
   	    }
   	}
  @@ -517,169 +380,15 @@
   	    throw new ServletException(e);
   	}
   
  -	// It's better to throw the exception - we don't
  -	// know if we can deal with sendError ( buffer may be
  -	// commited )
  -	// catch (Throwable t) {
  -	// 	    unknownException(response, t);
  -	// 	}
       }
   
       public void destroy() {
   	if (Constants.jasperLog != null)
   	    Constants.jasperLog.log("JspServlet.destroy()", Logger.INFORMATION);
   
  -	Enumeration servlets = jsps.elements();
  -	while (servlets.hasMoreElements()) 
  -	    ((JspServletWrapper) servlets.nextElement()).destroy();
  -    }
  -
  -
  -    /*  Check if we need to reload a JSP page.
  -     *
  -     *  Side-effect: re-compile the JSP page.
  -     *
  -     *  @param classpath explicitly set the JSP compilation path.
  -     *  @return true if JSP files is newer
  -     */
  -    boolean loadJSP(String jspUri, String classpath, 
  -	boolean isErrorPage, HttpServletRequest req, HttpServletResponse res) 
  -	throws JasperException, FileNotFoundException 
  -    {
  -
  -	JspServletWrapper jsw=(JspServletWrapper) jsps.get(jspUri);
  -	if( jsw==null ) {
  -	    throw new JasperException("Can't happen - JspServletWrapper=null");
  -	}
  -        return loadJSP(jsw, jspUri, classpath, isErrorPage, req, res);
  -        
  -    }
  -
  -
  -    /*  Check if we need to reload a JSP page.
  -     *
  -     *  Side-effect: re-compile the JSP page.
  -     *
  -     *  @param classpath explicitly set the JSP compilation path.
  -     *  @return true if JSP files is newer
  -     */
  -    boolean loadJSP(JspServletWrapper jsw, String jspUri, String classpath, 
  -	boolean isErrorPage, HttpServletRequest req, HttpServletResponse res) 
  -	throws JasperException, FileNotFoundException 
  -    {
  -
  -	boolean firstTime = jsw.servletClass == null;
  -        if (jsw.ctxt == null) {
  -            jsw.ctxt = new JspEngineContext
  -                (parentClassLoader, classpath, context, jspUri, 
  -                 jsw.outDir, isErrorPage, options,
  -                 req, res);
  -        }
  -        JspCompilationContext ctxt = jsw.ctxt;
  -	boolean outDated = false; 
  -        Compiler compiler = ctxt.createCompiler();
  -        
  -        if (options.getReloading() || (jsw.servletClass == null)) {
  -            try {
  -                synchronized (jsw) {
  -
  -                    // Synchronizing on jsw enables simultaneous 
  -                    // compilations of different pages, but not the 
  -                    // same page.
  -                    outDated = compiler.isOutDated();
  -                    if (outDated)
  -                        compiler.compile();
  -
  -                    if ((jsw.servletClass == null) || outDated) {
  -                        URL [] urls = new URL[1];
  -			File outputDir = 
  -                            new File(normalize(ctxt.getOutputDir()));
  -			urls[0] = outputDir.toURL();
  -			jsw.loader = new JasperLoader
  -                            (urls,ctxt.getServletClassName(),
  -                             parentClassLoader, permissionCollection,
  -                             codeSource);
  -			jsw.servletClass = jsw.loader.loadClass
  -                            (Constants.JSP_PACKAGE_NAME + "." 
  -                             + ctxt.getServletClassName());
  -                    }
  -
  -                }
  -            } catch (FileNotFoundException ex) {
  -                compiler.removeGeneratedFiles();
  -                throw ex;
  -            } catch (ClassNotFoundException cex) {
  -		throw new JasperException(
  -		    Constants.getString("jsp.error.unable.load"),cex);
  -	    } catch (MalformedURLException mue) {
  -                throw new JasperException(
  -		    Constants.getString("jsp.error.unable.load"),mue);
  -	    } catch (JasperException ex) {
  -                throw ex;
  -            } catch (Exception ex) {
  -                throw new JasperException
  -                    (Constants.getString("jsp.error.unable.compile"), ex);
  -            }
  -        }
  -
  -	return outDated;
  +	Iterator servlets = jsps.values().iterator();
  +	while (servlets.hasNext()) 
  +	    ((JspServletWrapper) servlets.next()).destroy();
       }
   
  -
  -    /**
  -     * Return a context-relative path, beginning with a "/", that represents
  -     * the canonical version of the specified path after ".." and "." elements
  -     * are resolved out.  If the specified path attempts to go outside the
  -     * boundaries of the current context (i.e. too many ".." path elements
  -     * are present), return <code>null</code> instead.
  -     *
  -     * @param path Path to be normalized
  -     */
  -    protected String normalize(String path) {
  -
  -        if (path == null)
  -            return null;
  -
  -        String normalized = path;
  -        
  -	// Normalize the slashes and add leading slash if necessary
  -	if (normalized.indexOf('\\') >= 0)
  -	    normalized = normalized.replace('\\', '/');
  -	if (!normalized.startsWith("/"))
  -	    normalized = "/" + normalized;
  -
  -	// Resolve occurrences of "//" in the normalized path
  -	while (true) {
  -	    int index = normalized.indexOf("//");
  -	    if (index < 0)
  -		break;
  -	    normalized = normalized.substring(0, index) +
  -		normalized.substring(index + 1);
  -	}
  -
  -	// Resolve occurrences of "/./" in the normalized path
  -	while (true) {
  -	    int index = normalized.indexOf("/./");
  -	    if (index < 0)
  -		break;
  -	    normalized = normalized.substring(0, index) +
  -		normalized.substring(index + 2);
  -	}
  -
  -	// Resolve occurrences of "/../" in the normalized path
  -	while (true) {
  -	    int index = normalized.indexOf("/../");
  -	    if (index < 0)
  -		break;
  -	    if (index == 0)
  -		return (null);	// Trying to go outside our context
  -	    int index2 = normalized.lastIndexOf('/', index - 1);
  -	    normalized = normalized.substring(0, index2) +
  -		normalized.substring(index + 3);
  -	}
  -
  -	// Return the normalized path that we have completed
  -	return (normalized);
  -
  -    }
   }
  
  
  
  1.1                  jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/servlet/JspServletWrapper.java
  
  Index: JspServletWrapper.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */ 
  
  package org.apache.jasper.servlet;
  
  import javax.servlet.Servlet;
  import javax.servlet.ServletContext;
  import javax.servlet.ServletConfig;
  import javax.servlet.ServletException;
  import javax.servlet.SingleThreadModel;
  import javax.servlet.UnavailableException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.FileNotFoundException;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.net.MalformedURLException;
  import java.security.CodeSource;
  import java.security.PermissionCollection;
  
  import org.apache.jasper.JasperException;
  import org.apache.jasper.Constants;
  import org.apache.jasper.Options;
  import org.apache.jasper.JspCompilationContext;
  import org.apache.jasper.JspEngineContext;
  import org.apache.jasper.runtime.*;
  
  import org.apache.jasper.compiler.Compiler;
  
  import org.apache.jasper.logging.Logger;
  
  /**
   * 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
   */
  
  class JspServletWrapper {
  
      private Servlet theServlet;
      private String jspUri;
      private Class servletClass;
      private URLClassLoader loader;
      private JspCompilationContext ctxt;
      private long available = 0L;
      private ServletConfig config;
      private Options options;
      private Compiler compiler;
      private PermissionCollection permissionCollection;
      private CodeSource codeSource;
      private URLClassLoader parentClassLoader;
  
      JspServletWrapper(ServletConfig config, Options options, String jspUri,
                        boolean isErrorPage, String classpath,
                        URLClassLoader parentClassLoader,
                        PermissionCollection permissionCollection,
                        CodeSource codeSource)
              throws JasperException {
          this.jspUri = jspUri;
          this.theServlet = null;
          this.config = config;
          this.options = options;
          this.parentClassLoader = parentClassLoader;
          this.permissionCollection = permissionCollection;
          this.codeSource = codeSource;
          ctxt = new JspEngineContext
              (parentClassLoader, classpath, config.getServletContext(),
               jspUri, isErrorPage, options);
          compiler = ctxt.createCompiler();
      }
  
      private void load() throws JasperException, ServletException {
          try {
              // This is to maintain the original protocol.
              destroy();
              theServlet = (Servlet) servletClass.newInstance();
          } catch (Exception ex) {
              throw new JasperException(ex);
          }
          theServlet.init(config);
      }
  
      public void service(HttpServletRequest request, 
                          HttpServletResponse response,
                          boolean precompile)
  	    throws ServletException, IOException, FileNotFoundException {
          try {
  
              if ((available > 0L) && (available < Long.MAX_VALUE)) {
                  response.setDateHeader("Retry-After", available);
                  response.sendError
                      (HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                       Constants.getString("jsp.error.unavailable"));
              }
  
              if (loadJSP(request, response) || theServlet == null) {
                  load();
              }
  
              // If a page is to only to be precompiled return.
              if (precompile)
                  return;
  
              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 (FileNotFoundException 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 new ServletException(ex);
              } else {
                  try {
                      response.sendError(HttpServletResponse.SC_NOT_FOUND, 
                                        ex.getMessage());
                  } catch (IllegalStateException ise) {
                      Constants.jasperLog.log(
                          Constants.getString("jsp.error.file.not.found",
  			                    new Object[] { ex.getMessage() }),
                          ex, Logger.ERROR);
                  }
              }
          }
      }
  
      public void destroy() {
          if (theServlet != null)
              theServlet.destroy();
      }
  
  
      /*  Check if we need to reload a JSP page.
       *
       *  Side-effect: re-compile the JSP page.
       *
       *  @return true if JSP has been recompiled
       */
      boolean loadJSP(HttpServletRequest req, HttpServletResponse res) 
  	throws JasperException, FileNotFoundException 
      {
  
  	boolean outDated = false; 
          
          if (options.getReloading() || (servletClass == null)) {
              try {
                  synchronized (this) {
  
                      // Synchronizing on jsw enables simultaneous 
                      // compilations of different pages, but not the 
                      // same page.
                      outDated = compiler.isOutDated();
                      if (outDated)
                          compiler.compile();
  
                      if ((servletClass == null) || outDated) {
                          URL [] urls = new URL[1];
  			File outputDir = 
                              new File(normalize(ctxt.getOutputDir()));
  			urls[0] = outputDir.toURL();
  			loader = new JasperLoader
                              (urls,ctxt.getServletClassName(),
                               parentClassLoader, permissionCollection,
                               codeSource);
  			servletClass = loader.loadClass
                              (Constants.JSP_PACKAGE_NAME + "." 
                               + ctxt.getServletClassName());
                      }
  
                  }
              } catch (FileNotFoundException ex) {
                  compiler.removeGeneratedFiles();
                  throw ex;
              } catch (ClassNotFoundException cex) {
  		throw new JasperException(
  		    Constants.getString("jsp.error.unable.load"),cex);
  	    } catch (MalformedURLException mue) {
                  throw new JasperException(
  		    Constants.getString("jsp.error.unable.load"),mue);
  	    } catch (JasperException ex) {
                  throw ex;
              } catch (Exception ex) {
                  throw new JasperException
                      (Constants.getString("jsp.error.unable.compile"), ex);
              }
          }
  
  	return outDated;
      }
  
  
      /**
       * Return a context-relative path, beginning with a "/", that represents
       * the canonical version of the specified path after ".." and "." elements
       * are resolved out.  If the specified path attempts to go outside the
       * boundaries of the current context (i.e. too many ".." path elements
       * are present), return <code>null</code> instead.
       *
       * @param path Path to be normalized
       */
      protected String normalize(String path) {
  
          if (path == null)
              return null;
  
          String normalized = path;
          
  	// Normalize the slashes and add leading slash if necessary
  	if (normalized.indexOf('\\') >= 0)
  	    normalized = normalized.replace('\\', '/');
  	if (!normalized.startsWith("/"))
  	    normalized = "/" + normalized;
  
  	// Resolve occurrences of "//" in the normalized path
  	while (true) {
  	    int index = normalized.indexOf("//");
  	    if (index < 0)
  		break;
  	    normalized = normalized.substring(0, index) +
  		normalized.substring(index + 1);
  	}
  
  	// Resolve occurrences of "/./" in the normalized path
  	while (true) {
  	    int index = normalized.indexOf("/./");
  	    if (index < 0)
  		break;
  	    normalized = normalized.substring(0, index) +
  		normalized.substring(index + 2);
  	}
  
  	// Resolve occurrences of "/../" in the normalized path
  	while (true) {
  	    int index = normalized.indexOf("/../");
  	    if (index < 0)
  		break;
  	    if (index == 0)
  		return (null);	// Trying to go outside our context
  	    int index2 = normalized.lastIndexOf('/', index - 1);
  	    normalized = normalized.substring(0, index2) +
  		normalized.substring(index + 3);
  	}
  
  	// Return the normalized path that we have completed
  	return (normalized);
  
      }
  }
  
  
  
  1.3       +1 -0      jakarta-tomcat-jasper/jasper2/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/build.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- build.xml	15 Apr 2002 22:36:51 -0000	1.2
  +++ build.xml	1 May 2002 01:33:42 -0000	1.3
  @@ -26,6 +26,7 @@
       <pathelement location="${xerces.jar}"/>
       <pathelement location="${xercesImpl.jar}"/>
       <pathelement location="${xmlParserAPIs.jar}"/>
  +    <pathelement location="${commons-collections.jar}"/>
       <pathelement location="${jasper.build}/shared/classes"/>
     </path>
   
  
  
  
  1.4       +46 -47    jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspEngineContext.java
  
  Index: JspEngineContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspEngineContext.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JspEngineContext.java	24 Apr 2002 02:21:05 -0000	1.3
  +++ JspEngineContext.java	1 May 2002 01:33:42 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspEngineContext.java,v 1.3 2002/04/24 02:21:05 kinman Exp $
  - * $Revision: 1.3 $
  - * $Date: 2002/04/24 02:21:05 $
  + * $Header: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspEngineContext.java,v 1.4 2002/05/01 01:33:42 glenn Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/05/01 01:33:42 $
    *
    * ====================================================================
    * 
  @@ -94,53 +94,57 @@
    * @author Pierre Delisle
    */
   public class JspEngineContext implements JspCompilationContext {
  -    JspReader reader;
  -    ServletWriter writer;
  -    ServletContext context;
  -    URLClassLoader loader;
  -    Compiler jspCompiler;
  -    String classpath; // for compiling JSPs.
  -    boolean isErrPage;
  -    String jspFile;
  -    String outDir;
  -    String servletClassName;
  -    String servletPackageName = Constants.JSP_PACKAGE_NAME;
  -    String servletJavaFileName;
  -    String contentType;
  -    Options options;
  -    HttpServletRequest req;
  -    HttpServletResponse res;
  -    
  +    private JspReader reader;
  +    private ServletWriter writer;
  +    private ServletContext context;
  +    private URLClassLoader loader;
  +    private Compiler jspCompiler;
  +    private String classpath; // for compiling JSPs.
  +    private boolean isErrPage;
  +    private String jspUri;
  +    private String baseURI;
  +    private String outDir;
  +    private String servletClassName;
  +    private String servletPackageName = Constants.JSP_PACKAGE_NAME;
  +    private String servletJavaFileName;
  +    private String contentType;
  +    private Options options;
   
       public JspEngineContext(URLClassLoader loader, String classpath, 
  -                            ServletContext context, String jspFile, String outDir,
  -                            boolean isErrPage, Options options,
  -                            HttpServletRequest req, HttpServletResponse res) 
  +                            ServletContext context, String jspUri,
  +                            boolean isErrPage, Options options)
       {
           this.loader = loader;
           this.classpath = classpath;
           this.context = context;
  -        this.jspFile = jspFile;
  -	this.outDir = outDir;
  +        this.jspUri = jspUri;
  +        baseURI = jspUri.substring(0, jspUri.lastIndexOf('/'));
           this.isErrPage = isErrPage;
           this.options = options;
  -        this.req = req;
  -        this.res = res;
  -    }
  -
  -    /**
  -     * Get the http request we are servicing now...
  -     */
  -    public HttpServletRequest getRequest() {
  -        return req;
  +        createOutdir();
       }
  -    
   
  -    /**
  -     * Get the http response we are using now...
  -     */
  -    public HttpServletResponse getResponse() {
  -        return res;
  +    private void createOutdir() {
  +        File outDir = null;      
  +        try {
  +            URL outURL = options.getScratchDir().toURL();
  +            String outURI = outURL.toString();           
  +            if( outURI.endsWith("/") )                   
  +                outURI = outURI +             
  +                         jspUri.substring(1,jspUri.lastIndexOf("/")+1);
  +            else                                                       
  +                outURI = outURI +                                      
  +                         jspUri.substring(0,jspUri.lastIndexOf("/")+1);;
  +            outURL = new URL(outURI);                                   
  +            outDir = new File(outURL.getFile());                        
  +            if( !outDir.exists() ) {
  +                outDir.mkdirs();
  +            }
  +            this.outDir = outDir.toString() + File.separator;
  +        } catch(Exception e) {
  +            throw new IllegalStateException("No output directory: " +
  +                                            e.getMessage());
  +        }   
       }
   
       /**
  @@ -224,7 +228,7 @@
        * the context rooted URI of the JSP file. 
        */
       public String getJspFile() {
  -        return jspFile;
  +        return jspUri;
       }
       
       /**
  @@ -347,12 +351,7 @@
           {
               return uri;
           }
  -        else
  -        {
  -            String actURI =  req.getServletPath();
  -            String baseURI = actURI.substring(0, actURI.lastIndexOf('/'));
  -            return baseURI + '/' + uri;
  -        }
  +        return baseURI + '/' + uri;
       }    
   
       /**
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>