costin      00/12/27 09:15:09

  Modified:    .        build.xml
               src/etc  server.xml
               src/facade22/org/apache/tomcat/facade ServletHandler.java
                        ServletInfo.java ServletInputStreamFacade.java
                        ServletWriterFacade.java
               src/share/org/apache/tomcat/startup EmbededTomcat.java
  Added:       src/build manifest.facade22
               src/facade22/org/apache/tomcat/facade JspInterceptor.java
                        LoadOnStartupInterceptor.java
  Removed:     src/facade22/org/apache/tomcat/modules/facade22
                        JspInterceptor.java LoadOnStartupInterceptor.java
  Log:
  - Changed class protection from "public" to "package" in facade.
  - added a "Sealed" manifest for facade
  - moved LoadOnStartup and JspInterceptor in the same package - they
  need access to package methods ( are specific to the facade )
  
  I read the "facade" package few times, I see no way to cast a facade to
  the implementation object or to access any method except what the API
  provides. More review is needed, and a class loader mechanism to double the
  protection.
  
  Trusted applications can still call getAttribute("org.apache.tomcat.request")
  or getAttribute("org.apache.tomcat.context") to access the "internal"
  objects.
  
  Revision  Changes    Path
  1.98      +3 -1      jakarta-tomcat/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/build.xml,v
  retrieving revision 1.97
  retrieving revision 1.98
  diff -u -r1.97 -r1.98
  --- build.xml 2000/12/25 04:43:15     1.97
  +++ build.xml 2000/12/27 17:14:57     1.98
  @@ -180,7 +180,9 @@
         <include name="org/apache/tomcat/facade/**"/>    
         <include name="org/apache/tomcat/modules/facade22/**"/>    
       </javac>
  -    <jar jarfile="${tomcat.build}/lib/facade22.jar" 
basedir="${tomcat.build}/classes"> 
  +    <jar jarfile="${tomcat.build}/lib/facade22.jar" 
  +      basedir="${tomcat.build}/classes"
  +      manifest="src/build/manifest.facade22"> 
         <include name="org/apache/tomcat/facade/**"/> 
         <include name="org/apache/tomcat/modules/facade22/**"/>    
       </jar>
  
  
  
  1.1                  jakarta-tomcat/src/build/manifest.facade22
  
  Index: manifest.facade22
  ===================================================================
  Manifest-Version: 1.0
  Name: org/apache/tomcat/facade/
  Sealed: true
  
  
  
  1.55      +2 -2      jakarta-tomcat/src/etc/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- server.xml        2000/12/12 20:21:18     1.54
  +++ server.xml        2000/12/27 17:15:00     1.55
  @@ -161,7 +161,7 @@
           <!-- "jsp" handler 
             -->
           <RequestInterceptor 
  -            className="org.apache.tomcat.modules.facade22.JspInterceptor" 
  +            className="org.apache.tomcat.facade.JspInterceptor" 
               debug="0"  />
           
           <!-- "default" handler - static files and dirs
  @@ -226,7 +226,7 @@
   
           <!-- Loaded last since JSP's that load-on-startup use request handling -->
           <ContextInterceptor 
  -            className="org.apache.tomcat.modules.facade22.LoadOnStartupInterceptor" 
/>
  +            className="org.apache.tomcat.facade.LoadOnStartupInterceptor" />
   
           <!-- Loaded last since JSP's that load-on-startup use request handling -->
           <RequestInterceptor 
  
  
  
  1.10      +1 -1      
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletHandler.java
  
  Index: ServletHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletHandler.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ServletHandler.java       2000/12/20 15:25:50     1.9
  +++ ServletHandler.java       2000/12/27 17:15:03     1.10
  @@ -85,7 +85,7 @@
    * @author Harish Prabandham
    * @author Costin Manolache
    */
  -public final class ServletHandler extends Handler {
  +final class ServletHandler extends Handler {
   
       /** 
        * If init() fails or preInit() detects the handler is still
  
  
  
  1.5       +8 -8      
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletInfo.java
  
  Index: ServletInfo.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletInfo.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ServletInfo.java  2000/12/27 07:18:46     1.4
  +++ ServletInfo.java  2000/12/27 17:15:04     1.5
  @@ -85,25 +85,25 @@
    * @author Harish Prabandham
    * @author [EMAIL PROTECTED]
    */
  -public class ServletInfo {
  +public final class ServletInfo {
   
       // the actual tomcat handler associated with this servlet
       private ServletHandler handler;
   
       // facade
  -    protected ServletConfig configF;
  +    private ServletConfig configF;
   
       // optional informations
  -    protected String description = null;
  +    private String description = null;
   
  -    Hashtable securityRoleRefs=new Hashtable();
  +    private Hashtable securityRoleRefs=new Hashtable();
   
  -    Hashtable initArgs=null;
  +    private Hashtable initArgs=null;
   
       // should be removed from handler
       private String jspFile = null;
  -    protected int loadOnStartup=-1;
  -    protected boolean loadingOnStartup=false;
  +    private int loadOnStartup=-1;
  +    private boolean loadingOnStartup=false;
   
       public ServletInfo() {
        handler=new ServletHandler();
  @@ -154,7 +154,7 @@
        return handler.getContext();
       }
   
  -    public Handler getHandler() {
  +    Handler getHandler() {
        return handler;
       }
   
  
  
  
  1.2       +1 -1      
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletInputStreamFacade.java
  
  Index: ServletInputStreamFacade.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletInputStreamFacade.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ServletInputStreamFacade.java     2000/08/23 05:39:20     1.1
  +++ ServletInputStreamFacade.java     2000/12/27 17:15:04     1.2
  @@ -73,7 +73,7 @@
    * This will also deal with the "contentLength" limit.
    * <b>Important</b> Only the methods in ServletInputStream can be public.
    */
  -public class ServletInputStreamFacade extends ServletInputStream {
  +final class ServletInputStreamFacade extends ServletInputStream {
       private int bytesRead = 0;
       private int limit = -1;
   
  
  
  
  1.2       +1 -1      
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletWriterFacade.java
  
  Index: ServletWriterFacade.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletWriterFacade.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ServletWriterFacade.java  2000/08/23 05:39:20     1.1
  +++ ServletWriterFacade.java  2000/12/27 17:15:05     1.2
  @@ -78,7 +78,7 @@
    * @author Costin Manolache [[EMAIL PROTECTED]]
    */
   // XXX hack - public will be removed after we add the CharBuffer and we fix the 
converter
  -public final class ServletWriterFacade extends PrintWriter {
  +final class ServletWriterFacade extends PrintWriter {
       Response resA;
       OutputBuffer ob;
       
  
  
  
  1.1                  
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/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 [EMAIL PROTECTED]
   *
   * 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.tomcat.facade;
  
  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.*;
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.util.depend.*;
  
  import org.apache.jasper.*;
  import org.apache.jasper.Constants;
  import org.apache.jasper.runtime.*;
  import org.apache.jasper.compiler.*;
  import org.apache.jasper.compiler.Compiler;
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.facade.*;
  
  /**
   * Plug in the JSP engine (a.k.a Jasper)! 
   *
   * @author Anil K. Vijendran
   * @author Harish Prabandham
   * @author Costin Manolache
   */
  public class JspInterceptor extends BaseInterceptor {
      TomcatOptions options=new TomcatOptions();
  
      static final String JIKES="org.apache.jasper.compiler.JikesJavaCompiler";
  
      // -------------------- Configurable properties --------------------
      
      public void setJavaCompiler( String type ) {
        // shortcut
        if( "jikes".equals( type ) )
            type=JIKES;
        
        try {
            options.jspCompilerPlugin=Class.forName(type);
        } catch(Exception ex ) {
            ex.printStackTrace();
        }
      }
  
      // -------------------- Hooks --------------------
  
      /**
       * Jasper-specific initializations, add work dir to classpath,
       *  make sure we have a dependManager.
       */
      public void addContext(ContextManager cm, Context ctx)
        throws TomcatException 
      {
        // Make sure JspFactory is set ( ? )
        JspFactory.setDefaultFactory(new JspFactoryImpl());
  
        try {
            URL url=new URL( "file", null,
                             ctx.getWorkDir().getAbsolutePath() + "/");
            ctx.addClassPath( url );
            if( debug > 9 ) log( "Added to classpath: " + url );
        } catch( MalformedURLException ex ) {
        }
  
        DependManager dm=ctx.getDependManager();
        if( dm==null ) {
            dm=new DependManager();
            ctx.setDependManager( dm );
        }
      }
  
      /** 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 ) {
        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;
  
        // if it's an extension mapped file, construct and map a handler
        if( "jsp".equals( wrapper.getName())) {
            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
        }
        
        Dependency dep= handler.getServletInfo().getDependency();
        if( dep!=null && ! dep.isExpired() ) {
            // if the jspfile is older than the class - we're ok
            return 0;
        }
  
        JasperLiaison liasion=new JasperLiaison(getLog(), debug, options);
        liasion.processJspFile(req, jspFile, handler);
        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]</></>
       */
      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 null; // 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;
      }
  
  }
  
  // -------------------- The main Jasper Liaison --------------------
  
  final class JasperLiaison {
      Log log;
      final int debug;
      Options options;
      
      JasperLiaison( Log log, int debug, Options options ) {
        this.log=log;
        this.debug=debug;
        this.options=options;
      }
      
      /** 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)
      {
        // ---------- 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 :-)
            JspMangler mangler=
                new JspMangler(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) 
                log.log( "Jsp source changed, recompiling: " + jspFile );
            
            //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
            log.log( "Update class Name " + mangler.getServletClassName());
            handler.setServletClassName( mangler.getServletClassName() );
  
            compile( handler, req, mangler );
            
            
            dep.setExpired( false );
            
        }
  
        return 0;
      }
  
      /** Convert the .jsp file to a java file, then compile it to class
       */
      void compile(Handler wrapper, Request req, JspMangler mangler ) {
        if( debug > 0 ) log.log( "Generating " + mangler.getJavaFileName());
        try {
            // 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();
  
            JspEngineContext1 ctxt = new JspEngineContext1(log,req, mangler);
            ctxt.setOptions( options );
            
            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());
                
            }
            javac( createJavaCompiler( options ), ctxt, mangler );
            
            if(debug>0)log.log( "Generated " + mangler.getClassFileName() );
        } catch( Exception ex ) {
            log.log("compile: req="+req, ex);
            wrapper.setErrorException(ex);
            wrapper.setState(Handler.STATE_DISABLED);
            // until the jsp cahnges, when it'll be enabled again
  
        }
      }
      
      String javaEncoding = "UTF8";           // perhaps debatable?
      static String sep = System.getProperty("path.separator");
  
      /** 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(JavaCompiler javac, JspCompilationContext ctxt,
                      Mangler mangler)
        throws JasperException
      {
  
          javac.setEncoding(javaEncoding);
        String cp=System.getProperty("java.class.path")+ sep + 
            ctxt.getClassPath() + sep + ctxt.getOutputDir();
          javac.setClasspath( cp );
        if( debug>5) log.log( "ClassPath " + cp);
        
        ByteArrayOutputStream out = new ByteArrayOutputStream (256);
        javac.setOutputDir(ctxt.getOutputDir());
          javac.setMsgOutput(out);
  
        String javaFileName = mangler.getJavaFileName();
        if( debug>0) log.log( "Compiling java file " + javaFileName);
        /**
           * Execute the compiler
           */
          boolean 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(Options options)
        throws JasperException
      {
        String compilerPath = options.getJspCompilerPath();
        Class jspCompilerPlugin = options.getJspCompilerPlugin();
          JavaCompiler javac;
  
        if (jspCompilerPlugin != null) {
              try {
                  javac = (JavaCompiler) jspCompilerPlugin.newInstance();
              } catch (Exception ex) {
                Constants.message("jsp.warning.compiler.class.cantcreate",
                                  new Object[] { jspCompilerPlugin, ex }, 
                                  Logger.FATAL);
                  javac = new SunJavaCompiler();
            }
        } else {
              javac = new SunJavaCompiler();
        }
  
          if (compilerPath != null)
              javac.setCompilerPath(compilerPath);
  
        return javac;
      }
  
      private Dependency setDependency( Context ctx, JspMangler 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 );
        if( mangler.getVersion() > 0 ) {
            // it has a previous version
            File f=new File( mangler.getClassFileName() );
            dep.setLastModified(f.lastModified());
            // update the "expired" variable
            dep.checkExpiry();
        } else {
            dep.setLastModified( -1 );
            dep.setExpired( true );
        }
        ctx.getDependManager().addDependency( dep );
        info.setDependency( dep );
        return dep;
      }
        
  
  }
  
  // -------------------- Jasper support - options --------------------
  
  class TomcatOptions implements Options {
      public boolean keepGenerated = true;
      public boolean largeFile = false;
      public boolean mappedFile = false;
      public boolean sendErrorToClient = false;
      public String ieClassId = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
      public Class jspCompilerPlugin = null;
      public String jspCompilerPath = null;
      public int debug=0;
      
      public File scratchDir;
      private Object protectionDomain;
      public String classpath = null;
  
      public boolean getKeepGenerated() {
          return keepGenerated;
      }
  
      public boolean getLargeFile() {
          return largeFile;
      }
  
      public boolean getMappedFile() {
          return mappedFile;
      }
      
      public boolean getSendErrorToClient() {
          return sendErrorToClient;
      }
   
      public String getIeClassId() {
          return ieClassId;
      }
  
      public void setScratchDir( File f ) {
        scratchDir=f;
      }
      
      public File getScratchDir() {
        if( debug>0 ) log("Options: getScratchDir " + scratchDir);
          return scratchDir;
      }
  
      public final Object getProtectionDomain() {
        if( debug>0 ) log("Options: GetPD" );
        return protectionDomain;
      }
  
      public String getClassPath() {
        if( debug>0 ) log("Options: GetCP " + classpath  );
          return classpath;
      }
  
      public Class getJspCompilerPlugin() {
          return jspCompilerPlugin;
      }
  
      public String getJspCompilerPath() {
          return jspCompilerPath;
      }
  
      void log(String s) {
        System.err.println(s);
      }
      
  }
  
  // -------------------- Jasper support - JspCompilationContext -------------
  
  class JspEngineContext1 implements JspCompilationContext {
      JspReader reader;
      ServletWriter writer;
      ServletContext context;
      JspLoader loader;
      String classpath; // for compiling JSPs.
      boolean isErrPage;
      String jspFile;
      String servletClassName;
      String servletPackageName;
      String servletJavaFileName;
      String contentType;
      Options options;
      public int debug=0;
      
      Request req;
      Mangler m;
      Log log;
      
      public JspEngineContext1(Log log, Request req, Mangler m)
      {
        this.log=log;
        this.req=req;
        this.m=m;
      }
  
      public HttpServletRequest getRequest() {
        if( debug>0 ) log.log("getRequest " + req );
          return (HttpServletRequest)req.getFacade();
      }
      
  
      /**
       * Get the http response we are using now...
       */
      public HttpServletResponse getResponse() {
        if( debug>0 ) log.log("getResponse " );
          return (HttpServletResponse)req.getResponse().getFacade();
      }
  
      /**
       * The classpath that is passed off to the Java compiler. 
       */
      public String getClassPath() {
        Context ctx=req.getContext();
        URL classP[]=ctx.getClassPath();
        String separator = System.getProperty("path.separator", ":");
          String cpath = "";
        
          for(int i=0; i< classP.length; i++ ) {
              URL cp = classP[i];
              File f = new File( cp.getFile());
              if (cpath.length()>0) cpath += separator;
              cpath += f;
          }
  
        if( debug>0 ) log.log("getClassPath " + cpath);
        return cpath;
      }
      
      /**
       * Get the input reader for the JSP text. 
       */
      public JspReader getReader() {
        if( debug>0 ) log.log("getReader " + reader );
          return reader;
      }
      
      /**
       * Where is the servlet being generated?
       */
      public ServletWriter getWriter() {
        if( debug>0 ) log.log("getWriter " + writer );
          return writer;
      }
      
      /**
       * Get the ServletContext for the JSP we're processing now. 
       */
      public ServletContext getServletContext() {
        if( debug>0 ) log.log("getCtx " +
                           req.getContext().getFacade());
          return (ServletContext)req.getContext().getFacade();
      }
      
      /**
       * 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.log("getLoader " + loader );
          return req.getContext().getClassLoader();
      }
  
      public void addJar( String jar ) throws IOException {
        if( debug>0 ) log.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.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.log("getOutputDir " +
                           req.getContext().getWorkDir().getAbsolutePath());
          return req.getContext().getWorkDir().getAbsolutePath();
      }
      
      /**
       * 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() {
        String sP=req.servletPath().toString();
        Context ctx=req.getContext();
        if( debug>0 ) log.log("getJspFile " +
                           sP);//   ctx.getRealPath( sP ) );
        //        return ctx.getRealPath( sP );
        return sP;
      }
      
      /**
       * Just the class name (does not include package name) of the
       * generated class. 
       */
      public String getServletClassName() {
        if( debug>0 ) log.log("getServletClassName " +
                           m.getClassName());
          return m.getClassName();
      }
      
      /**
       * The package name into which the servlet class is generated. 
       */
      public String getServletPackageName() {
        if( debug>0 ) log.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.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.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 setServletClassName(String servletClassName) {
          this.servletClassName = servletClassName;
      }
      
      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.log("createCompiler ");
        return null;
      }
      
      public String resolveRelativeUri(String uri)
      {
        if( debug>0 ) log.log("resolveRelativeUri " +
                                 uri);
        return null;
      };    
  
      public java.io.InputStream getResourceAsStream(String res)
      {
        if( debug>0 ) log.log("getResourceAsStream " + res);
          ServletContext sctx=(ServletContext)req.getContext().getFacade();
        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.log("GetRP " + path);
        Context ctx=req.getContext();
        return FileUtil.safePath( ctx.getAbsolutePath(),
                                  path);
      };
  }
  
  // -------------------- Jasper support - mangler --------------------
  
  final class JspMangler implements Mangler{
  
      public JspMangler(String workDir, String docBase, String jspFile)
      {
        this.jspFile=jspFile;
        this.workDir=workDir;
        this.docBase=docBase;
        init();
      }
  
      /** Versioned class name ( without package ).
       */
      public String getClassName() {
        return JavaGeneratorTool.getVersionedName( baseClassN, version );
      }
      
      /**
       *   Full path to the generated java file ( including version )
       */
      public String getJavaFileName() {
        return javaFileName;
      }
  
      /** The package name ( "." separated ) of the generated
       *  java file
       */
      public String getPackageName() {
        if( pkgDir!=null ) {
            return pkgDir.replace('/', '.');
        } else {
            return null;
        }
      }
  
      // -------------------- JspInterceptor fields --------------------
      
      /** Returns the jsp file, as declared by <jsp-file> in server.xml
       *  or the context-relative path that was extension mapped to jsp
       */
      public String getJspFile() {
        return jspFile;
      }
  
      /** Returns the directory where the class is located, using
       *  the normal class loader rules.
       */
      public String getClassDir() {
        return classDir;
      }
      
      /** The class name ( package + class + versioning ) of the
       *  compilation result
       */
      public String getServletClassName() {
        if( pkgDir!=null ) {
            return getPackageName()  + "." + getClassName();
        } else {
            return getClassName();
        }
      }
  
      public int getVersion() {
        return version;
      }
  
      /** Full path to the compiled class file ( including version )
       */
      public String getClassFileName() {
        return classFileName;
      }
      // In Jasper = not used - it's specific to the class scheme
      // used by JspServlet
      // Full path to the class file - without version.
      
  
      public String getBaseClassName() {
        return baseClassN;
      }
  
      public String getPackageDir() {
        return pkgDir;
      }
      
      public String getJspFilePath() {
        return FileUtil.safePath( docBase, jspFile);
      }
  
      /** compute basic names - pkgDir and baseClassN
       */
      private void init() {
        int lastComp=jspFile.lastIndexOf(  "/" );
  
        if( lastComp > 0 ) {
            // has package 
            // ignore the first "/" of jspFile
            pkgDir=jspFile.substring( 1, lastComp );
        }
        
        // remove "special" words, replace "."
        if( pkgDir!=null ) {
            pkgDir=JavaGeneratorTool.manglePackage(pkgDir);
            pkgDir=pkgDir.replace('.', '_');
            classDir=workDir + "/" + pkgDir;
        } else {
            classDir=workDir;
        }
        
        int extIdx=jspFile.lastIndexOf( "." );
  
        if( extIdx<0 ) {
            // no "." 
            if( lastComp > 0 )
                baseClassN=jspFile.substring( lastComp+1 );
            else
                baseClassN=jspFile.substring( 1 );
        } else {
            if( lastComp > 0 )
                baseClassN=jspFile.substring( lastComp+1, extIdx );
            else
                baseClassN=jspFile.substring( 1, extIdx );
        }
  
        System.out.println("XXXMangler: " + jspFile + " " + pkgDir + " " + baseClassN);
  
        // extract version from the .class dir, using the base name
        version=JavaGeneratorTool.readVersion(classDir,
                                              baseClassN);
        if( version==-1 ) {
            version=0;
        }
        updateVersionPaths();
      }
  
      private void updateVersionPaths() {
        // version dependent stuff
        String baseName=classDir + "/" + JavaGeneratorTool.
            getVersionedName( baseClassN, version);
        
        javaFileName= baseName + ".java";
  
        classFileName=baseName +  ".class";
      }
      
      /** Move to a new class name, if a changes has been detected.
       */
      void nextVersion() {
        version++;
        JavaGeneratorTool.writeVersion( getClassDir(), baseClassN, version);
        updateVersionPaths();
      }
  
      // context-relative jsp path 
      // extracted from the <jsp-file> or the result of a *.jsp mapping
      private String jspFile; 
      // version of the compiled java file
      private int version;
      private String workDir;
      private String docBase;
      // the "/" separted version
      private String pkgDir;
      // class name without package and version
      private String baseClassN;
      private String classDir;
      private String javaFileName;
      private String classFileName;
  }
  
  
  
  
  1.1                  
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/LoadOnStartupInterceptor.java
  
  Index: LoadOnStartupInterceptor.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 [EMAIL PROTECTED]
   *
   * 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/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  package org.apache.tomcat.facade;
  
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.facade.*;
  import org.apache.tomcat.util.log.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  /**
   * Interceptor that loads the "load-on-startup" servlets
   *
   * @author [EMAIL PROTECTED]
   */
  public class LoadOnStartupInterceptor extends BaseInterceptor {
      private static StringManager sm =
        StringManager.getManager("org.apache.tomcat.resources");
      
      public LoadOnStartupInterceptor() {
      }
  
      public void contextInit(Context ctx) {
        Hashtable loadableServlets = new Hashtable();
        init(ctx,loadableServlets);
        
        Vector orderedKeys = new Vector();
        Enumeration e=  loadableServlets.keys();
                
        // order keys
        while (e.hasMoreElements()) {
            Integer key = (Integer)e.nextElement();
            int slot = -1;
            for (int i = 0; i < orderedKeys.size(); i++) {
                if (key.intValue() <
                    ((Integer)(orderedKeys.elementAt(i))).intValue()) {
                    slot = i;
                    break;
                }
            }
            if (slot > -1) {
                orderedKeys.insertElementAt(key, slot);
            } else {
                orderedKeys.addElement(key);
            }
        }
  
        // loaded ordered servlets
  
        // Priorities IMO, should start with 0.
        // Only System Servlets should be at 0 and rest of the
        // servlets should be +ve integers.
        // WARNING: Please do not change this without talking to:
        // [EMAIL PROTECTED] (J2EE impact)
  
        for (int i = 0; i < orderedKeys.size(); i ++) {
            Integer key = (Integer)orderedKeys.elementAt(i);
            Enumeration sOnLevel =  ((Vector)loadableServlets.get( key )).
                elements();
            while (sOnLevel.hasMoreElements()) {
                String servletName = (String)sOnLevel.nextElement();
                Handler result = ctx.getServletByName(servletName);
  
                if( ctx.getDebug() > 0 )
                    ctx.log("Loading " + key + " "  + servletName );
                if(result==null)
                    log("Warning: we try to load an undefined servlet " +
                        servletName, Logger.WARNING);
                else {
                    try {
                        // special case for JSP - should be dealed with in
                        // ServletHandler !
                        if( result instanceof ServletHandler &&
                            ((ServletHandler)result).getServletInfo().
                            getJspFile() != null ) {
                            loadJsp( ctx, result );
                        } else {
                            ((ServletHandler)result).init();
                        }
                    } catch (Exception ee) {
                        String msg = sm.getString("context.loadServlet.e",
                                                  servletName);
                        log(msg, ee);
                    } 
                }
            }
        }
      }
  
      void loadJsp( Context context, Handler result ) throws Exception {
        // A Jsp initialized in web.xml -
  
        // Log ( since I never saw this code called, let me know if it does
        // for you )
        log("Initializing JSP with JspWrapper");
        
        // Ugly code to trick JSPServlet into loading this.
        ContextManager cm=context.getContextManager();
        String path=((ServletHandler)result).getServletInfo().getJspFile();
        Request request = new Request();
        Response response = new Response();
        request.recycle();
        response.recycle();
        cm.initRequest(request,response);
        
        String requestURI = path + "?jsp_precompile=true";
  
        if( !path.startsWith( "/" ) ) path="/" + path;
        request.requestURI().setString(context.getPath() + path);
  
        // this is not used with JspInterceptor, but maybe a jsp servlet is
        // used
        request.queryString().setString( "jsp_precompile=true" );
        
        request.setContext(context);
  
        //cm.service( request, response );
        // If we switch to JspInterceptor, it's enough to process the
        // request, it'll detect the page and precompile
        cm.processRequest( request );
      }
      // -------------------- 
      // Old logic from Context - probably something cleaner can replace it.
  
      void init(Context ctx, Hashtable loadableServlets ) {
        Enumeration enum=ctx.getServletNames();
        while(enum.hasMoreElements()) {
            String name=(String)enum.nextElement();
            Handler h=ctx.getServletByName( name );
            if( ! ( h instanceof ServletHandler ) )
                continue;
            ServletHandler sw= (ServletHandler)h;
            if( sw.getServletInfo().getLoadingOnStartUp() ) {
                Integer level=new Integer(sw.getServletInfo().
                                          getLoadOnStartUp());
                Vector v;
                if( loadableServlets.get(level) != null ) 
                    v=(Vector)loadableServlets.get(level);
                else
                    v=new Vector();
                
                v.addElement(name);
                loadableServlets.put(level, v);
            }
        }
      }
      
  
  }
  
  
  
  1.35      +2 -5      
jakarta-tomcat/src/share/org/apache/tomcat/startup/EmbededTomcat.java
  
  Index: EmbededTomcat.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/EmbededTomcat.java,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- EmbededTomcat.java        2000/12/27 07:20:22     1.34
  +++ EmbededTomcat.java        2000/12/27 17:15:09     1.35
  @@ -6,7 +6,6 @@
   import org.apache.tomcat.core.*;
   import org.apache.tomcat.request.*;
   import org.apache.tomcat.modules.server.*;
  -import org.apache.tomcat.modules.facade22.*;
   import org.apache.tomcat.modules.session.*;
   import org.apache.tomcat.context.*;
   import org.apache.tomcat.util.log.*;
  @@ -273,7 +272,7 @@
        InvokerInterceptor invI=new InvokerInterceptor();
        addInterceptor( invI );
        
  -     JspInterceptor jspI=new JspInterceptor();
  +     BaseInterceptor 
jspI=(BaseInterceptor)newObject("org.apache.tomcat.facade.JspInterceptor");
        addInterceptor( jspI );
   
        StaticInterceptor staticI=new StaticInterceptor();
  @@ -281,7 +280,7 @@
   
        addInterceptor( new SimpleSessionStore());
        
  -     BaseInterceptor loadOnSI= 
(BaseInterceptor)newObject("org.apache.tomcat.modules.facade22.LoadOnStartupInterceptor");
  +     BaseInterceptor loadOnSI= 
(BaseInterceptor)newObject("org.apache.tomcat.facade.LoadOnStartupInterceptor");
        addInterceptor( loadOnSI );
   
        BaseInterceptor 
s22=(BaseInterceptor)newObject("org.apache.tomcat.facade.Servlet22Interceptor");
  @@ -296,8 +295,6 @@
        Jdk12Interceptor jdk12I=new Jdk12Interceptor();
        addInterceptor( jdk12I );
   
  -     // xXXX
  -     //      addInterceptor( new SimpleRealm());
       }
       
   
  
  
  

Reply via email to