You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2001/05/28 04:18:59 UTC

cvs commit: jakarta-tomcat-jasper/jasper34/liaison/org/apache/jasper34/tomcat33 JasperEngineContext.java JasperOptionsImpl.java JspInterceptor.java

costin      01/05/27 19:18:59

  Added:       jasper34/liaison/org/apache/jasper34/tomcat33
                        JasperEngineContext.java JasperOptionsImpl.java
                        JspInterceptor.java
  Log:
  Added tomcat33 specific interface ( will be compiled only if 33 is detected).
  
  This is few times faster than the servlet and the default for 3.3.
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat-jasper/jasper34/liaison/org/apache/jasper34/tomcat33/JasperEngineContext.java
  
  Index: JasperEngineContext.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.jasper34.tomcat33;
  
  import javax.servlet.*;
  import javax.servlet.http.*;
  import org.apache.jasper34.generator.*;
  import org.apache.jasper34.generator.Compiler;
  import org.apache.jasper34.core.*;
  import org.apache.jasper34.runtime.*;
  
  import java.util.*;
  import java.io.*;
  import java.net.*;
  
  //import org.apache.jasper.JspCompilationContext;
  
  /** Alternative implementation of JspCompilationContext ( in addition
      to the servlet and standalone ). Used by JspInterceptor - but
      it's in no way specific to tomcat.
  */
  public class JasperEngineContext implements JspCompilationContext {
      JspReader reader;
      ServletWriter writer;
      ServletContext context;
      ClassLoader loader;
      boolean isErrPage;
      String jspFile;
      String servletClassName;
      String servletPackageName;
      String servletJavaFileName;
      String contentType;
      Options options;
  
      String cpath;    // for compiling JSPs.
      ServletContext sctx;
      String outputDir;
  
      public JasperEngineContext()
      {
      }
  
      public void setClassPath( String s ) {
  	cpath=s;
      }
      
      /**
       * The classpath that is passed off to the Java compiler. 
       */
      public String getClassPath() {
  	return cpath;
      }
      
      /**
       * Get the input reader for the JSP text. 
       */
      public JspReader getReader() {
  	if( debug>0 ) log("getReader " + reader );
          return reader;
      }
      
      /**
       * Where is the servlet being generated?
       */
      public ServletWriter getWriter() {
  	if( debug>0 ) log("getWriter " + writer );
          return writer;
      }
  
      public void setServletContext( Object o ) {
  	sctx=(ServletContext)o;
      }
      
      /**
       * Get the ServletContext for the JSP we're processing now. 
       */
      public ServletContext getServletContext() {
  	if( debug>0 ) log("getCtx " + sctx );
          return sctx;
      }
      
      /**
       * What class loader to use for loading classes while compiling
       * this JSP? I don't think this is used right now -- akv. 
       */
      public ClassLoader getClassLoader() {
  	if( debug>0 ) log("getLoader " + loader );
          return loader;
      }
  
      public void setClassLoader( ClassLoader cl ) {
  	loader=cl;
      }
  
      public void addJar( String jar ) throws IOException {
  	if( debug>0 ) log("Add jar " + jar);
  	//loader.addJar( jar );
      }
  
      /**
       * Are we processing something that has been declared as an
       * errorpage? 
       */
      public boolean isErrorPage() {
  	if( debug>0 ) log("isErrorPage " + isErrPage );
          return isErrPage;
      }
      
      /**
       * What is the scratch directory we are generating code into?
       * FIXME: In some places this is called scratchDir and in some
       * other places it is called outputDir.
       */
      public String getOutputDir() {
  	if( debug>0 ) log("getOutputDir " + outputDir  );
          return outputDir;
      }
  
      public void setOutputDir(String s ) {
  	outputDir=s;
      }
      
      /**
       * Path of the JSP URI. Note that this is not a file name. This is
       * the context rooted URI of the JSP file. 
       */
      public String getJspFile() {
  	if( debug>0 ) log("getJspFile " +  jspFile);
  	return jspFile;
      }
  
      public void setJspFile( String s ) {
  	jspFile=s;
      }
      
      /**
       * Just the class name (does not include package name) of the
       * generated class. 
       */
      public String getServletClassName() {
  	if( debug>0 ) log("getServletClassName " +  servletClassName);
          return servletClassName;
      }
  
      public void setServletClassName( String s ) {
  	servletClassName=s;
      }
      
      /**
       * The package name into which the servlet class is generated. 
       */
      public String getServletPackageName() {
  	if( debug>0 ) log("getServletPackageName " +
  			   servletPackageName );
          return servletPackageName;
      }
  
      /**
       * Utility method to get the full class name from the package and
       * class name. 
       */
      public final String getFullClassName() {
  	if( debug>0 ) log("getServletPackageName " +
  			   servletPackageName + "." + servletClassName);
          if (servletPackageName == null)
              return servletClassName;
          return servletPackageName + "." + servletClassName;
      }
  
      /**
       * Full path name of the Java file into which the servlet is being
       * generated. 
       */
      public String getServletJavaFileName() {
  	if( debug>0 ) log("getServletPackageName " +
  			   servletPackageName + "." + servletClassName);
          return servletJavaFileName;
      }
  
      /**
       * Are we keeping generated code around?
       */
      public boolean keepGenerated() {
          return options.getKeepGenerated();
      }
  
      /**
       * What's the content type of this JSP? Content type includes
       * content type and encoding. 
       */
      public String getContentType() {
          return contentType;
      }
  
      /**
       * Get hold of the Options object for this context. 
       */
      public Options getOptions() {
          return options;
      }
  
      public void setOptions(Options options) {
  	this.options=options;
      }
      
      public void setContentType(String contentType) {
          this.contentType = contentType;
      }
  
      public void setReader(JspReader reader) {
          this.reader = reader;
      }
      
      public void setWriter(ServletWriter writer) {
          this.writer = writer;
      }
      
      public void setServletPackageName(String servletPackageName) {
          this.servletPackageName = servletPackageName;
      }
      
      public void setServletJavaFileName(String servletJavaFileName) {
          this.servletJavaFileName = servletJavaFileName;
      }
      
      public void setErrorPage(boolean isErrPage) {
          this.isErrPage = isErrPage;
      }
  
      public Compiler createCompiler() throws JasperException {
  	if( debug>0 ) log("createCompiler ");
  	return null;
      }
      
      public String resolveRelativeUri(String uri)
      {
  	if( debug>0 ) log("resolveRelativeUri " + uri);
  	if (uri.charAt(0) == '/') {
  	    return uri;
          } else {
              String baseURI = jspFile.substring(0, jspFile.lastIndexOf('/'));
              return baseURI + '/' + uri;
          }
      }
  
      public java.io.InputStream getResourceAsStream(String res)
      {
  	if( debug>0 ) log("getResourceAsStream " + res);
  	return sctx.getResourceAsStream(res);
      }
  
      /** 
       * Gets the actual path of a URI relative to the context of
       * the compilation.
       */
      public String getRealPath(String path)
      {
  	if( debug>0 ) log("getRealPath " + path + " = " +
  			  sctx.getRealPath( path ));
  	return sctx.getRealPath( path );
      }
  
      // development tracing 
      private static int debug=0;
      private void log( String s ) {
  	System.out.println("JasperEngineContext: "+ s);
      }
  }
  
  
  
  1.1                  jakarta-tomcat-jasper/jasper34/liaison/org/apache/jasper34/tomcat33/JasperOptionsImpl.java
  
  Index: JasperOptionsImpl.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.jasper34.tomcat33;
  
  import java.util.*;
  import java.io.*;
  import java.net.*;
  
  import org.apache.jasper34.core.*;
  
  //import org.apache.jasper.Options;
  
  
  /** Another implementation of Options, backed by a Properties file
   *  and with no external dependencies. 
   */
  public class JasperOptionsImpl implements Options {
      static final String ieClassId =
  	"clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
  
      // cache
      private Class jspCompilerPlugin = null;
  
      // special property.
      private Object protectionDomain;
  
      Properties args;
      
      public JasperOptionsImpl( Properties args ) {
  	this.args=args;
      }
  
      // -------------------- Options implementation --------------------
  
      public boolean getKeepGenerated() {
  	return s2b( args.getProperty("keepgenerated", "true") );
      }
  
      public String getJavaEncoding() {
  	return args.getProperty("javaEncoding", "UTF8");
      }
  
      public boolean getLargeFile() {
          return s2b( args.getProperty("largefile", "false"));
      }
  
      public boolean getMappedFile() {
          return s2b( args.getProperty("mappedfile"));
      }
      
      public boolean getSendErrorToClient() {
          return s2b( args.getProperty( "sendErrToClient" ));
      }
   
      public boolean getClassDebugInfo() {
          return s2b( args.getProperty( "classDebugInfo" ));
      }
  
      public String getIeClassId() {
          return args.getProperty( "ieClassId" , ieClassId);
      }
  
      public File getScratchDir() {
  	if( debug>0 ) log("Options: getScratchDir " );
          return new File( args.getProperty( "scratchdir" ));
      }
  
      public final Object getProtectionDomain() {
  	if( debug>0 ) log("Options: GetPD" );
  	return protectionDomain;
      }
  
      public String getClassPath() {
  	if( debug>0 ) log("Options: GetCP "  );
          return args.getProperty( "classpath" );
      }
  
      public Class getJspCompilerPlugin() {
  	if( debug>0 ) log("Options: getJspCompilerPlugin "   );
  	if( jspCompilerPlugin!= null ) return jspCompilerPlugin;
  	String type=args.getProperty( "jspCompilerPlugin" );
  	if( type != null ) {
  	    try {
  		jspCompilerPlugin=Class.forName(type);
  	    } catch(Exception ex ) {
  		ex.printStackTrace();
  	    }
  	}
  	return jspCompilerPlugin;
      }
  
      public String getJspCompilerPath() {
          return args.getProperty( "jspCompilerPath" );
      }
  
      // -------------------- Setters --------------------
  
      public void setProtectionDomain( Object pd ) {
  	protectionDomain=pd;
      }
      
      // --------------------
      private boolean s2b( String s ) {
  	return new Boolean( s ).booleanValue();
      }
          
      // trace for development purpose --------------------    
      private static int debug=0;
      private void log(String s) {
  	System.err.println(s);
      }
  
  }
  
  
  
  
  
  1.1                  jakarta-tomcat-jasper/jasper34/liaison/org/apache/jasper34/tomcat33/JspInterceptor.java
  
  Index: JspInterceptor.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.jasper34.tomcat33;
  
  import javax.servlet.*;
  import javax.servlet.http.*;
  
  import javax.servlet.jsp.HttpJspPage;
  import javax.servlet.jsp.JspFactory;
  
  import java.util.*;
  import java.io.*;
  import java.net.*;
  
  import org.apache.tomcat.util.log.Log;
  import org.apache.tomcat.util.res.StringManager;
  import org.apache.tomcat.util.depend.*;
  import org.apache.tomcat.util.compat.*;
  
  import org.apache.jasper34.core.*;
  import org.apache.jasper34.runtime.*;
  import org.apache.jasper34.generator.*;
  import org.apache.jasper34.generator.Compiler;
  
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.facade.*;
  
  /**
   * Plug in the JSP engine (a.k.a Jasper)!
   * Tomcat uses a "built-in" mapping for jsps ( *.jsp -> jsp ). "jsp"
   * can be either a real servlet (JspServlet) that compiles the jsp
   * and include the resource, or we can "intercept" and do the
   * compilation and mapping in requestMap stage.
   *
   * JspInterceptor will be invoked once per jsp, and will add an exact
   * mapping - all further invocation are identical with servlet invocations
   * with direct maps, with no extra overhead.
   *
   * Future - better abstraction for jsp->java converter ( jasper ), better
   * abstraction for java->class, plugin other jsp implementations,
   * better scalability.
   *
   * @author Anil K. Vijendran
   * @author Harish Prabandham
   * @author Costin Manolache
   */
  public class JspInterceptor extends BaseInterceptor {
      static final String JIKES="org.apache.jasper.compiler.JikesJavaCompiler";
      static final String JSP_SERVLET="org.apache.jasper34.servlet.JspServlet";
      
      Properties args=new Properties(); // args for jasper
      boolean useJspServlet=false; 
      String jspServletCN=JSP_SERVLET;
      String runtimePackage;
      
      // -------------------- Jasper options --------------------
      // Options that affect jasper functionality. Will be set on
      // JspServlet ( if useJspServlet="true" ) or TomcatOptions.
      // IMPORTANT: periodically test for new jasper options
      
      /**
       * Are we keeping generated code around?
       */
      public void setKeepGenerated( String s ) {
  	args.put( "keepgenerated", s );
      }
  
      /**
       * Are we supporting large files?
       */
      public void setLargeFile( String s ) {
  	args.put( "largefile", s );
      }
  
      /**
       * Are we supporting HTML mapped servlets?
       */
      public void setMappedFile( String s ) {
  	args.put( "mappedfile", s );
      }
  
      /**
       * Should errors be sent to client or thrown into stderr?
       */
      public void setSendErrToClient( String s ) {
  	args.put( "sendErrToClient", s );
      }
  
      /**
       * Class ID for use in the plugin tag when the browser is IE. 
       */
      public void setIEClassId( String s ) {
  	args.put( "ieClassId", s );
      }
  
      /**
       * What classpath should I use while compiling the servlets
       * generated from JSP files?
       */
      public void setClassPath( String s ) {
  	args.put( "classpath", s );
      }
  
      /**
       * What is my scratch dir?
       */
      public void setScratchdir( String s ) {
  	args.put( "scratchdir", s );
      }
  
      /**
       * Path of the compiler to use for compiling JSP pages.
       */
      public void setJspCompilerPath( String s ) {
  	args.put( "jspCompilerPath", s );
      }
  
      /**
       * What compiler plugin should I use to compile the servlets
       * generated from JSP files?
       * @deprecated Use setJavaCompiler instead
       */
      public void setJspCompilerPlugin( String s ) {
  	args.put( "jspCompilerPlugin", s );
      }
  
      /** Include debug information in generated classes
       */
      public void setClassDebugInfo( String s ) {
  	args.put("classDebugInfo", s );
      }
      
      public void setProperty( String n, String v ) {
  	args.put( n, v );
      }
      // -------------------- JspInterceptor properties --------------------
  
      /** Use the old JspServlet to execute Jsps, instead of the
  	new code. Note that init() never worked (AFAIK) and it'll
  	be slower - but given the stability of JspServlet it may
  	be a safe option. This will significantly slow down jsps.
  	Default is false.
      */
      public void setUseJspServlet( boolean b ) {
  	useJspServlet=b;
      }
  
      /** Specify the implementation class of the jsp servlet.
       */
      public void setJspServlet( String  s ) {
  	jspServletCN=s;
      }
  
      /**
       * What compiler should I use to compile the servlets
       * generated from JSP files? Default is "javac" ( you can use
       * "jikes" as a shortcut ).
       */
      public void setJavaCompiler( String type ) {
  	if( "jikes".equals( type ) )
  	    type=JIKES;
  	if( "javac".equals( type ) )
  	    type="org.apache.jasper.compiler.SunJavaCompiler";
  		
  	args.put( "jspCompilerPlugin", type );
      }
  
      int pageContextPoolSize=JspFactoryImpl.DEFAULT_POOL_SIZE;
      /** Set the PageContext pool size for jasper factory.
  	0 will disable pooling of PageContexts.
       */
      public void setPageContextPoolSize(int i) {
  	pageContextPoolSize=i;
      }
  
      /** The generator will produce code using a different
  	runtime ( default is org.apache.jasper.runtime ).
  	The runtime must use the same names for classes as the
  	default one, so the code will compile.
      */
      public void setRuntimePackage(String rp ) {
  	runtimePackage=rp;
      }
      
      // -------------------- Hooks --------------------
  
      /**
       * Jasper-specific initializations, add work dir to classpath,
       */
      public void addContext(ContextManager cm, Context ctx)
  	throws TomcatException 
      {
  	if( runtimePackage!=null ) {
  	    Constants.JSP_RUNTIME_PACKAGE=runtimePackage;
  	    Constants.JSP_SERVLET_BASE=runtimePackage+".HttpJspBase";
  	}
  
  	JspFactoryImpl factory=new JspFactoryImpl(pageContextPoolSize);
  	
  	JspFactory.setDefaultFactory(factory);
  
  	// jspServlet uses it's own loader. We need to add workdir
  	// to the context classpath to use URLLoader and normal
  	// operation
  	// XXX alternative: use WEB-INF/classes for generated files 
  	if( ! useJspServlet ) {
  	    try {
  		// Note: URLClassLoader in JDK1.2.2 doesn't work with file URLs
  		// that contain '\' characters.  Insure only '/' is used.
  		// jspServlet uses it's own mechanism
  		URL url=new URL( "file", null,
  		 ctx.getWorkDir().getAbsolutePath().replace('\\','/') + "/");
  		ctx.addClassPath( url );
  		if( debug > 9 ) log( "Added to classpath: " + url );
  	    } catch( MalformedURLException ex ) {
  	    }
  	}
      }
  
      /** Do the needed initialization if jspServlet is used.
       *  It must be called after Web.xml is read ( WebXmlReader ).
       */
      public void contextInit(Context ctx)
  	throws TomcatException
      {
  	if( useJspServlet ) {
  	    // prepare jsp servlet. 
  	    Handler jasper=ctx.getServletByName( "jsp" );
  	    if ( debug>10) log( "Got jasper servlet " + jasper );
  
  	    ServletHandler jspServlet=(ServletHandler)jasper;
  	    if( jspServlet.getServletClassName() == null ) {
  		log( "Jsp already defined in web.xml " +
  		     jspServlet.getServletClassName() );
  		return;
  	    }
  	    if( debug>-1)
  		log( "jspServlet=" +  jspServlet.getServletClassName());
  	    Enumeration enum=args.keys();
  	    while( enum.hasMoreElements() ) {
  		String s=(String)enum.nextElement();
  		String v=(String)args.get(s);
  		if( debug>0 ) log( "Setting " + s + "=" + v );
  		jspServlet.getServletInfo().addInitParam(s, v );
  	    }
  	    
  	    if( debug > 0 ) {
  		//enable jasperServlet logging
  		log( "Seetting debug on jsp servlet");
  		Constants.jasperLog=  loghelper;
  		// 		org.apache.jasper.Constants.jasperLog.
  		// 		    setVerbosityLevel("debug");
  	    }
  
  	    jspServlet.setServletClassName(jspServletCN);
  	} else {
  	    ctx.addServlet( new JspPrecompileH());
  	}
      }
  
      /** Set the HttpJspBase classloader before init,
       *  as required by Jasper
       */
      public void preServletInit( Context ctx, Handler sw )
  	throws TomcatException
      {
  	if( ! (sw instanceof ServletHandler) )
  	    return;
  	try {
  	    // requires that everything is compiled
  	    Servlet theServlet = ((ServletHandler)sw).getServlet();
  	    if (theServlet instanceof HttpJspBase)  {
  		if( debug > 9 )
  		    log( "PreServletInit: HttpJspBase.setParentClassLoader" +
  			 sw );
  		HttpJspBase h = (HttpJspBase) theServlet;
  		h.setClassLoader(ctx.getClassLoader());
  	    }
  	} catch(Exception ex ) {
  	    throw new TomcatException( ex );
  	}
      }
  
      //-------------------- Main hook - compile the jsp file if needed
      
      /** Detect if the request is for a JSP page and if it is find
  	the associated servlet name and compile if needed.
  
  	That insures that init() will take place on the equivalent
  	servlet - and behave exactly like a servlet.
  
  	A request is for a JSP if:
  	- the handler is a ServletHandler ( i.e. defined in web.xml
  	or dynamically loaded servlet ) and it has a "path" instead of
  	class name
  	- the handler has a special name "jsp". That means a *.jsp -> jsp
  	needs to be defined. This is a tomcat-specific mechanism ( not
  	part of the standard ) and allow users to associate other extensions
  	with JSP by using the "fictious" jsp handler.
  
  	An (cleaner?) alternative for mapping other extensions would be
  	to set them on JspInterceptor.
      */
      public int requestMap( Request req ) {
  	if( useJspServlet ) {
  	    // no further processing - jspServlet will take care
  	    // of the processing as before ( all processing
  	    // will happen in the handle() pipeline.
  	    return 0;
  	}
  
  	Handler wrapper=req.getHandler();
  	
  	if( wrapper==null )
  	    return 0;
  
  	// It's not a jsp if it's not "*.jsp" mapped or a servlet
  	if( (! "jsp".equals( wrapper.getName())) &&
  	    (! (wrapper instanceof ServletHandler)) ) {
  	    return 0;
  	}
  
  	ServletHandler handler=null;
  	String jspFile=null;
  
  	// There are 2 cases: extension mapped and exact map with
  	// a <servlet> with file-name declaration
  
  	// note that this code is called only the first time
  	// the jsp page is called - all other calls will treat the jsp
  	// as a regular servlet, nothing is special except the initial
  	// processing.
  
  	// XXX deal with jsp_compile
  	
  	if( "jsp".equals( wrapper.getName())) {
  	    // if it's an extension mapped file, construct and map a handler
  	    jspFile=req.servletPath().toString();
  	    
  	    // extension mapped jsp - define a new handler,
  	    // add the exact mapping to avoid future overhead
  	    handler= mapJspPage( req.getContext(), jspFile );
  	    req.setHandler( handler );
  	} else if( wrapper instanceof ServletHandler) {
  	    // if it's a simple servlet, we don't care about it
  	    handler=(ServletHandler)wrapper;
  	    jspFile=handler.getServletInfo().getJspFile();
  	    if( jspFile==null )
  		return 0; // not a jsp
  	}
  
  	// if it's a jsp_precompile request, don't execute - just
  	// compile ( if needed ). Since we'll compile the jsp on
  	// the first request the only special thing is to not
  	// execute the jsp if jsp_precompile param is in parameters.
  	String qString=req.queryString().toString();
  	// look for ?jsp_precompile or &jsp_precompile
  
  	// quick test to see if we need to worry about params
  	// ( preserve lazy eval for parameters )
  	boolean pre_compile=false;
  	int i=(qString==null) ? -1: qString.indexOf( "jsp_precompile" );
  	if( i>= 0 ) {
  	    // Probably we are in the problem case. 
  	    req.parameters().handleQueryParameters();
  	    String p=req.parameters().getParameter( "jsp_precompile");
  	    if( p==null || p.equalsIgnoreCase("true")) {
  		pre_compile=true;
  	    }
  	}
  	
  	// Each .jsp file is compiled to a servlet, and will
  	// have a dependency to check if it's expired
  	Dependency dep= handler.getServletInfo().getDependency();
  	if( dep!=null && ! dep.isExpired() ) {
  	    // if the jspfile is older than the class - we're ok
  	    // this happens if the .jsp file was compiled in a previous
  	    // run of tomcat.
  	    return 0;
  	}
  
  	// we need to compile... ( or find previous .class )
  	JasperLiaison liasion=new JasperLiaison(getLog(), debug);
  	liasion.processJspFile(req, jspFile, handler, args);
  
  	if( pre_compile ) {
  	    // we may have compiled the page ( if needed ), but
  	    // we can't execute it. The handler will just
  	    // report that we detected the trick.
  
  	    // Future: detail information about compile results
  	    // and if indeed we had to do something or not
  	    req.setHandler(  ctx.
  			     getServletByName( "tomcat.jspPrecompileHandler"));
  	}
  	
  	return 0;
      }
  
      // -------------------- Utils --------------------
      
      private static final String SERVLET_NAME_PREFIX="TOMCAT/JSP";
      
      /** Add an exact map that will avoid *.jsp mapping and intermediate
       *  steps. It's equivalent with declaring
       *  <servlet-name>tomcat.jsp.[uri]</>
       *  <servlet-mapping><servlet-name>tomcat.jsp.[uri]</>
       *                   <url-pattern>[uri]</></>
       */
      private ServletHandler mapJspPage( Context ctx, String uri)
      {
  	String servletName= SERVLET_NAME_PREFIX + uri;
  
  	if( debug>0)
  	    log( "mapJspPage " + ctx + " " + " " + servletName + " " +  uri  );
  
  	Handler h=ctx.getServletByName( servletName );
  	if( h!= null ) {
  	    log( "Name already exists " + servletName +
  		 " while mapping " + uri);
  	    return (ServletHandler)h; // exception ?
  	}
  	
  	ServletHandler wrapper=new ServletHandler();
  	wrapper.setModule( this );
  	wrapper.setContext(ctx);
  	wrapper.setName(servletName);
  	wrapper.getServletInfo().setJspFile( uri );
  	
  	// add the mapping - it's a "invoker" map ( i.e. it
  	// can be removed to keep memory under control.
  	// The memory usage is smaller than JspSerlvet anyway, but
  	// can be further improved.
  	try {
  	    ctx.addServlet( wrapper );
  	    ctx.addServletMapping( uri ,
  				   servletName );
  	    if( debug > 0 )
  		log( "Added mapping " + uri + " path=" + servletName );
  	} catch( TomcatException ex ) {
  	    log("mapJspPage: ctx=" + ctx +
  		", servletName=" + servletName, ex);
  	    return null;
  	}
  	return wrapper;
      }
  
  }
  
  // -------------------- Jsp_precompile handler --------------------
  
  /** What to do for jsp precompile
   */
  class JspPrecompileH extends Handler {
      static StringManager sm=StringManager.
  	getManager("org.apache.tomcat.resources");
      
      JspPrecompileH() {
  	name="tomcat.jspPrecompileHandler";
      }
  
      public void doService(Request req, Response res)
  	throws Exception
      {
  	res.setContentType("text/html");	
  
  	String msg="<h1>Jsp Precompile Done</h1>";
  
  	res.setContentLength(msg.length());
  
  	res.getBuffer().write( msg );
      }
  }
  
  
  
  
  // -------------------- The main Jasper Liaison --------------------
  
  final class JasperLiaison {
      Log log;
      final int debug;
      
      JasperLiaison( Log log, int debug ) {
  	this.log=log;
  	this.debug=debug;
      }
      
      /** Generate mangled names, check for previous versions,
       *  generate the .java file, compile it - all the expensive
       *  operations. This happens only once ( or when the jsp file
       *  changes ). 
       */
      int processJspFile(Request req, String jspFile,
  		       ServletHandler handler, Properties args)
      {
  	// ---------- Expensive part - compile and load
  	
  	// If dep==null, the handler was never used - we need
  	// to either compile it or find the previous compiled version
  	// If dep.isExpired() we need to recompile.
  
  	if( debug > 10 ) log.log( "Before compile sync  " + jspFile );
  	synchronized( handler ) {
  	    
  	    // double check - maybe another thread did that for us
  	    Dependency dep= handler.getServletInfo().getDependency();
  	    if( dep!=null && ! dep.isExpired() ) {
  		// if the jspfile is older than the class - we're ok
  		return 0;
  	    }
  
  	    Context ctx=req.getContext();
  	    
  	    // Mangle the names - expensive operation, but nothing
  	    // compared with a compilation :-)
  	    JasperMangler mangler=
  		new JasperMangler(ctx.getWorkDir().getAbsolutePath(),
  			       ctx.getAbsolutePath(),
  			       jspFile );
  
  	    // register the handler as dependend of the jspfile 
  	    if( dep==null ) {
  		dep=setDependency( ctx, mangler, handler );
  		// update the servlet class name
  		handler.setServletClassName( mangler.getServletClassName() );
  
  		// check again - maybe we just found a compiled class from
  		// a previous run
  		if( ! dep.isExpired() )
  		    return 0;
  	    }
  
  	    //	    if( debug > 3) 
  	    ctx.log( "Compiling: " + jspFile + " to " +
  		     mangler.getServletClassName());
  	    
  	    //XXX old servlet -  destroy(); 
  	    
  	    // jump version number - the file needs to be recompiled
  	    // reset the handler error, un-initialize the servlet
  	    handler.setErrorException( null );
  	    handler.setState( Handler.STATE_ADDED );
  	    
  	    // Move to the next class name
  	    mangler.nextVersion();
  
  	    // record time of attempted translate-and-compile
  	    // if the compilation fails, we'll not try again
  	    // until the jsp file changes
  	    dep.setLastModified( System.currentTimeMillis() );
  
  	    // Update the class name in wrapper
  	    if( debug> 1 )
  		log.log( "Update class Name " + mangler.getServletClassName());
  	    handler.setServletClassName( mangler.getServletClassName() );
  
  	    
  	    try {
  		Options options=new JasperOptionsImpl(args); 
  		JspCompilationContext ctxt=createCompilationContext(req,
  								    jspFile,
  								    options,
  								    mangler);
  		jsp2java( mangler, ctxt );
  
  		javac( options, ctxt, mangler );
  	    
  		if(debug>0)log.log( "Generated " +
  				    mangler.getClassFileName() );
  	    } catch( Exception ex ) {
  		if( ctx!=null )
  		    ctx.log("compile error: req="+req, ex);
  		else
  		    log.log("compile error: req="+req, ex);
  		handler.setErrorException(ex);
  		handler.setState(Handler.STATE_DISABLED);
  		// until the jsp cahnges, when it'll be enabled again
  		return 500;
  	    }
  
  	    dep.setExpired( false );
  	    
  	}
  
  	return 0;
      }
  
      /** Convert the .jsp file to a java file, then compile it to class
       */
      void jsp2java(JasperMangler mangler,  JspCompilationContext ctxt)
  	throws Exception
      {
  	if( debug > 0 ) log.log( "Generating " + mangler.getJavaFileName());
  	// make sure we have the directories
  	String javaFileName=mangler.getJavaFileName();
  	
  	File javaFile=new File(javaFileName);
  	
  	// make sure the directory is created
  	new File( javaFile.getParent()).mkdirs();
  	
  	Compiler compiler=new Compiler(ctxt);
  	compiler.setMangler( mangler );
  	// we will compile ourself
  	compiler.setJavaCompiler( null );
  	
  	
  	synchronized ( mangler ) {
  	    compiler.compile();
  	}
  	if( debug > 0 ) {
  	    File f = new File( mangler.getJavaFileName());
  	    log.log( "Created file : " + f +  " " + f.lastModified());
  	    
  	}
      }
      
      String javaEncoding = "UTF8";           // perhaps debatable?
      static String sep = System.getProperty("path.separator");
  
      private void prepareCompiler( JavaCompiler javac,
  				  Options options, 
  				  JspCompilationContext ctxt )
  	throws JasperException
      {
  	String compilerPath = options.getJspCompilerPath();
          if (compilerPath != null)
              javac.setCompilerPath(compilerPath);
  
  	javac.setClassDebugInfo(options.getClassDebugInfo());
  
  	javac.setEncoding(javaEncoding);
  	String cp=System.getProperty("java.class.path")+ sep + 
  	    ctxt.getClassPath() + sep + ctxt.getOutputDir();
          javac.setClasspath( cp );
  	javac.setOutputDir(ctxt.getOutputDir());
  
  	if( debug>5) log.log( "ClassPath " + cp);
      }
  
      static boolean tryJikes=true;
      static Class jspCompilerPlugin = null;
      
      /** Compile a java to class. This should be moved to util, togheter
  	with JavaCompiler - it's a general purpose code, no need to
  	keep it part of jasper
      */
      void javac(Options options, JspCompilationContext ctxt,
  	       Mangler mangler)
  	throws JasperException
      {
  	String javaFileName = mangler.getJavaFileName();
  	if( debug>0 ) log.log( "Compiling java file " + javaFileName);
  
  	boolean status=true;
  	if( jspCompilerPlugin == null ) {
  	    jspCompilerPlugin=options.getJspCompilerPlugin();
  	}
  	// If no explicit compiler, and we never tried before
  	if( jspCompilerPlugin==null && tryJikes ) {
  	    ByteArrayOutputStream out = new ByteArrayOutputStream (256);
  	    try {
  
  		jspCompilerPlugin=Class.
  		    forName("org.apache.jasper.compiler.JikesJavaCompiler");
  		JavaCompiler javaC=createJavaCompiler( jspCompilerPlugin );
  		
  		prepareCompiler( javaC, options, ctxt );
  		javaC.setMsgOutput(out);
  		status = javaC.compile(javaFileName);
  	    } catch( Exception ex ) {	
  		log.log("Guess java compiler: no jikes " + ex.toString());
  		status=false;
  	    }
  	    if( status==false ) {
  		log.log("Guess java compiler: no jikes ");
  		log.log("Guess java compiler: OUT " + out.toString());
  		jspCompilerPlugin=null;
  		tryJikes=false;
  	    } else {
  		log.log("Guess java compiler: using jikes ");
  	    }
  	}
  
  	JavaCompiler javaC=createJavaCompiler( jspCompilerPlugin );
  	prepareCompiler( javaC, options, ctxt );
  	ByteArrayOutputStream out = new ByteArrayOutputStream (256);
  	javaC.setMsgOutput(out);
  	
  	status = javaC.compile(javaFileName);
  
          if (!ctxt.keepGenerated()) {
              File javaFile = new File(javaFileName);
              javaFile.delete();
          }
      
          if (status == false) {
              String msg = out.toString ();
              throw new JasperException("Unable to compile "
                                        + msg);
          }
  	if( debug > 0 ) log.log("Compiled ok");
      }
  
      /** tool for customizing javac.
       */
      public JavaCompiler createJavaCompiler(Class jspCompilerPlugin )
  	throws JasperException
      {
          JavaCompiler javac;
  
  	if (jspCompilerPlugin != null) {
              try {
                  javac = (JavaCompiler) jspCompilerPlugin.newInstance();
              } catch (Exception ex) {
  		Constants.message("jsp.warning.compiler.class.cantcreate",
  				  new Object[] { jspCompilerPlugin, ex }, 
  				  Log.FATAL);
                  javac = new SunJavaCompiler();
  	    }
  	} else {
              javac = new SunJavaCompiler();
  	}
  
  	return javac;
      }
  
      private String computeClassPath(Context ctx) {
  	String separator = System.getProperty("path.separator", ":");
  	URL classP[]=ctx.getClassPath();
          String cpath = "";
          cpath+=extractClassPath(classP);
          Jdk11Compat jdkProxy=Jdk11Compat.getJdkCompat();
          URL appsCP[];
          URL commonCP[];
          ClassLoader parentLoader=ctx.getContextManager().getParentLoader();
          appsCP=jdkProxy.getParentURLs(parentLoader);
          commonCP=jdkProxy.getURLs(parentLoader);
  	if( appsCP!=null ) 
  	    cpath+=separator+extractClassPath(appsCP);
  	if( commonCP!=null ) 
  	    cpath+=separator+extractClassPath(commonCP);
  	return cpath;
      }
      String extractClassPath(URL urls[]){
  	String separator = System.getProperty("path.separator", ":");
          String cpath="";
          for(int i=0; i< urls.length; i++ ) {
              URL cp = urls[i];
  	    if( cp == null ) {
  		continue;
  	    }
              File f = new File( cp.getFile());
              if (cpath.length()>0) cpath += separator;
              cpath += f;
          }
          return cpath;
      }
  
      private JspCompilationContext createCompilationContext( Request req,
  							    String jspFile,
  							    Options opt,
  							    Mangler mangler)
      {
  	JasperEngineContext ctxt = new JasperEngineContext();
  	ctxt.setServletClassName( mangler.getClassName());
  	//	ctxt.setJspFile( req.servletPath().toString());
  	ctxt.setJspFile( jspFile );
  	ctxt.setClassPath( computeClassPath( req.getContext()) );
  //        System.out.println("computeClasspath:"+ctxt.getClassPath());
  	ctxt.setServletContext( req.getContext().getFacade());
  	ctxt.setOptions( opt );
  	ctxt.setClassLoader( req.getContext().getClassLoader());
  	ctxt.setOutputDir(req.getContext().getWorkDir().getAbsolutePath());
  	return ctxt;
      }
  
      // Add an "expire check" to the generated servlet.
      private Dependency setDependency( Context ctx, JasperMangler mangler,
  				      ServletHandler handler )
      {
  	ServletInfo info=handler.getServletInfo();
  	// create a lastModified checker.
  	if( debug>0) log.log("Registering dependency for " + handler );
  	Dependency dep=new Dependency();
  	dep.setOrigin( new File(mangler.getJspFilePath()) );
  	dep.setTarget( handler );
  	dep.setLocal( true );
  	File f=new File( mangler.getClassFileName() );
  	if( mangler.getVersion() > 0 ) {
  	    // it has a previous version
  	    dep.setLastModified(f.lastModified());
  	    // update the "expired" variable
  	    dep.checkExpiry();
  	} else {
  	    dep.setLastModified( -1 );
  	    dep.setExpired( true );
  	}
  	if( debug>0 )
  	    log.log( "file = " + mangler.getClassFileName() + " " +
  		     f.lastModified() );
  	if( debug>0 )
  	    log.log("origin = " + dep.getOrigin() + " " +
  		    dep.getOrigin().lastModified());
  	try {
  	    DependManager dm=(DependManager)ctx.getContainer().
  		getNote("DependManager");
  	    if( dm!=null ) {
  		dm.addDependency( dep );
  	    }
  	} catch( TomcatException ex ) {
  	    ex.printStackTrace();
  	}
  	info.setDependency( dep );
  	return dep;
      }
  
  
  }