costin      00/12/12 12:21:45

  Modified:    src/etc  server.xml
               src/facade22/org/apache/tomcat/facade
                        Servlet22Interceptor.java ServletConfigImpl.java
                        WebXmlReader.java
               src/facade22/org/apache/tomcat/modules/facade22
                        JspInterceptor.java
               src/share/org/apache/tomcat/core Handler.java
               src/share/org/apache/tomcat/startup EmbededTomcat.java
  Added:       src/facade22/org/apache/tomcat/facade ServletHandler.java
                        ServletInfo.java
               src/facade22/org/apache/tomcat/modules/facade22
                        LoadOnStartupInterceptor.java
  Removed:     src/facade22/org/apache/tomcat/facade ServletWrapper.java
               src/share/org/apache/tomcat/context
                        LoadOnStartupInterceptor.java
  Log:
  Stage 2 of Handler/ServletWrapper refactoring.
  
  Split ServletWrapper in 2 smaller components - ServletInfo containing
  all the information that web.xml is setting on a servlet, and
  ServletHandler that deals only with the execution, init, destroy of the
  servlet.
  
  Moved LoadOnStartup into facade, since it's specific to internal details
  of the servlet/jsp implementation ( the JSP init needs more work ). This
  prepares for more simplifications in Handler.
  
  Removed unused fields in Handler - load on startup, path, etc - all are
  part of the ServletInfo, and not used by core.
  
  Added comments on JspInterceptor - it's on the list for documentation/refactoring.
  
  Revision  Changes    Path
  1.54      +1 -1      jakarta-tomcat/src/etc/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- server.xml        2000/11/22 19:23:17     1.53
  +++ server.xml        2000/12/12 20:21:18     1.54
  @@ -226,7 +226,7 @@
   
           <!-- Loaded last since JSP's that load-on-startup use request handling -->
           <ContextInterceptor 
  -            className="org.apache.tomcat.context.LoadOnStartupInterceptor" />
  +            className="org.apache.tomcat.modules.facade22.LoadOnStartupInterceptor" 
/>
   
           <!-- Loaded last since JSP's that load-on-startup use request handling -->
           <RequestInterceptor 
  
  
  
  1.7       +4 -4      
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/Servlet22Interceptor.java
  
  Index: Servlet22Interceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/Servlet22Interceptor.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Servlet22Interceptor.java 2000/12/12 00:42:40     1.6
  +++ Servlet22Interceptor.java 2000/12/12 20:21:21     1.7
  @@ -141,15 +141,15 @@
        if( ct.getHandler() == null ) {
            // we have a container with a valid handler name but without
            // a Handler. Create a ServletWrapper
  -         ServletWrapper sw=new ServletWrapper();
  -         sw.setName( hN );
  +         ServletInfo sw=new ServletInfo();
  +         sw.setServletName( hN );
            sw.setContext( ct.getContext() );
            // *.jsp -> jsp is a legacy default mapping  
            if( ! "jsp".equals(hN) ) {
                log( "Create handler " + hN);
            }
  -         ct.setHandler(sw);
  -         ct.getContext().addServlet(  sw );
  +         ct.setHandler(sw.getHandler());
  +         ct.getContext().addServlet(  sw.getHandler() );
        }
            
       }
  
  
  
  1.3       +5 -5      
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletConfigImpl.java
  
  Index: ServletConfigImpl.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletConfigImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ServletConfigImpl.java    2000/09/24 18:10:57     1.2
  +++ ServletConfigImpl.java    2000/12/12 20:21:22     1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletConfigImpl.java,v
 1.2 2000/09/24 18:10:57 costin Exp $
  - * $Revision: 1.2 $
  - * $Date: 2000/09/24 18:10:57 $
  + * $Header: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletConfigImpl.java,v
 1.3 2000/12/12 20:21:22 costin Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/12/12 20:21:22 $
    *
    * ====================================================================
    *
  @@ -79,9 +79,9 @@
    */
   final class ServletConfigImpl implements ServletConfig {
   
  -    ServletWrapper servletW;
  +    ServletInfo servletW;
       
  -    ServletConfigImpl( ServletWrapper sw) {
  +    ServletConfigImpl( ServletInfo sw) {
        servletW=sw;
       }
   
  
  
  
  1.7       +31 -30    
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/WebXmlReader.java
  
  Index: WebXmlReader.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/WebXmlReader.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- WebXmlReader.java 2000/12/12 00:42:40     1.6
  +++ WebXmlReader.java 2000/12/12 20:21:25     1.7
  @@ -37,35 +37,35 @@
        validate=b;
       }
   
  -    private Handler addServlet( Context ctx, String name, String classN )
  -     throws TomcatException
  -    {
  -     ServletWrapper sw=new ServletWrapper(); // ctx.createHandler();
  -     sw.setContext(ctx);
  -     sw.setServletName( name );
  -     sw.setServletClassName( classN);
  -     ctx.addServlet( sw );
  -     sw.setLoadOnStartUp( -2147483646 );
  -     return sw;
  -    }
  +//     private Handler addServlet( Context ctx, String name, String classN )
  +//   throws TomcatException
  +//     {
  +//   ServletInfo sw=new ServletInfo(); // ctx.createHandler();
  +//   sw.setContext(ctx);
  +//   sw.setServletName( name );
  +//   sw.setServletClassName( classN);
  +//   ctx.addServlet( sw.getHandler() );
  +//   sw.setLoadOnStartUp( -2147483646 );
  +//   return sw.getHandler();
  +//     }
       
  -    private void setDefaults( Context ctx )
  -     throws TomcatException
  -    {
  -     //      addServlet( ctx, "default", 
"org.apache.tomcat.servlets.DefaultServlet");
  -     //      addServlet( ctx, "invoker", 
"org.apache.tomcat.servlets.InvokerServlet");
  -     //      Handler sw=addServlet( ctx, "jsp", 
"org.apache.jasper.servlet.JspServlet");
  -     //      sw.addInitParam("jspCompilerPlugin", 
"org.apache.jasper.compiler.JikesJavaCompiler");
  -
  -//   ctx.addServletMapping( "/servlet/*", "invoker");
  -     ctx.addServletMapping( "*.jsp", "jsp");
  +//     private void setDefaults( Context ctx )
  +//   throws TomcatException
  +//     {
  +//   //      addServlet( ctx, "default", 
"org.apache.tomcat.servlets.DefaultServlet");
  +//   //      addServlet( ctx, "invoker", 
"org.apache.tomcat.servlets.InvokerServlet");
  +//   //      Handler sw=addServlet( ctx, "jsp", 
"org.apache.jasper.servlet.JspServlet");
  +//   //      sw.addInitParam("jspCompilerPlugin", 
"org.apache.jasper.compiler.JikesJavaCompiler");
  +
  +// //        ctx.addServletMapping( "/servlet/*", "invoker");
  +//   ctx.addServletMapping( "*.jsp", "jsp");
        
  -     ctx.setSessionTimeOut( 30 );
  +//   ctx.setSessionTimeOut( 30 );
   
  -     // mime-mapping - are build into MimeMap.
  -     // Note that default mappings are based on existing registered types.
  +//   // mime-mapping - are build into MimeMap.
  +//   // Note that default mappings are based on existing registered types.
   
  -    }
  +//     }
   
   
       private void readDefaultWebXml( Context ctx ) throws TomcatException {
  @@ -92,8 +92,9 @@
        ContextManager cm=ctx.getContextManager();
        
        try {
  -         // Default init
  -         setDefaults( ctx );
  +         // Defaults 
  +         ctx.addServletMapping( "*.jsp", "jsp");
  +         ctx.setSessionTimeOut( 30 );
   
            // We may read a "default" web.xml from INSTALL/conf/web.xml -
            // the code is commented out right now because we want to
  @@ -185,14 +186,14 @@
            xh.addRule("web-app/session-config/session-timeout", xh.methodParam(0));
   
            // Servlet
  -         xh.addRule("web-app/servlet", 
xh.objectCreate("org.apache.tomcat.facade.ServletWrapper") ); // servlet-wrapper
  +         xh.addRule("web-app/servlet", 
xh.objectCreate("org.apache.tomcat.facade.ServletInfo") ); // servlet-wrapper
            xh.addRule("web-app/servlet", xh.setParent( "setContext") ); // remove it 
from stack when done
            //      xh.addRule("web-app/servlet", xh.addChild("addServlet", 
"org.apache.tomcat.core.Handler") );
   
            xh.addRule("web-app/servlet", new XmlAction() {
                           public void end( SaxContext xctx)
                               throws Exception {
  -                            ServletWrapper sw=(ServletWrapper)
  +                            ServletInfo sw=(ServletInfo)
                                   xctx.currentObject();
                               Context cctx=(Context)xctx.previousObject();
                               sw.addServlet(cctx);
  @@ -201,7 +202,7 @@
                   );
            // remove it from stack when done
            xh.addRule("web-app/servlet/servlet-name", 
xh.methodSetter("setServletName",0) );
  -         xh.addRule("web-app/servlet/servlet-class", 
xh.methodSetter("setServletClass",0));
  +         xh.addRule("web-app/servlet/servlet-class", 
xh.methodSetter("setServletClassName",0));
            xh.addRule("web-app/servlet/jsp-file",xh.methodSetter("setPath",0));
   
            xh.addRule("web-app/servlet/security-role-ref", 
xh.methodSetter("addSecurityMapping", 3) );
  
  
  
  1.1                  
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletHandler.java
  
  Index: ServletHandler.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 java.io.*;
  import java.net.*;
  import java.util.*;
  import javax.servlet.*;
  import javax.servlet.http.*;
  
  /**
   * Handler for servlets. It'll implement all servlet-specific
   * requirements ( init, Unavailable exception, etc).
   *
   * It is also used for Jsps ( since a Jsp is a servlet ), but
   * requires the Jsp interceptor to make sure that indeed a Jsp is
   * a servlet ( and set the class name ).
   * 
   * The old Jsp hack is no longer supported ( i.e. declaring a servlet
   * with the name jsp, mapping *.jsp -> jsp will work as required
   * by the servlet spec - no special hook is provided for initialization ).
   * Note that JspServlet doesn't work without special cases in ServletWrapper.
   * 
   * @author James Duncan Davidson [[EMAIL PROTECTED]]
   * @author Jason Hunter [[EMAIL PROTECTED]]
   * @author James Todd [[EMAIL PROTECTED]]
   * @author Harish Prabandham
   * @author Costin Manolache
   */
  public final class ServletHandler extends Handler {
  
      // extra informations - if the servlet is declared in web.xml
      private ServletInfo sw;
  
      private String servletClassName;
      protected Class servletClass;
      protected Servlet servlet;
  
      // If init() fails, Handler.errorException will hold the reason.
      // In the case of an UnavailableException, this field will hold
      // the expiration time if UnavailableException is not permanent.
      long unavailableTime=-1;
      
      public ServletHandler() {
        super();
      }
  
      public String toString() {
        return "ServletHandler " + name + "(" + sw  + ")";
      }
  
      public void setServletInfo( ServletInfo sw ) {
        this.sw=sw;
      }
      
      public ServletInfo getServletInfo() {
        if( sw==null ) {
            // it is possible to create a handler without ServletInfo
            // defaults are used.
            sw=new ServletInfo(this);
        }
        return sw;
      }
  
      public void setServletClassName( String servletClassName) {
        servlet=null; // reset the servlet, if it was set
        servletClass=null;
        this.servletClassName=servletClassName;
        if( debug>0 && sw.getPath()!=null)
            log( "setServletClassName for " + sw.getPath() +
                 ": " + servletClassName);
      }
  
      public String getServletClassName() {
        if( servletClassName == null )
            servletClassName=name;
          return servletClassName;
      }
  
      // -------------------- --------------------
  
      public void reload() {
        if( getState()==STATE_READY ) {
            try {
                destroy();
            } catch(Exception ex ) {
                log( "Error in destroy ", ex );
            }
        }
  
        if( sw.getServletClassName() != null ) {
            // I can survive reload
            servlet=null;
            servletClass=null;
        }
        setState( STATE_ADDED );
      }
      
      // -------------------- 
  
      public Servlet getServlet() 
        throws ClassNotFoundException, InstantiationException,
        IllegalAccessException
      {
        if(servlet!=null)
            return servlet;
  
        if( debug>0)
            log("LoadServlet " + name + " " + sw.getServletName() + " " +
                sw.getServletClassName() + " " + servletClass );
  
        // default
        if( servletClassName==null )
            servletClassName=name;
        
        if (servletClass == null) {
            servletClass=context.getClassLoader().loadClass(servletClassName);
        }
        
        servlet = (Servlet)servletClass.newInstance();
        return servlet;
      }
  
      // -------------------- Destroy --------------------
      
      protected void doDestroy() throws TomcatException {
        synchronized (this) {
            try {
                if( servlet!=null) {
                    BaseInterceptor cI[]=context.
                        getContainer().getInterceptors();
                    for( int i=0; i< cI.length; i++ ) {
                        try {
                            cI[i].preServletDestroy( context, this );
                        } catch( TomcatException ex) {
                            log("preServletDestroy", ex);
                        }
                    }
                    servlet.destroy();
  
                    for( int i=0; i< cI.length; i++ ) {
                        try {
                            cI[i].postServletDestroy( context, this );
                        } catch( TomcatException ex) {
                            log("postServletDestroy", ex);
                        }
                    }
                }
            } catch(Exception ex) {
                // Should never come here...
                log( "Error in destroy ", ex );
            }
        }
      }
  
      // Special hook
      protected void preInit() throws Exception
      {
        if( debug > 0 )
            log( "preInit " + servlet + " " + path + " " + servletClassName);
  
        // Deal with Unavailable errors
        if( ! checkAvailable() ) {
            // init can't proceed
            setState( STATE_DELAYED_INIT );
            return;
        }
        
        // For JSPs we rely on JspInterceptor to set the servlet class name.
        // We make no distinction between servlets and jsps.
        getServlet();
      }
  
      
      protected void doInit()
        throws Exception
      {
        try {
            servlet.init( getServletInfo().getServletConfig() );
        } catch( UnavailableException ex ) {
            // Implement the "UnavailableException" specification
            // servlet exception state
            setErrorException( ex );
            if ( ex.isPermanent() ) {
                setState( STATE_DISABLED );
            } else {
                setState( STATE_DELAYED_INIT );
                setServletUnavailable( ex );
            }
            servlet=null;
            throw ex;
            // it's a normal exception, servlet will
            // not be initialized.
        }
  
        // other exceptions are just thrown -
        // init() will deal with them.
      }
  
      protected void doService(Request req, Response res)
        throws Exception
      {
        // <servlet><jsp-file> case
        if( path!=null ) {
            if( path.startsWith("/"))
                req.setAttribute( "javax.servlet.include.request_uri",
                                  req.getContext().getPath()  + path );
            else
                req.setAttribute( "javax.servlet.include.request_uri",
                                  req.getContext().getPath()  + "/" + path );
            req.setAttribute( "javax.servlet.include.servlet_path", path );
        }
  
  
        // if unavailable
        if( ! checkAvailable() ) {
            // if error still present
            Exception ex=getErrorException();
            if( ex!=null ) {
                // save error state on request and response
                saveError( req, res, ex );
            }
            // if we have an error on this request
            if ( req.isExceptionPresent()) {
                // if in included, defer handling to higher level
                if ( res.isIncluded() )
                    return;
                // otherwise handle error
                contextM.handleError( req, res, getErrorException());
            }
            return; // we can't handle it
        }
  
        // Get facades - each req have one facade per context
        // the facade itself is very light.
  
        // For big servers ( with >100s of webapps ) we can
        // use a pool or other technique. Right now there
        // are many other ( much more expensive ) resources
        // associated with contexts ( like the session thread)
  
        // XXX
        HttpServletRequest reqF= (HttpServletRequest)req.getFacade();
        HttpServletResponse resF= (HttpServletResponse)res.getFacade();
        if( reqF == null || resF == null ||
            ! (reqF instanceof HttpServletRequestFacade) ) {
            reqF=new HttpServletRequestFacade(req);
            resF=new HttpServletResponseFacade(res);
            req.setFacade( reqF );
            res.setFacade( resF );
        }
  
        try {
            // We are initialized and fine
            if (servlet instanceof SingleThreadModel) {
                synchronized(servlet) {
                    servlet.service(reqF, resF);
                }
            } else {
                servlet.service(reqF, resF);
            }
        } catch ( UnavailableException ex ) {
            if ( ex.isPermanent() ) {
                setState( STATE_DISABLED );
            } else {
                setServletUnavailable((UnavailableException)ex );
            }
            if ( null != getErrorException() ) {
                synchronized(this) {
                    if ( null!= getErrorException() ) {
                        // servlet exception state
                        setErrorException( ex );
                    }
                }
            }
        }
        // other exceptions will be thrown
      }
  
      // -------------------- Unavailable --------------------
  
      /** Set unavailable time
       */
      private void setServletUnavailable( UnavailableException ex ) {
        unavailableTime=System.currentTimeMillis() +
            ex.getUnavailableSeconds() * 1000;
        setErrorException( ex );
      }
  
      /** Check if error exception is present and if so, has the error
        expired.  Sets error on request and response if un-expired
        error found.
       */
      private boolean checkAvailable() {
        if( unavailableTime == -1 )
            return true;
        
        // if permanent exception this code isn't called
        // if timer not expired
        if ( (unavailableTime - System.currentTimeMillis()) < 0) {
            // disable the error - it expired
            unavailableTime=-1;
            setErrorException(null);
            context.log(getName() +
                        " unavailable time expired, trying again ");
            return true;
        }
        // still unavailable
        return false;
      }
  }
  
  
  
  1.1                  
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletInfo.java
  
  Index: ServletInfo.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.util.collections.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import javax.servlet.*;
  import javax.servlet.http.*;
  
  /**
   * Class used to represent a servlet inside a Context.
   *
   * It will deal with all servlet-specific issues:
   * - load on startup
   * - servlet class name ( dynamic loading )
   * - init parameters
   * - security roles/mappings ( per servlet )
   * - jsp that acts like a servlet ( web.xml )
   * - reloading
   * 
   * @author James Duncan Davidson [[EMAIL PROTECTED]]
   * @author Jason Hunter [[EMAIL PROTECTED]]
   * @author James Todd [[EMAIL PROTECTED]]
   * @author Harish Prabandham
   * @author [EMAIL PROTECTED]
   */
  public class ServletInfo {
  
      // the actual tomcat handler associated with this servlet
      private ServletHandler handler;
  
      // facade
      protected ServletConfig configF;
  
      // optional informations
      protected String description = null;
  
      Hashtable securityRoleRefs=new Hashtable();
  
      Hashtable initArgs=null;
  
      // should be removed from handler
      private String path = null;
      protected int loadOnStartup=-1;
      protected boolean loadingOnStartup=false;
  
      public ServletInfo() {
        handler=new ServletHandler();
        handler.setServletInfo( this );
      }
  
      public ServletInfo( ServletHandler handler ) {
        this.handler=handler;
        handler.setServletInfo( this );
      }
  
      public String toString() {
        return "SW " + handler.getName() + "(" + path + "/" +
            handler.getServletClassName() +  ")";
      }
  
      // -------------------- Configuration hook
  
      /** This method can called to add the servlet to the web application.
       * ( typlically used from the config - WebXmlReader ).
       */
      public void addServlet(Context ctx) throws TomcatException {
        ctx.addServlet( handler );
        handler.setContext( ctx );
      }
  
      public void setContext(Context ctx ) {
        handler.setContext( ctx );
      }
      
      public Context getContext() {
        return handler.getContext();
      }
  
      public Handler getHandler() {
        return handler;
      }
  
      // -------------------- Init parameters --------------------
  
      /** Add configuration properties associated with this handler.
       *  This is a non-final method, handler may override it with an
       *  improved/specialized version.
       */
      public void addInitParam( String name, String value ) {
        if( initArgs==null) {
            initArgs=new Hashtable();
        }
        initArgs.put( name, value );
      }
  
      public String getInitParameter(String name) {
        if (initArgs != null) {
              return (String)initArgs.get(name);
          } else {
              return null;
          }
      }
      
      public Enumeration getInitParameterNames() {
          if (initArgs != null) {
              return initArgs.keys();
          } else {
            return EmptyEnumeration.getEmptyEnumeration();
        }
      }
  
      // -------------------- Servlet specific properties 
      public void setLoadOnStartUp( int level ) {
        loadOnStartup=level;
        // here setting a level implies loading
        loadingOnStartup=true;
      }
  
      public void setLoadOnStartUp( String level ) {
        if (level.length() > 0)
            loadOnStartup=new Integer(level).intValue();
        else
            loadOnStartup=-1;
        // here setting a level implies loading
        loadingOnStartup=true;
      }
  
      public int getLoadOnStartUp() {
        return loadOnStartup;
      }
  
      public boolean getLoadingOnStartUp() {
        return loadingOnStartup;
      }
  
      public String getServletName() {
        return handler.getName();
      }
  
      public void setServletName(String servletName) {
        handler.setName(servletName);
      }
  
      public String getServletDescription() {
          return this.description;
      }
  
      public void setServletDescription(String description) {
          this.description = description;
      }
  
      public String getServletClassName() {
        return handler.getServletClassName();
      }
  
      public void setServletClassName(String servletClassName) {
        handler.setServletClassName( servletClassName );
      }
      
      /** Security Role Ref represent a mapping between servlet role names and
       *  server roles
       */
      public void addSecurityMapping( String name, String role,
                                    String description ) {
        securityRoleRefs.put( name, role );
      }
  
      public String getSecurityRole( String name ) {
        return (String)securityRoleRefs.get( name );
      }
  
      // -------------------- Jsp specific code
      
      public String getPath() {
          return this.path;
      }
  
      public void setPath(String path) {
          this.path = path;
        if( handler.getName() == null ) 
            handler.setName(path);
        // the path will serve as servlet name if not set
      }
  
      // -------------------- 
  
      public ServletConfig getServletConfig() {
        if( configF==null )
            configF=new ServletConfigImpl( this );
        return configF;
      }
      
  }
  
  
  
  1.15      +62 -24    
jakarta-tomcat/src/facade22/org/apache/tomcat/modules/facade22/JspInterceptor.java
  
  Index: JspInterceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/modules/facade22/JspInterceptor.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- JspInterceptor.java       2000/12/12 00:42:42     1.14
  +++ JspInterceptor.java       2000/12/12 20:21:29     1.15
  @@ -73,7 +73,7 @@
   import org.apache.jasper.compiler.*;
   import org.apache.jasper.compiler.Compiler;
   import org.apache.tomcat.core.*;
  -import org.apache.tomcat.facade.ServletWrapper;
  +import org.apache.tomcat.facade.ServletHandler;
   
   /**
    * Plug in the JSP engine (a.k.a Jasper)! 
  @@ -128,30 +128,63 @@
       public void preServletInit( Context ctx, Handler sw )
        throws TomcatException
       {
  -     if( ! (sw instanceof ServletWrapper) )
  +     if( ! (sw instanceof ServletHandler) )
            return;
  -     Servlet theServlet = ((ServletWrapper)sw).getServlet();
  -     if (theServlet instanceof HttpJspBase)  {
  -         if( debug > 0 )
  -             log( "PreServletInit: HttpJspBase.setParentClassLoader" + sw );
  -         HttpJspBase h = (HttpJspBase) theServlet;
  -         h.setClassLoader(ctx.getClassLoader());
  +     try {
  +         Servlet theServlet = ((ServletHandler)sw).getServlet();
  +         if (theServlet instanceof HttpJspBase)  {
  +             if( debug > 0 )
  +                 log( "PreServletInit: HttpJspBase.setParentClassLoader" +
  +                      sw );
  +             HttpJspBase h = (HttpJspBase) theServlet;
  +             h.setClassLoader(ctx.getClassLoader());
  +         }
  +     } catch(Exception ex ) {
  +         throw new TomcatException( ex );
        }
       }
   
  +    /** 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=(Handler)req.getHandler();
  +     Handler wrapper=req.getHandler();
   
  -     //      log( "Try: " + req );
  -     
  -     if( wrapper!=null && ! "jsp".equals( wrapper.getName())
  -         && wrapper.getPath() == null)
  +     if( wrapper==null )
            return 0;
   
  -     // XXX jsp handler is still needed
  -     if( wrapper==null )
  +     // That's equivalent with the previous behavior
  +     // of tomcat, where a special "jsp" handler was defined.
  +
  +     // we should change that - but we need a way to map
  +     // other extensions, and that is backward compatible
  +
  +     // the condition is: continue if the request is mapped to
  +     // the special "jsp" handler ( as result of *.jsp ) or
  +     // to a named handler that has a path ( <servlet> defined with path)
  +     if( ! ( "jsp".equals( wrapper.getName()) ||
  +             ( wrapper instanceof ServletHandler &&
  +               ((ServletHandler)wrapper).getServletInfo().getPath()
  +               != null)
  +             )) {
            return 0;
  -     
  +     }
  +
        Context ctx= req.getContext();
   
        // If this Wrapper was already used, we have all the info
  @@ -200,22 +233,24 @@
                     String servletName, String classN )
       {
        Context ctx=req.getContext();
  -     ServletWrapper wrapper=null;
  +     Handler wrapper=null;
        String servletPath=servletName;
        // 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 {
  -         wrapper=(ServletWrapper)ctx.getServletByName( servletName );
  +         wrapper=ctx.getServletByName( servletName );
            // We may want to replace the class and reset it if changed
            
            if( wrapper==null ) {
  -             wrapper=new ServletWrapper();
  +             wrapper=new ServletHandler();
                wrapper.setContext(ctx);
  -             wrapper.setServletName(servletName);
  -             wrapper.setPath( servletPath );
  +             wrapper.setName(servletName);
                wrapper.setOrigin( Handler.ORIGIN_INVOKER );
  +
  +             ((ServletHandler)wrapper).getServletInfo().
  +                 setPath( servletPath );
                ctx.addServlet( wrapper );
                
                ctx.addServletMapping( servletPath ,
  @@ -224,7 +259,7 @@
                    log( "Added mapping " + servletPath +
                         " path=" + servletPath );
            }
  -         wrapper.setServletClassName( classN );
  +         ((ServletHandler)wrapper).setServletClassName( classN );
            wrapper.setNote( jspInfoNOTE, jspInfo );
            // set initial exception on the servlet if one is present
            if ( jspInfo.isExceptionPresent() ) {
  @@ -232,11 +267,14 @@
                wrapper.setState(Handler.STATE_DISABLED);
            }
        } catch( TomcatException ex ) {
  -         log("mapJspPage: request=" + req + ", jspInfo=" + jspInfo + ", 
servletName=" + servletName + ", classN=" + classN, ex);
  +         log("mapJspPage: request=" + req +
  +             ", jspInfo=" + jspInfo +
  +             ", servletName=" + servletName +
  +             ", classN=" + classN, ex);
            return ;
        }
        req.setHandler( wrapper );
  -     if( debug>0) log("Wrapper " + wrapper);
  +     if( debug>0) log("Handler " + wrapper);
       }
   
       /** Convert the .jsp file to a java file, then compile it to class
  
  
  
  1.1                  
jakarta-tomcat/src/facade22/org/apache/tomcat/modules/facade22/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.modules.facade22;
  
  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().
                            getPath() != null ) {
                            loadJsp( ctx, result );
                        } else {
                            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().getPath();
        Request request = new Request();
        Response response = new Response();
        request.recycle();
        response.recycle();
        cm.initRequest(request,response);
        
        String requestURI = path + "?jsp_precompile=true";
        
        request.requestURI().setString(context.getPath() + path);
        request.queryString().setString( "jsp_precompile=true" );
        
        request.setContext(context);
  
        cm.service( request, response );
      }
      // -------------------- 
      // 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.27      +10 -63    jakarta-tomcat/src/share/org/apache/tomcat/core/Handler.java
  
  Index: Handler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Handler.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- Handler.java      2000/12/12 00:42:46     1.26
  +++ Handler.java      2000/12/12 20:21:38     1.27
  @@ -182,24 +182,16 @@
   
       private int state=STATE_NEW;
       
  -    Hashtable initArgs=null;
  -
       // who creates the servlet definition
       protected int origin;
   
       protected String path;
   
  -    protected String servletName;
  -
  -    protected int loadOnStartup=-1;
  -    protected boolean loadingOnStartup=false;
  -
       protected Exception errorException=null;
       
       // Debug
       protected int debug=0;
       protected Log logger=null;
  -    protected String debugHead=null;
   
       private Counters cntr=new Counters( ACCOUNTS );
       private Object notes[]=new Object[ContextManager.MAX_NOTES];
  @@ -268,22 +260,6 @@
       }
   
       // -------------------- Common servlet attributes
  -    public void setLoadOnStartUp( int level ) {
  -     loadOnStartup=level;
  -    }
  -
  -    public int getLoadOnStartUp() {
  -     return loadOnStartup;
  -    }
  -
  -    public void setLoadingOnStartUp( boolean load ) {
  -     loadingOnStartup=load;
  -    }
  -
  -    public boolean getLoadingOnStartUp() {
  -     return loadingOnStartup;
  -    }
  -
       /** Sets an exception that relates to the ability of the
        servlet to execute.  An exception may be set by an
        interceptor if there is an error during the creation
  @@ -300,46 +276,17 @@
        return errorException;
       }
   
  -    // -------------------- Jsp specific code
  +//     // -------------------- Jsp specific code
       
  -    public String getPath() {
  -        return this.path;
  -    }
  -
  -    public void setPath(String path) {
  -        this.path = path;
  -     if( name==null )
  -         name=path; // the path will serve as servlet name if not set
  -    }
  -
  -    // -------------------- Init params
  -
  -    /** Add configuration properties associated with this handler.
  -     *  This is a non-final method, handler may override it with an
  -     *  improved/specialized version.
  -     */
  -    public void addInitParam( String name, String value ) {
  -     if( initArgs==null) {
  -         initArgs=new Hashtable();
  -     }
  -     initArgs.put( name, value );
  -    }
  -
  -    public String getInitParameter(String name) {
  -     if (initArgs != null) {
  -            return (String)initArgs.get(name);
  -        } else {
  -            return null;
  -        }
  -    }
  -    
  -    public Enumeration getInitParameterNames() {
  -        if (initArgs != null) {
  -            return initArgs.keys();
  -        } else {
  -         return EmptyEnumeration.getEmptyEnumeration();
  -     }
  -    }
  +//     public String getPath() {
  +//         return this.path;
  +//     }
  +
  +//     public void setPath(String path) {
  +//         this.path = path;
  +//   if( name==null )
  +//       name=path; // the path will serve as servlet name if not set
  +//     }
   
       // -------------------- Methods --------------------
   
  
  
  
  1.32      +2 -1      
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.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- EmbededTomcat.java        2000/11/22 01:10:30     1.31
  +++ EmbededTomcat.java        2000/12/12 20:21:43     1.32
  @@ -353,7 +353,8 @@
        addInterceptor( wdI );
   
        
  -     LoadOnStartupInterceptor loadOnSI=new LoadOnStartupInterceptor();
  +     BaseInterceptor loadOnSI= 
(BaseInterceptor)newObject("org.apache.tomcat.modules.facade22.LoadOnStartupInterceptor");
  +     //      LoadOnStartupInterceptor loadOnSI=new LoadOnStartupInterceptor();
        addInterceptor( loadOnSI );
   
        // Debug
  
  
  

Reply via email to