costin      00/12/02 00:27:05

  Modified:    src/share/org/apache/tomcat/core BaseInterceptor.java
                        ContextManager.java
               src/share/org/apache/tomcat/request ReloadInterceptor.java
               src/share/org/apache/tomcat/util/collections MultiMap.java
               src/share/org/apache/tomcat/util/depend DependManager.java
               src/share/org/apache/tomcat/util/http Parameters.java
  Log:
  - Fixed the documentation of ContextManager ( or started to ), fixed
  the shutdown. Thanks Larry, I think now is better. I'll continue to
  fix the code to match the documentation.
  
  - fixed the compilation for jdk1.1.7 ( the compiler is buggy )
  
  - make sure the "JVM is broken" is displayed only once, no need
  to see it for every request.
  
  Revision  Changes    Path
  1.26      +5 -0      
jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java
  
  Index: BaseInterceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- BaseInterceptor.java      2000/11/02 21:24:42     1.25
  +++ BaseInterceptor.java      2000/12/02 08:26:45     1.26
  @@ -247,6 +247,9 @@
        * 
        *  WebXmlReader needs to be the first interceptor in
        *  the contextInit chain.
  +     *
  +     *  @exception If the interceptor throws exception the context will 
  +     *             not be initialized ( state==NEW or ADDED or DISABLED ).
        */
       public void contextInit(Context ctx)
        throws TomcatException
  @@ -307,6 +310,8 @@
       }
   
       /** Called when the ContextManger is started
  +     *  @exception TomcatException The server will not start if any exception is 
thrown by
  +     *  engineInit
        */
       public void engineInit(ContextManager cm)
        throws TomcatException
  
  
  
  1.153     +151 -94   
jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java
  
  Index: ContextManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v
  retrieving revision 1.152
  retrieving revision 1.153
  diff -u -r1.152 -r1.153
  --- ContextManager.java       2000/12/01 17:42:51     1.152
  +++ ContextManager.java       2000/12/02 08:26:47     1.153
  @@ -90,76 +90,91 @@
     One application may try to embed multiple ( distinct ) servlet containers -
     this feature hasn't been tested or used
    
  - 
  -   Expected startup order:
  +   <h2>Startup</h2>
   
  -  1. Create ContextManager
  +  1. Create ContextManager.
   
  -  2. Set settable properties for ContextManager ( home, debug, etc)
  +  2. Set properties for ContextManager ( home, debug, etc).
   
  -  3. Add global Interceptors
  +  3. Add global Interceptors.
   
     4. You may create, set and add Contexts. NO HOOKS ARE CALLED.
  +      This adds a lot of complexity to the code - but allow
  +      the server to have an initial set of contexts when it starts.
  +      More contexts can be added after startup.
     
  -  5. Call init(). At this stage engineInit() callback will be
  -     called for all global interceptors.
  -     - DefaultCMSetter ( or a replacement ) must be the first in
  -     the chain and will adjust the paths and set defaults for
  -     all unset properties.
  -     - AutoSetup and other interceptors can automatically add/set
  -     more properties and make other calls.
  +  5. init() At this stage engineInit() callback will be
  +     called for all global interceptors. 
   
  -     During engineInit() a number of Contexts are created and
  +     During engineInit() a number of Contexts can be created and
        added to the server. No addContext() callback is called until
  -     the last engineInit() returns. ( XXX do we need this restriction ?)
  +     the last engineInit() returns. Interceptors can also change the
  +     state of the server ( change properites, add other interceptors,
  +     etc)
   
  -  XXX I'n not sure about contextInit and about anything below.
  +     After this call the server will be in INITIALIZED state.
  +     No callback other than engineInit  can be called before the server
  +     enters this state.
   
  -  x. Server will move to INITIALIZED state. No callback other than engineInit
  -     can be called before the server enters this state.
  +  6. init() will also call the addContext() hook for all contexts
  +     that were added during engineInit or before init() was called.
  +     More contexts can be added after init() and before start().
   
  -  x. addContext() callbacks will be called for each context.
  -     After init you may add more contexts, and addContext() callback
  -     will be called (since the server is initialized )
  +     InitContext will have no effect before the server is started -
  +     all initContexts for added contexts will be called automatically
  +     at start.
   
  -  x. Call start().
  +  7. start(). All contexts will be initialized ( contextInit()
  +     callback ). ContextInit will move the context to READY state,
  +     allowing it to serve requests.
   
  -  x. All contexts will be initialized ( contextInit()
  -     callback ).
  +     Server will move to START state after all configured contexts
  +     are READY. No servlet should be served before the container is
  +     in START state ( tomcat should return "Server not ready") .
   
  -  x. Server will move to STARTED state. No servlet should be 
  -     served before this state.
  +     <h2>Normal operation</h2>
   
  -     
  -     During normal operation, it is possible to add  Contexts.
  +  1. Requests for a context in READY state will be served by that context.
  +     Requests for a context that is not READY will return an error (
  +     "application temp. unavailable" - no 404 on the parent context !)
   
  -  1. Create the Context, set properties ( that can be done from servlets
  -     or by interceptors like ~user)
  +  2. At any time you can create a new Context, set properties ( that can
  +     be done from servlets or by interceptors like ~user). The context is
  +     not visible to tomcat until addContext completes.
   
  -  2. call CM.addContext(). This will triger the addContext() callback.
  -     ( if CM is initialized )
  +  3. addContext(). This will triger the addContext() callback.
   
  -  3. call CM.initContext( ctx ). This will triger contextInit() callback.
  -     After that the context is initialized and can serve requests.
  -     No request belonging to this context can't be served before this
  -     method returns.
  +  4. initContext(). This will triger contextInit() callbacks/
  +     After that the context is READY and can serve requests.
   
  -     XXX Context state
  -     
  -     It is also possible to remove Contexts.
  +  5. You can find a Context by enumerating all added contexts.
   
  -  1. Find the Context ( enumerate all existing contexts and find the one
  -    you need - host and path are most likely keys ).
  +  6. contextShutdown(). The context will no longer be READY and can't
  +     serve requests ( Application unavailable ). contextShutdown hooks
  +     are called
   
  -  2. Call removeContext(). This will call removeContext() callbacks.
  +  7. removeContext(). This will call removeContext() hooks. After this
  +     method the context will no longer be visible to tomcat and will
  +     be removed from the list of known contexts. Requests for this
  +     context will be served by the parent context ( or root )
   
  -  
  -     To stop the server, you need to:
  +     <h2>Stopping the server</h2>
  +
  +  1. stop(). The server will exit the START state and enter STOP,any request
  +     will get a "Server unavailable" error. All contextShutdown() and
  +     will be called. ( STOP==INIT ? )
   
  -  1. Call shutdown().
  +  2. shutdown(). All  removeContext() callbacks will be called and the server
  +      will enter PRE_INIT state. The contexts will not be removed from
  +      the server - it is possible to call init again ( server restart ? )
   
  -  2. The server will ...
  +  Notes: 
  +  DefaultCMSetter ( or a replacement ) must be the first in
  +  the chain and will adjust the paths and set defaults for
  +  all unset properties.
   
  +  AutoSetup and other interceptors can automatically add/set
  +  more properties and make other calls.
    
     @author James Duncan Davidson [[EMAIL PROTECTED]]
     @author James Todd [[EMAIL PROTECTED]]
  @@ -385,39 +400,35 @@
        */
       public final void init()  throws TomcatException {
        if(debug>0 ) log( "Tomcat init");
  -
  +     if( state!= STATE_PRE_INIT  )
  +         throw new TomcatException("Invalid state in init " + state );
  +     
        BaseInterceptor cI[]=defaultContainer.getInterceptors();
        for( int i=0; i< cI.length; i++ ) {
            cI[i].setContextManager( this );
  +         // If an exception is thrown, the server will not
  +         // move to INIT state.
            cI[i].engineInit( this );
        }
   
        state=STATE_INIT;
   
  -     // delayed execution of addContext
  +     // delayed execution of addContext.
  +     // If any context is added before init, its initialization
  +     // will be delayed until INIT
        Enumeration existingCtxE=contextsV.elements();
        while( existingCtxE.hasMoreElements() ) {
            Context ctx=(Context)existingCtxE.nextElement();
  -         cI=ctx.getContainer().getInterceptors();
  -         for( int i=0; i< cI.length; i++ ) {
  -             cI[i].addContext( this, ctx );
  +         try {
  +             cI=ctx.getContainer().getInterceptors();
  +             for( int i=0; i< cI.length; i++ ) {
  +                 cI[i].addContext( this, ctx );
  +             }
  +             ctx.setState( Context.STATE_ADDED );
  +         } catch( TomcatException ex ) {
  +             log( "Context not added " + ctx , ex );
  +             continue;
            }
  -         ctx.setState( Context.STATE_ADDED );
  -     }
  -    }
  -
  -    /** Remove all contexts.
  -     *  - call removeContext ( that will call Interceptor.removeContext hooks )
  -     *  - call Interceptor.engineShutdown() hooks.
  -     */
  -    public final void shutdown() throws TomcatException {
  -     while (!contextsV.isEmpty()) {
  -         removeContext((Context)contextsV.firstElement());
  -     }
  -
  -     BaseInterceptor cI[]=defaultContainer.getInterceptors();
  -     for( int i=0; i< cI.length; i++ ) {
  -         cI[i].engineShutdown( this );
        }
       }
   
  @@ -425,17 +436,24 @@
        *  It must be called after init.
        */
       public final void start() throws TomcatException {
  -
  +     if( state!=STATE_INIT )
  +         throw new TomcatException( "Invalid state in start(), " +
  +                                    " you need to call init() "+ state);
  +     
        Enumeration enum = getContexts();
        while (enum.hasMoreElements()) {
            Context ctx = (Context)enum.nextElement();
  -         BaseInterceptor cI[]=ctx.getContainer().getInterceptors();
  -         for( int i=0; i< cI.length; i++ ) {
  -             cI[i].contextInit( ctx );
  +         try {
  +             initContext( ctx );
  +         } catch( TomcatException ex ) {
  +             // just log the error, the context will not serve
  +             // requests but we go on
  +             log( "Error initializing " + ctx , ex );
  +             continue; 
            }
  -         ctx.setState( Context.STATE_READY );
        }
  -     
  +
  +     // requests can be processed now
        state=STATE_START;
       }
   
  @@ -445,6 +463,21 @@
        shutdown();
       }
   
  +    /** Remove all contexts.
  +     *  - call removeContext ( that will call Interceptor.removeContext hooks )
  +     *  - call Interceptor.engineShutdown() hooks.
  +     */
  +    public final void shutdown() throws TomcatException {
  +     while (!contextsV.isEmpty()) {
  +         removeContext((Context)contextsV.firstElement());
  +     }
  +
  +     BaseInterceptor cI[]=defaultContainer.getInterceptors();
  +     for( int i=0; i< cI.length; i++ ) {
  +         cI[i].engineShutdown( this );
  +     }
  +    }
  +
       // -------------------- Contexts --------------------
   
       /** Return the list of contexts managed by this server
  @@ -465,22 +498,31 @@
        * @param ctx context to be added.
        */
       public final void addContext( Context ctx ) throws TomcatException {
  -     log("Adding context " +  ctx.toString());
  -     
        // Make sure context knows about its manager.
        ctx.setContextManager( this );
        ctx.setState( Context.STATE_NEW );
  -     
  +
  +     // Add it to the contextV, when init all contexts will be added
        contextsV.addElement( ctx );
   
  -     if( state == STATE_PRE_INIT )
  -         return; 
  +     if( state == STATE_PRE_INIT ) {
  +         log( "Delay context add " + ctx.toString());
  +         return;
  +     }
        
  -     BaseInterceptor cI[]=ctx.getContainer().getInterceptors();
  -     for( int i=0; i< cI.length; i++ ) {
  -         cI[i].addContext( this, ctx );
  +     try {
  +         BaseInterceptor cI[]=ctx.getContainer().getInterceptors();
  +         for( int i=0; i< cI.length; i++ ) {
  +             // If an exception is thrown, context will remain in
  +             // NEW state.
  +             cI[i].addContext( this, ctx ); 
  +         }
  +         ctx.setState( Context.STATE_ADDED );
  +         log("Adding context " +  ctx.toString());
  +     } catch (TomcatException ex ) {
  +         log( "Context not added " + ctx , ex );
  +         throw ex;
        }
  -     ctx.setState( Context.STATE_ADDED );
       }
   
       /** Shut down and removes a context from service.
  @@ -489,24 +531,29 @@
        if( context==null ) return;
   
        log( "Removing context " + context.toString());
  -     
  -     // disable the context.
  -     if( context.getState() == Context.STATE_READY )
  -         shutdownContext( context );
   
        contextsV.removeElement(context);
   
  -     if( context.getState() == Context.STATE_DISABLED )
  +     // if it's already disabled - or was never activated,
  +     // no need to shutdown and remove
  +     if( context.getState() == Context.STATE_NEW )
            return;
        
  -     context.setState( Context.STATE_NEW );
  +     // disable the context - it it is running 
  +     // ( it is possible to explicitely shut it down before
  +     // calling removeContext )
  +     if( context.getState() == Context.STATE_READY )
  +         shutdownContext( context );
   
  -     // remove it from operation
  +     // remove it from operation - notify interceptors that
  +     // this context is no longer active
        BaseInterceptor cI[]=context.getContainer().getInterceptors();
        for( int i=0; i< cI.length; i++ ) {
            cI[i].removeContext( this, context );
        }
   
  +     // mark the context as "not active" 
  +     context.setState( Context.STATE_NEW );
       }
   
   
  @@ -522,14 +569,21 @@
        *
        * After this call, the context will be in READY state and will
        * be able to server requests.
  +     * 
  +     * @exception if any interceptor throws an exception the error
  +     *   will prevent the context from becoming READY
        */
       public final void initContext( Context ctx ) throws TomcatException {
  -     if( state!= STATE_PRE_INIT ) {
  -         BaseInterceptor cI[]=ctx.getContainer().getInterceptors();
  -         for( int i=0; i< cI.length; i++ ) {
  -             cI[i].contextInit( ctx );
  -         }
  +     // no action if ContextManager is not initialized
  +     if( state == STATE_PRE_INIT )
  +         throw new TomcatException("Invalid state");
  +     
  +     BaseInterceptor cI[]=ctx.getContainer().getInterceptors();
  +     for( int i=0; i< cI.length; i++ ) {
  +         cI[i].contextInit( ctx );
        }
  +     
  +     // Only if all init methods succeed an no ex is thrown
        ctx.setState( Context.STATE_READY );
       }
   
  @@ -542,10 +596,13 @@
   
        All servlets will be destroyed, and resources held by the
        context will be freed.
  +
  +     The contextShutdown callbacks can wait until the running serlvets
  +     are completed - there is no way to force the shutdown.
        */
       public final void shutdownContext( Context ctx ) throws TomcatException {
        ctx.setState( Context.STATE_DISABLED ); // called before
  -     // the hook, no request should be allowed in unstable state
  +     // the hook, no more request should be allowed in unstable state
   
        BaseInterceptor cI[]=ctx.getContainer().getInterceptors();
        for( int i=0; i< cI.length; i++ ) {
  
  
  
  1.9       +3 -0      
jakarta-tomcat/src/share/org/apache/tomcat/request/ReloadInterceptor.java
  
  Index: ReloadInterceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/ReloadInterceptor.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ReloadInterceptor.java    2000/11/02 21:44:50     1.8
  +++ ReloadInterceptor.java    2000/12/02 08:26:49     1.9
  @@ -125,6 +125,9 @@
   
        if( ! ctx.shouldReload() ) return 0;
   
  +     if( debug> 0 )
  +         log( "Detected changes in " + ctx.toString());
  +
        try {
            // Reload context.  
            ContextManager cm=ctx.getContextManager();
  
  
  
  1.2       +8 -6      
jakarta-tomcat/src/share/org/apache/tomcat/util/collections/MultiMap.java
  
  Index: MultiMap.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/collections/MultiMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- MultiMap.java     2000/11/30 17:34:16     1.1
  +++ MultiMap.java     2000/12/02 08:26:53     1.2
  @@ -232,7 +232,7 @@
   
       public int findNext( int startPos ) {
        int next= fields[startPos].nextPos;
  -     if( next != Field.NEED_NEXT ) {
  +     if( next != MultiMap.NEED_NEXT ) {
            return next;
        }
   
  @@ -245,10 +245,14 @@
                return i;
            }
        }
  -     fields[startPos].nextPos= Field.LAST;
  +     fields[startPos].nextPos= MultiMap.LAST;
           return -1;
       }
   
  +    // workaround for JDK1.1.8/solaris
  +    static final int NEED_NEXT=-2;
  +    static final int LAST=-1;
  +
       // -------------------- Internal representation --------------------
       final class Field {
        MessageBytes name;
  @@ -258,8 +262,6 @@
        
        //  multiple fields with same name - a linked list will
        // speed up multiple name enumerations and search.
  -     static final int NEED_NEXT=-2;
  -     static final int LAST=-1;
        int nextPos;
   
        // hashkey
  @@ -267,13 +269,13 @@
        Field nextSameHash;
   
        Field() {
  -         nextPos=NEED_NEXT;
  +         nextPos=MultiMap.NEED_NEXT;
        }
        
        void recycle() {
            name.recycle();
            value.recycle();
  -         nextPos=NEED_NEXT;
  +         nextPos=MultiMap.NEED_NEXT;
        }
       }
   }
  
  
  
  1.3       +5 -2      
jakarta-tomcat/src/share/org/apache/tomcat/util/depend/DependManager.java
  
  Index: DependManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/depend/DependManager.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DependManager.java        2000/12/01 23:15:22     1.2
  +++ DependManager.java        2000/12/02 08:26:58     1.3
  @@ -101,11 +101,14 @@
        return checkCount;
       }
   
  +    private static boolean noWarnBadVM=true;
       public boolean shouldReload() {
        boolean b=shouldReload1();
  -     if( b!=expired)
  +     if( b!=expired && noWarnBadVM ) {
            log("BUG ( VM or Tomcat? ) shouldReload returns expired=" + b +
                " and the real value is " + expired);
  +         noWarnBadVM=false;
  +     }
        return expired;
       }
   
  @@ -173,7 +176,7 @@
   
       // -------------------- Private 
   
  -    private static final int debug=10;
  +    private static final int debug=0;
       
       void log( String s ) {
        System.out.println("DependManager: " + s );
  
  
  
  1.2       +15 -1     
jakarta-tomcat/src/share/org/apache/tomcat/util/http/Parameters.java
  
  Index: Parameters.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/http/Parameters.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Parameters.java   2000/11/30 17:42:49     1.1
  +++ Parameters.java   2000/12/02 08:27:03     1.2
  @@ -87,7 +87,21 @@
        isSet=false;
        isFormBased=false;
       }
  -
  +    // XXX need better name
  +    public boolean isEvaluated() {
  +     return isSet;
  +    }
  +    public void setEvaluated( boolean b ) {
  +     isSet=b;
  +    }
  +    // XXX need better name
  +    public boolean hasFormData() {
  +     return isFormBased;
  +    }
  +    public void setFormData(boolean b ) {
  +     isFormBased=b;
  +    }
  +    
       // duplicated
       public static int indexOf( byte bytes[], int off, int end, char qq )
       {
  
  
  

Reply via email to