You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by dl...@apache.org on 2001/12/29 23:32:49 UTC

cvs commit: jakarta-turbine-3/src/java/org/apache/turbine/pipeline BasePipeline.java DefaultActionValve.java DefaultTargetValve.java ClassicPipeline.java DirectClassicPipeline.java

dlr         01/12/29 14:32:49

  Modified:    src/java/org/apache/turbine Pipeline.java Turbine.java
               src/java/org/apache/turbine/pipeline ClassicPipeline.java
                        DirectClassicPipeline.java
  Added:       src/java/org/apache/turbine Valve.java ValveContext.java
               src/java/org/apache/turbine/pipeline BasePipeline.java
                        DefaultActionValve.java DefaultTargetValve.java
  Log:
  A simplified Catalina-style Pipeline with continued support for classic mode.  This commit should not change existing function -- it should only improve flexibility.
  
  Revision  Changes    Path
  1.4       +34 -34    jakarta-turbine-3/src/java/org/apache/turbine/Pipeline.java
  
  Index: Pipeline.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-3/src/java/org/apache/turbine/Pipeline.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -u -r1.3 -r1.4
  --- Pipeline.java	28 Dec 2001 02:27:12 -0000	1.3
  +++ Pipeline.java	29 Dec 2001 22:32:48 -0000	1.4
  @@ -54,7 +54,9 @@
    * <http://www.apache.org/>.
    */
   
  -/*
  +import java.io.IOException;
  +
  +/**
    * The idea of a pipeline is being taken from Catalina
    * in its entirety :-)
    *
  @@ -74,61 +76,59 @@
    * work this can be fully working. The first pipeline
    * to be fully implemented will the ClassicPipeline
    * will emulate the Turbine 2.1 way of doing things.
  + *
  + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
  + * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
    */
  -
   public interface Pipeline
   {
       /**
  -     * Initializes this instance.  Called once.
  +     * Initializes this instance.  Called once by the Turbine servlet.
        */
       public void init()
           throws Exception;
   
       /**
  -     * Processes the pipeline.  Called at the beginning of each
  -     * request.
  -     */
  -    public void process(RunData data)
  -        throws Exception;
  -
  -    /**
  -     * Called before the action is executed.  Called for each request.
  +     * <p>Add a new Valve to the end of the pipeline.</p>
        *
  -     * @param data Run-time information.
  -     */
  -    public void preExecuteAction(RunData data)
  -        throws Exception;
  -
  -    /**
  -     * Executes the action.  Called for each request.
  +     * @param valve Valve to be added.
        *
  -     * @param data Run-time information.
  +     * @exception IllegalStateException If the pipeline has not been
  +     * initialized.
        */
  -    public void executeAction(RunData data)
  -        throws Exception;
  +    public void addValve(Valve valve);
   
       /**
  -     * Called after the action is executed.  Called for each request.
  +     * Return the set of all Valves in the pipeline.  If there are no
  +     * such Valves, a zero-length array is returned.
        *
  -     * @param data Run-time information.
  +     * @return An array of valves.
        */
  -    public void postExecuteAction(RunData data)
  -        throws Exception;
  +    public Valve[] getValves();
   
       /**
  -     * Executes the pipeline.  Called for each request.
  +     * <p>Cause the specified request and response to be processed by
  +     * the sequence of Valves associated with this pipeline, until one
  +     * of these Valves decides to end the processing.</p>
        *
  -     * @param data Run-time information.
  +     * <p>The implementation must ensure that multiple simultaneous
  +     * requests (on different threads) can be processed through the
  +     * same Pipeline without interfering with each other's control
  +     * flow.</p>
  +     *
  +     * @param data The run-time information, including the servlet
  +     * request and response we are processing.
  +     *
  +     * @exception IOException an input/output error occurred.
        */
  -    public void execute(RunData data)
  -        throws Exception;
  +    public void invoke(RunData data)
  +        throws TurbineException, IOException;
   
       /**
  -     * Called after the pipeline has been executed.  Called at the end
  -     * of each request.
  +     * Remove the specified Valve from the pipeline, if it is found;
  +     * otherwise, do nothing.
        *
  -     * @param data Run-time information.
  +     * @param valve Valve to be removed.
        */
  -    public void finished(RunData data)
  -        throws Exception;
  +    public void removeValve(Valve valve);
   }
  
  
  
  1.18      +19 -15    jakarta-turbine-3/src/java/org/apache/turbine/Turbine.java
  
  Index: Turbine.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-3/src/java/org/apache/turbine/Turbine.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -u -r1.17 -r1.18
  --- Turbine.java	28 Dec 2001 02:16:35 -0000	1.17
  +++ Turbine.java	29 Dec 2001 22:32:48 -0000	1.18
  @@ -77,6 +77,7 @@
   import org.apache.fulcrum.TurbineServices;
   import org.apache.log4j.Category;
   import org.apache.turbine.modules.ModuleLoader;
  +import org.apache.turbine.pipeline.DefaultTargetValve;
   import org.apache.turbine.services.rundata.RunDataService;
   
   /**
  @@ -118,11 +119,11 @@
    * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
    * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
  - * @version $Id: Turbine.java,v 1.17 2001/12/28 02:16:35 dlr Exp $
  + * @version $Id: Turbine.java,v 1.18 2001/12/29 22:32:48 dlr Exp $
    */
   public class Turbine
       extends HttpServlet
  -    implements TurbineConstants
  +    implements TurbineConstants, ValveContext
   {
       /**
        * In certain situations the init() method is called more than once,
  @@ -280,12 +281,7 @@
               // in catalina there is also a ValveContext which
               // can alter the execution path of the valves. What
               // is listed below here could eventually be anything :-)
  -            pipeline.process(data);
  -            pipeline.preExecuteAction(data);
  -            pipeline.executeAction(data);
  -            pipeline.postExecuteAction(data);
  -            pipeline.execute(data);
  -            pipeline.finished(data);
  +            pipeline.invoke(data);
   
               /*
               TODO: Move this logic into the pipeline.
  @@ -336,6 +332,13 @@
       }
   
       /**
  +     * No-op implementation of ValveContext interface.
  +     */
  +    public final void invokeNext(RunData ignored)
  +    {
  +    }
  +
  +    /**
        * Return the servlet info.
        *
        * @return a string with the servlet information.
  @@ -398,8 +401,10 @@
                   data.setTarget(configuration
                                  .getString("template.error","/Error.vm"));
                   data.setStackTrace(StringUtils.stackTrace(t), t);
  -                pipeline.execute(data);
  -                pipeline.finished(data);
  +
  +                // We act as a minimal Pipeline here to run the target
  +                // set above.
  +                new DefaultTargetValve().invoke(data, this);
               }
               catch (Exception f)
               {
  @@ -407,9 +412,8 @@
                   
                   try
                   {
  -                    // This should be more useful and formatted in
  -                    // a useful fashion but this will get rid of ECS
  -                    // for the time being.
  +                    // TODO: Make output formatting more flexible --
  +                    // what's below was to remove the use of ECS.
                       String trace = StringUtils.stackTrace(t);
                       data.setStackTrace(trace,t);
                       data.getResponse().setContentType(data.getContentType());
  @@ -701,9 +705,9 @@
           // Create the logging directory
           File logDir = new File(getRealPath("/logs"));
           
  -        if (logDir.exists() == false)
  +        if (!logDir.exists())
           {
  -            if(logDir.mkdirs() == false)
  +            if (!logDir.mkdirs())
               {
                   System.err.println("Cannot create directory for logs!");
               }
  
  
  
  1.1                  jakarta-turbine-3/src/java/org/apache/turbine/Valve.java
  
  Index: Valve.java
  ===================================================================
  package org.apache.turbine;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * 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/>.
   */
  
  import java.io.IOException;
  
  /**
   * <p>A <b>Valve</b> is a request processing component.  A series of
   * Valves are generally associated with each other into a Pipeline.
   * The detailed contract for a Valve is included in the description of
   * the <code>invoke()</code> method below.</p>
   *
   * <b>HISTORICAL NOTE</b>:  The "Valve" name was assigned to this concept
   * because a valve is what you use in a real world pipeline to control and/or
   * modify flows through it.
   *
   * @author Craig R. McClanahan
   * @author Gunnar Rjnning
   * @author Peter Donald
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   *
   * @see #invoke(RunData, ValveContext)
   */
  public interface Valve
  {
      /**
       * <p>Perform request processing as required by this Valve.</p>
       *
       * <p>An individual Valve <b>MAY</b> perform the following actions, in
       * the specified order:</p>
       * <ul>
       * <li>Examine and/or modify the properties of the specified Request and
       *     Response.
       * <li>Examine the properties of the specified Request, completely generate
       *     the corresponding Response, and return control to the caller.
       * <li>Examine the properties of the specified Request and Response, wrap
       *     either or both of these objects to supplement their functionality,
       *     and pass them on.
       * <li>If the corresponding Response was not generated (and control was not
       *     returned, call the next Valve in the pipeline (if there is one) by
       *     executing <code>context.invokeNext()</code>.
       * <li>Examine, but not modify, the properties of the resulting Response
       *     (which was created by a subsequently invoked Valve via a
       *     call to <code>context.invokeNext()</code>).
       * </ul>
       *
       * <p>A Valve <b>MUST NOT</b> do any of the following things:</p>
       * <ul>
       * <li>Change request properties that have already been used to direct
       *     the flow of processing control for this request.
       * <li>Create a completed Response <strong>AND</strong> pass this
       *     Request and Response on to the next Valve in the pipeline.
       * <li>Consume bytes from the input stream associated with the Request,
       *     unless it is completely generating the response, or wrapping the
       *     request before passing it on.
       * <li>Modify the HTTP headers included with the Response after the
       *     <code>invokeNext()</code> method has returned.
       * <li>Perform any actions on the output stream associated with the
       *     specified Response after the <code>invokeNext()</code> method has
       *     returned.
       * </ul>
       *
       * @param data The run-time information, including the servlet
       * request and response we are processing.
       * @param context The valve context used to invoke the next valve
       *  in the current processing pipeline
       *
       * @exception IOException Thrown by a subsequent Valve.
       * @exception TurbineException Thrown by a subsequent Valve.
       */
      public void invoke(RunData data, ValveContext context)
          throws IOException, TurbineException;
  }
  
  
  
  1.1                  jakarta-turbine-3/src/java/org/apache/turbine/ValveContext.java
  
  Index: ValveContext.java
  ===================================================================
  package org.apache.turbine;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * 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/>.
   */
  
  import java.io.IOException;
  
  /**
   * <p>A <b>ValveContext</b> is the mechanism by which a Valve can trigger the
   * execution of the next Valve in a Pipeline, without having to know anything
   * about the internal implementation mechanisms.  An instance of a class
   * implementing this interface is passed as a parameter to the
   * <code>Valve.invoke()</code> method of each executed Valve.</p>
   *
   * <p><strong>IMPLEMENTATION NOTE</strong>: It is up to the implementation of
   * ValveContext to ensure that simultaneous requests being processed (by
   * separate threads) through the same Pipeline do not interfere with each
   * other's flow of control.</p>
   *
   * @author Craig R. McClanahan
   * @author Gunnar Rjnning
   * @author Peter Donald
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @version $Revision: 1.1 $ $Date: 2001/12/29 22:32:48 $
   */
  public interface ValveContext
  {
      /**
       * <p>Cause the <code>invoke()</code> method of the next Valve
       * that is part of the Pipeline currently being processed (if any)
       * to be executed, passing on the specified request and response
       * objects plus this <code>ValveContext</code> instance.
       * Exceptions thrown by a subsequently executed Valve will be
       * passed on to our caller.</p>
       *
       * <p>If there are no more Valves to be executed, an appropriate
       * ServletException will be thrown by this ValveContext.</p>
       *
       * @param data The run-time information, including the servlet
       * request and response we are processing.
       *
       * @exception IOException Thrown by a subsequent Valve.
       * @exception TurbineException Thrown by a subsequent Valve.
       * @exception TurbineException No further Valves configured in the
       * Pipeline currently being processed.
       */
      public void invokeNext(RunData data)
          throws IOException, TurbineException;
  }
  
  
  
  1.12      +13 -263   jakarta-turbine-3/src/java/org/apache/turbine/pipeline/ClassicPipeline.java
  
  Index: ClassicPipeline.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-3/src/java/org/apache/turbine/pipeline/ClassicPipeline.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -u -r1.11 -r1.12
  --- ClassicPipeline.java	29 Dec 2001 01:19:57 -0000	1.11
  +++ ClassicPipeline.java	29 Dec 2001 22:32:48 -0000	1.12
  @@ -54,282 +54,32 @@
    * <http://www.apache.org/>.
    */
   
  +import java.io.IOException;
   import java.util.Enumeration;
  -import org.apache.turbine.Turbine;
  -import org.apache.turbine.TurbineConstants; // for convenience right now
  -import org.apache.turbine.Pipeline;
  -import org.apache.turbine.RunData;
  -import org.apache.turbine.Resolver;
  -import org.apache.turbine.TemplateContext;
  -import org.apache.turbine.modules.Module;
  -import org.apache.turbine.modules.ModuleLoader;
  -import org.apache.turbine.Log;
  -import org.apache.turbine.DynamicURI;
  -import org.apache.turbine.modules.actions.SessionValidator;
  -import org.apache.turbine.modules.actions.AccessController;
  -import org.apache.fulcrum.security.util.AccessControlList;
  +
  +import org.apache.turbine.Valve;
   
   /**
  - * This is a pipeline that emulates the standard Turbine
  - * 2.1 page/layout/navigation/screen pipeline.
  + * This is a pipeline that emulates the standard Turbine 2.1
  + * page/layout/navigation/screen pipeline.
    *
  - * The ClassicPipeline uses the 'template' as a
  - * starting point for output.
  + * The ClassicPipeline uses the 'template' (as described by RunData's
  + * target attribute) as a starting point for output.
    *
    * @author <a href="mailto:mikeh@apache.org">Mike Haberman</a>
    * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
  - * @version $Id: ClassicPipeline.java,v 1.11 2001/12/29 01:19:57 dlr Exp $
  + * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
  + * @version $Id: ClassicPipeline.java,v 1.12 2001/12/29 22:32:48 dlr Exp $
    */
   public class ClassicPipeline
  -    implements Pipeline,TurbineConstants
  +    extends BasePipeline
   {
  -    protected ModuleRunner runner = null;
  -    protected SessionValidator sessionValidator = null;
  -    protected AccessController accessController = null;
  -    protected String targetModuleType;
  -    protected int timeout = -1;
  -
  -    /**
  -     * Here we can setup objects that are thread safe and be
  -     * reused. We setup the session validator and the access
  -     * controller.
  -     */
       public void init()
           throws Exception
       {
  -        // instantiate the ModuleRunner
  -        runner = new ModuleRunner();
  -        
  -        // Get the instance of the Session Validator.
  -        sessionValidator = (SessionValidator)
  -            Turbine.getResolver().getModule(ACTIONS,
  -                Turbine.getConfiguration().getString(
  -                    ACTION_SESSION_VALIDATOR));
  -
  -        // Get the instance of the AccessController.
  -        accessController = (AccessController)
  -            Turbine.getResolver().getModule(ACTIONS,
  -                Turbine.getConfiguration().getString(
  -                    ACTION_ACCESS_CONTROLLER));
  -
  -        // get the module type
  -        targetModuleType = 
  -            Turbine.getConfiguration().getString(
  -               "pipeline.default.targetModuleType");
  -               
  -        // get the session timeout
  -        timeout = Turbine.getConfiguration().getInt(SESSION_TIMEOUT, -1);
  -    }
  -
  -    /**
  -     * Handles user sessions, parsing of the action from the query
  -     * string, and access control.
  -     *
  -     * @param data The run-time data.
  -     */
  -    public void process(RunData data)
  -        throws Exception
  -    {
  -        Log.debug("[ClassicPipeline] process()");
  -
  -        if (data.getSession().isNew())
  -        {
  -            // as the session is new take this opportunity to
  -            // set the session timeout if specified in TR.properties
  -            if (timeout != -1)
  -            {
  -                data.getSession().setMaxInactiveInterval(timeout);
  -            }
  -        }
  -
  -        // Fill in the screen and action variables.
  -        data.setAction(data.getParameters().getString(ACTION));
  -
  -        // Special case for login and logout, this must happen before the
  -        // session validator is executed in order either to allow a user to
  -        // even login, or to ensure that the session validator gets to
  -        // mandate its page selection policy for non-logged in users
  -        // after the logout has taken place.
  -        if (data.hasAction()
  -             &&
  -             data.getAction().equalsIgnoreCase(
  -                Turbine.getConfiguration().getString(ACTION_LOGIN))
  -             ||
  -             data.getAction().equalsIgnoreCase(
  -                Turbine.getConfiguration().getString(ACTION_LOGOUT)))
  -        {
  -            // If a User is logging in, we should refresh the
  -            // session here.  Invalidating session and starting a
  -            // new session would seem to be a good method, but I
  -            // (JDM) could not get this to work well (it always
  -            // required the user to login twice).  Maybe related
  -            // to JServ?  If we do not clear out the session, it
  -            // is possible a new User may accidently (if they
  -            // login incorrectly) continue on with information
  -            // associated with the previous User.  Currently the
  -            // only keys stored in the session are "turbine.user"
  -            // and "turbine.acl".
  -            if (data.getAction().equalsIgnoreCase(
  -                Turbine.getConfiguration().getString(ACTION_LOGIN)))
  -            {
  -                String[] names = data.getSession().getValueNames();
  -                if (names != null)
  -                {
  -                    for (int i = 0; i < names.length; i++)
  -                    {
  -                        data.getSession().removeValue(names[i]);
  -                    }
  -                }
  -            }
  -
  -            Module action;
  -            action = Turbine.getResolver().getModule(ACTIONS, 
  -                                                     data.getAction());
  -            action.execute(data);
  -            data.setAction(null);
  -        }
  -
  -        // This is where the validation of the Session information
  -        // is performed if the user has not logged in yet, then
  -        // the screen is set to be Login. This also handles the
  -        // case of not having a screen defined by also setting the
  -        // screen to Login. If you want people to go to another
  -        // screen other than Login, you need to change that within
  -        // TurbineResources.properties...screen.homepage; or, you
  -        // can specify your own SessionValidator action.
  -        sessionValidator.execute(data);
  -
  -        // Put the Access Control List into the RunData object, so
  -        // it is easily available to modules.  It is also placed
  -        // into the session for serialization.  Modules can null
  -        // out the ACL to force it to be rebuilt based on more
  -        // information.
  -        accessController.execute(data);
  -    }
  -
  -    /**
  -     * Adds a reference the request's context to the run-time data's
  -     * temporary--per-request--storage so that all subsequent stages
  -     * of the request have access to the template context.  Called
  -     * before the action is executed.
  -     *
  -     * @param data The run-time data.
  -     */
  -    public void preExecuteAction(RunData data)
  -        throws Exception
  -    {
  -        // Puts a copy of the Context into the data.setTemp()
  -        Module.getTemplateContext(data);
  -    }
  -
  -    /**
  -     * Executes the action parsed from the query string.
  -     *
  -     * @param data The run-time data.
  -     */
  -    public void executeAction(RunData data)
  -        throws Exception
  -    {
  -        // If an action has been defined, execute it here.  Actions
  -        // can re-define the template definition.
  -        if (data.hasAction())
  -        {
  -            Turbine.getResolver().getModule(
  -                Turbine.ACTIONS, data.getAction()).execute(data);
  -        }
  -    }
  -
  -    /**
  -     * No op.  Called after the action is executed.
  -     *
  -     * @param data The run-time data.
  -     */
  -    public void postExecuteAction(RunData data)
  -        throws Exception
  -    {
  -    }
  -
  -    /**
  -     * Executes the <code>Pipeline</code>.
  -     *
  -     * @param data The run-time data.
  -     */
  -    public void execute(RunData data)
  -        throws Exception
  -    {
  -        data.getResponse().setLocale(data.getLocale());
  -        data.getResponse().setContentType(data.getContentType());
  -
  -        // run the module chain
  -        // Need to execute the module that matches the template
  -        // if it exists.
  -        // As long as data.getTarget() changes during execution,
  -        // the new target is run , and so on
  -
  -        runner.run(targetModuleType, data);
  -
  -        // The execution of the module that corresponds to the requested
  -        // template may result in the target template being changed.
  -        // This happens for example when a user isn't logged in. The
  -        // template requested is '/Index.vm', but executing an Index
  -        // module might result in the target template being changed
  -        // to '/Login.vm'. We want to reset the target template value
  -        // here in case it has changed.
  -        String target = data.getTarget();
  -
  -        // With this target template we start by rendering
  -        // the appropriate layout template and everything
  -        // goes from there.
  -
  -        // Now I think we have to find a page template based
  -        // on the content type. What other criterion could
  -        // we use. Maybe you might want to change it if
  -        // you were branding ...
  -        Renderer r = new Renderer();
  -        TemplateContext context = Module.getTemplateContext(data);
  -        // FIXME: Remove hard coding!
  -        context.put("renderer", r);
  -        context.put("template", target);
  -        context.put("runner", runner);
  -
  -        // now we can use the renderer here
  -        // use the renderer to start the whole shabang
  -        String layoutTemplate = Turbine.getResolver()
  -            .getTemplate("layouts", target);
  -        String out = r.render(data, layoutTemplate);
  -        data.getOut().print(out);
  -
  -        // Note that the target is not yet rendered in the classic
  -        // Turbine 2.x -- $screen_placeholder held the result of
  -        // r.render(data, data.getTarget()).
  -    }
  -
  -    /**
  -     * Perform clean up.
  -     *
  -     * @param data The run-time data.
  -     */
  -    public void finished(RunData data)
  -        throws Exception
  -    {
  -        TemplateContext context = Module.getTemplateContext(data);
  -        Module.requestFinished(context);
  -
  -        // If a module has set data.acl = null, remove acl from
  -        // the session.
  -        if (data.getACL() == null)
  -        {
  -            try
  -            {
  -                data.getSession().removeValue(
  -                    AccessControlList.SESSION_KEY);
  -            }
  -            catch (IllegalStateException invalidatedSession)
  -            {
  -                // Web was used to shut us down. Trying to clean up
  -                // our stuff, but it's already been done for us.
  -            }
  -        }
  +        // Add the classic Valve(s) to our pipeline
  +        super.valves = new Valve[]
  +            { new DefaultActionValve(), new DefaultTargetValve() };
       }
   }
  
  
  
  1.3       +64 -49    jakarta-turbine-3/src/java/org/apache/turbine/pipeline/DirectClassicPipeline.java
  
  Index: DirectClassicPipeline.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-3/src/java/org/apache/turbine/pipeline/DirectClassicPipeline.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -u -r1.2 -r1.3
  --- DirectClassicPipeline.java	4 Dec 2001 19:23:02 -0000	1.2
  +++ DirectClassicPipeline.java	29 Dec 2001 22:32:48 -0000	1.3
  @@ -54,76 +54,91 @@
    * <http://www.apache.org/>.
    */
   
  +import org.apache.turbine.Log;
  +import org.apache.turbine.RunData;
   import org.apache.turbine.Turbine;
   import org.apache.turbine.TemplateContext;
  -import org.apache.turbine.RunData;
   import org.apache.turbine.modules.Module;
  -import org.apache.turbine.Log;
   
   /**
    * This pipeline overrides the <code>execute()</code> method of
  - * ClassicPipeline, so that the response is written as the template is
  + * DefaultTargetValve, so that the response is written as the template is
    * rendered.  In the ClassicPipeline the results of template rendering
    * are buffered (built up as a <code>String</code>) and output after
    * all rendering is completed.
    *
    * @author <a href="mailto:jmcnally@apache.org">John McNally</a>
  - * @version $Id: DirectClassicPipeline.java,v 1.2 2001/12/04 19:23:02 dlr Exp $
  + * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
  + * @version $Id: DirectClassicPipeline.java,v 1.3 2001/12/29 22:32:48 dlr Exp $
    * @see org.apache.turbine.pipeline.ClassicPipeline
    */
   public class DirectClassicPipeline extends ClassicPipeline
   {
       /**
  -     * Renders and writes result to the output stream in an unbuffered
  -     * fashion.
  -     *
  -     * @see org.apache.turbine.pipeline.ClassicPipeline#execute(RunData)
  +     * Supplies our version of the <code>DefaultTargetValve</code>.
        */
  -    public void execute(RunData data)
  +    public void init()
           throws Exception
       {
  -        data.getResponse().setLocale(data.getLocale());
  -        data.getResponse().setContentType(data.getContentType());
  +        super.init();
  +        super.valves[1] = new DirectTargetValve();
  +    }
   
  -        // run the module chain
  -        // Need to execute the module that matches the template
  -        // if it exists.
  -        // As long as data.getTarget() changes during execution,
  -        // the new target is run , and so on
  -
  -        runner.run(targetModuleType, data);
  -
  -        // The execution of the module that corresponds to the requested
  -        // template may result in the target template being changed.
  -        // This happens for example when a user isn't logged in. The
  -        // template requested is '/Index.vm', but executing an Index
  -        // module might result in the target template being changed
  -        // to '/Login.vm'. We want to reset the target template value
  -        // here in case it has changed.
  -        String target = data.getTarget();
  -
  -        // With this target template we start by rendering
  -        // the appropriate layout template and everything
  -        // goes from there.
  -
  -        // Now I think we have to find a page template based
  -        // on the content type. What other criterion could
  -        // we use. Maybe you might want to change it if
  -        // you were branding ...
  -        Renderer r = new DirectRenderer(data.getOut());
  -        TemplateContext context = Module.getTemplateContext(data);
  -        context.put("renderer", r);
  -        context.put("template", target);
  -        context.put("runner", runner);
  -
  -        // now we can use the renderer here
  -        // use the renderer to start the whole shabang
  -        String layoutTemplate = Turbine.getResolver()
  -            .getTemplate("layouts", target);
  -        String out = r.render(data, layoutTemplate);
  -        if ( out != null && out.length() > 0 ) 
  +    protected class DirectTargetValve extends DefaultTargetValve
  +    {
  +        /**
  +         * Renders and writes result to the output stream in an
  +         * unbuffered fashion.
  +         *
  +         * @see org.apache.turbine.pipeline.DefaultTargetValve#execute(RunData)
  +         */
  +        protected void execute(RunData data)
  +            throws Exception
           {
  -            data.getOut().print(out);            
  +            data.getResponse().setLocale(data.getLocale());
  +            data.getResponse().setContentType(data.getContentType());
  +
  +            // run the module chain
  +            // Need to execute the module that matches the template
  +            // if it exists.
  +            // As long as data.getTarget() changes during execution,
  +            // the new target is run , and so on
  +
  +            runner.run(targetModuleType, data);
  +
  +            // The execution of the module that corresponds to the requested
  +            // template may result in the target template being changed.
  +            // This happens for example when a user isn't logged in. The
  +            // template requested is '/Index.vm', but executing an Index
  +            // module might result in the target template being changed
  +            // to '/Login.vm'. We want to reset the target template value
  +            // here in case it has changed.
  +            String target = data.getTarget();
  +
  +            // With this target template we start by rendering
  +            // the appropriate layout template and everything
  +            // goes from there.
  +
  +            // Now I think we have to find a page template based
  +            // on the content type. What other criterion could
  +            // we use. Maybe you might want to change it if
  +            // you were branding ...
  +            Renderer r = new DirectRenderer(data.getOut());
  +            TemplateContext context = Module.getTemplateContext(data);
  +            context.put("renderer", r);
  +            context.put("template", target);
  +            context.put("runner", runner);
  +
  +            // now we can use the renderer here
  +            // use the renderer to start the whole shabang
  +            String layoutTemplate = Turbine.getResolver()
  +                .getTemplate("layouts", target);
  +            String out = r.render(data, layoutTemplate);
  +            if (out != null && out.length() > 0)
  +            {
  +                // Write the response directly to the output stream.
  +                data.getOut().print(out);            
  +            }
           }
       }
   }
  
  
  
  1.1                  jakarta-turbine-3/src/java/org/apache/turbine/pipeline/BasePipeline.java
  
  Index: BasePipeline.java
  ===================================================================
  package org.apache.turbine.pipeline;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * 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/>.
   */
  
  //import org.apache.log4j.Category;
  
  import java.io.IOException;
  
  import org.apache.turbine.Pipeline;
  import org.apache.turbine.RunData;
  import org.apache.turbine.TurbineException;
  import org.apache.turbine.Valve;
  import org.apache.turbine.ValveContext;
  
  /**
   * Base implementation of a {@link org.apache.turbine.Pipeline}.
   * Originally based on code from Catalina and ideas from Apache httpd.
   *
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   */
  public abstract class BasePipeline
      implements Pipeline, ValveContext
  {
      /**
       * The set of Valves associated with this Pipeline.
       */
      protected Valve[] valves = new Valve[0];
  
      /**
       * The per-thread execution state for processing through this
       * pipeline.  The actual value is a java.lang.Integer object
       * containing the subscript into the <code>values</code> array, or
       * a subscript equal to <code>values.length</code> if the basic
       * Valve is currently being processed.
       */
      protected ThreadLocal state = new ThreadLocal();
  
      /**
       * @see org.apache.turbine.Pipeline#addValve(Valve)
       */
      public void addValve(Valve valve)
      {
          // Add this Valve to the set associated with this Pipeline
          synchronized (valves)
          {
              Valve[] results = new Valve[valves.length + 1];
              System.arraycopy(valves, 0, results, 0, valves.length);
              results[valves.length] = valve;
              valves = results;
          }
      }
  
      /**
       * @see org.apache.turbine.Pipeline#getValves()
       */
      public Valve[] getValves()
      {
          synchronized (valves)
          {
              Valve[] results = new Valve[valves.length];
              System.arraycopy(valves, 0, results, 0, valves.length);
              return results;
          }
      }
  
      /**
       * @see org.apache.turbine.Pipeline#removeValve(Valve)
       */
      public void removeValve(Valve valve)
      {
          synchronized (valves)
          {
              // Locate this Valve in our list
              int index = -1;
              for (int i = 0; i < valves.length; i++)
              {
                  if (valve == valves[i])
                  {
                      index = i;
                      break;
                  }
              }
              if (index < 0)
              {
                  return;
              }
  
              // Remove this valve from our list
              Valve[] results = new Valve[valves.length - 1];
              int n = 0;
              for (int i = 0; i < valves.length; i++)
              {
                  if (i == index)
                  {
                      continue;
                  }
                  results[n++] = valves[i];
              }
              valves = results;
          }
      }
  
      /**
       * @see org.apache.turbine.Pipeline#invoke(RunData)
       */
      public void invoke(RunData data)
          throws TurbineException, IOException
      {
          // Initialize the per-thread state for this thread
          state.set(new Integer(0));
  
          // Invoke the first Valve in this pipeline for this request
          invokeNext(data);
      }
  
      /**
       * @see org.apache.turbine.ValveContext#invokeNext(RunData)
       */
      public void invokeNext(RunData data)
          throws TurbineException, IOException
      {
          // Identify the current subscript for the current request thread
          Integer current = (Integer) state.get();
          int subscript = current.intValue();
          state.set(new Integer(subscript + 1));
  
          // Invoke the requested Valve for the current request thread
          if (subscript < valves.length)
          {
              valves[subscript].invoke(data, this);
          }
          else
          {
              throw new TurbineException("No more Valves on this Pipeline");
          }
      }
  }
  
  
  
  1.1                  jakarta-turbine-3/src/java/org/apache/turbine/pipeline/DefaultActionValve.java
  
  Index: DefaultActionValve.java
  ===================================================================
  package org.apache.turbine.pipeline;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * 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/>.
   */
  
  import java.io.IOException;
  import java.util.Enumeration;
  import org.apache.turbine.Log;
  import org.apache.turbine.DynamicURI;
  import org.apache.turbine.Turbine;
  import org.apache.turbine.TurbineConstants;
  import org.apache.turbine.RunData;
  import org.apache.turbine.Resolver;
  import org.apache.turbine.TemplateContext;
  import org.apache.turbine.TurbineException;
  import org.apache.turbine.Valve;
  import org.apache.turbine.ValveContext;
  import org.apache.turbine.modules.Module;
  import org.apache.turbine.modules.ModuleLoader;
  import org.apache.turbine.modules.actions.AccessController;
  import org.apache.turbine.modules.actions.SessionValidator;
  
  /**
   * Implements the action portion of the "Turbine classic" processing
   * pipeline (from the Turbine 2.x series).
   *
   * @author <a href="mailto:mikeh@apache.org">Mike Haberman</a>
   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @version $Id: DefaultActionValve.java,v 1.1 2001/12/29 22:32:48 dlr Exp $
   */
  public class DefaultActionValve
      implements Valve, TurbineConstants
  {
      protected SessionValidator sessionValidator = null;
      protected AccessController accessController = null;
      protected int timeout = -1;
  
      /**
       * Here we can setup objects that are thread safe and can be
       * reused. We setup the session validator and the access
       * controller.
       */
      public DefaultActionValve()
          throws Exception
      {
          // Get the instance of the Session Validator.
          sessionValidator = (SessionValidator)
              Turbine.getResolver().getModule(ACTIONS,
                  Turbine.getConfiguration().getString(
                      ACTION_SESSION_VALIDATOR));
  
          // Get the instance of the AccessController.
          accessController = (AccessController)
              Turbine.getResolver().getModule(ACTIONS,
                  Turbine.getConfiguration().getString(
                      ACTION_ACCESS_CONTROLLER));
  
          // get the session timeout
          timeout = Turbine.getConfiguration().getInt(SESSION_TIMEOUT, -1);
      }
  
      /**
       * @see org.apache.turbine.Valve#invoke(RunData, ValveContext)
       */
      public void invoke(RunData data, ValveContext context)
          throws IOException, TurbineException
      {
          try
          { 
              process(data);
              preExecuteAction(data);
              executeAction(data);
              postExecuteAction(data);
          }
          catch (Exception e)
          {
              throw new TurbineException(e);
          }
  
          // Pass control to the next Valve in the Pipeline
          context.invokeNext(data);
      }
  
      /**
       * Handles user sessions, parsing of the action from the query
       * string, and access control.
       *
       * @param data The run-time data.
       */
      protected void process(RunData data)
          throws Exception
      {
          Log.debug("[ClassicValve] process()");
  
          if (data.getSession().isNew())
          {
              // as the session is new take this opportunity to
              // set the session timeout if specified in TR.properties
              if (timeout != -1)
              {
                  data.getSession().setMaxInactiveInterval(timeout);
              }
          }
  
          // Fill in the screen and action variables.
          data.setAction(data.getParameters()
                         .getString(ACTION));
  
          // Special case for login and logout, this must happen before the
          // session validator is executed in order either to allow a user to
          // even login, or to ensure that the session validator gets to
          // mandate its page selection policy for non-logged in users
          // after the logout has taken place.
          if (data.hasAction() &&
              data.getAction().equalsIgnoreCase
              (Turbine.getConfiguration().getString(ACTION_LOGIN)) ||
              data.getAction().equalsIgnoreCase
              (Turbine.getConfiguration().getString(ACTION_LOGOUT)))
          {
              // If a User is logging in, we should refresh the
              // session here.  Invalidating session and starting a
              // new session would seem to be a good method, but I
              // (JDM) could not get this to work well (it always
              // required the user to login twice).  Maybe related
              // to JServ?  If we do not clear out the session, it
              // is possible a new User may accidently (if they
              // login incorrectly) continue on with information
              // associated with the previous User.  Currently the
              // only keys stored in the session are "turbine.user"
              // and "turbine.acl".
              if (data.getAction().equalsIgnoreCase
                  (Turbine.getConfiguration().getString(ACTION_LOGIN)))
              {
                  String[] names = data.getSession().getValueNames();
                  if (names != null)
                  {
                      for (int i = 0; i < names.length; i++)
                      {
                          data.getSession().removeValue(names[i]);
                      }
                  }
              }
  
              Module action;
              action = Turbine.getResolver().getModule(ACTIONS, 
                                                       data.getAction());
              action.execute(data);
              data.setAction(null);
          }
  
          // This is where the validation of the Session information
          // is performed if the user has not logged in yet, then
          // the screen is set to be Login. This also handles the
          // case of not having a screen defined by also setting the
          // screen to Login. If you want people to go to another
          // screen other than Login, you need to change that within
          // TurbineResources.properties...screen.homepage; or, you
          // can specify your own SessionValidator action.
          sessionValidator.execute(data);
  
          // Put the Access Control List into the RunData object, so
          // it is easily available to modules.  It is also placed
          // into the session for serialization.  Modules can null
          // out the ACL to force it to be rebuilt based on more
          // information.
          accessController.execute(data);
      }
  
      /**
       * Adds a reference the request's context to the run-time data's
       * temporary--per-request--storage so that all subsequent stages
       * of the request have access to the template context.  Called
       * before the action is executed.
       *
       * @param data The run-time data.
       */
      protected void preExecuteAction(RunData data)
          throws Exception
      {
          // Puts a copy of the Context into the data.setTemp()
          Module.getTemplateContext(data);
      }
  
      /**
       * Executes the action parsed from the query string.
       *
       * @param data The run-time data.
       */
      protected void executeAction(RunData data)
          throws Exception
      {
          // If an action has been defined, execute it here.  Actions
          // can re-define the template definition.
          if (data.hasAction())
          {
              Turbine.getResolver().getModule
                  (Turbine.ACTIONS, data.getAction()).execute(data);
          }
      }
  
      /**
       * No op.  Called after the action is executed.
       *
       * @param data The run-time data.
       */
      protected void postExecuteAction(RunData data)
          throws Exception
      {
      }
  }
  
  
  
  1.1                  jakarta-turbine-3/src/java/org/apache/turbine/pipeline/DefaultTargetValve.java
  
  Index: DefaultTargetValve.java
  ===================================================================
  package org.apache.turbine.pipeline;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * 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/>.
   */
  
  import java.io.IOException;
  import java.util.Enumeration;
  import org.apache.fulcrum.security.util.AccessControlList;
  import org.apache.turbine.Log;
  import org.apache.turbine.DynamicURI;
  import org.apache.turbine.Turbine;
  import org.apache.turbine.TurbineConstants;
  import org.apache.turbine.RunData;
  import org.apache.turbine.Resolver;
  import org.apache.turbine.TemplateContext;
  import org.apache.turbine.TurbineException;
  import org.apache.turbine.Valve;
  import org.apache.turbine.ValveContext;
  import org.apache.turbine.modules.Module;
  import org.apache.turbine.modules.ModuleLoader;
  import org.apache.turbine.modules.actions.AccessController;
  
  /**
   * Implements the RunData target portion of the "Turbine classic"
   * processing pipeline (from the Turbine 2.x series).
   *
   * @author <a href="mailto:mikeh@apache.org">Mike Haberman</a>
   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @version $Id: DefaultTargetValve.java,v 1.1 2001/12/29 22:32:48 dlr Exp $
   */
  public class DefaultTargetValve
      implements Valve
  {
      protected ModuleRunner runner = null;
      protected String targetModuleType;
  
      /**
       * Creates a new instance with the <code>targetModuleType</code>
       * and <code>runner</code> members filled in from Turbine's
       * configuration.
       */
      public DefaultTargetValve()
      {
          // Instantiate the ModuleRunner
          runner = new ModuleRunner();
  
          // Get the module type
          targetModuleType = 
              Turbine.getConfiguration().getString(
                 "pipeline.default.targetModuleType");
      }
  
      /**
       * @see org.apache.turbine.Valve#invoke(RunData, ValveContext)
       */
      public void invoke(RunData data, ValveContext context)
          throws IOException, TurbineException
      {
          try
          { 
              execute(data);
              finished(data);
          }
          catch (Exception e)
          {
              throw new TurbineException(e);
          }
  
          // Pass control to the next Valve in the Pipeline
          context.invokeNext(data);
      }
  
      /**
       * Executes the <code>Valve</code>.
       *
       * @param data The run-time data.
       */
      protected void execute(RunData data)
          throws Exception
      {
          data.getResponse().setLocale(data.getLocale());
          data.getResponse().setContentType(data.getContentType());
  
          // run the module chain
          // Need to execute the module that matches the template
          // if it exists.
          // As long as data.getTarget() changes during execution,
          // the new target is run , and so on
  
          runner.run(targetModuleType, data);
  
          // The execution of the module that corresponds to the requested
          // template may result in the target template being changed.
          // This happens for example when a user isn't logged in. The
          // template requested is '/Index.vm', but executing an Index
          // module might result in the target template being changed
          // to '/Login.vm'. We want to reset the target template value
          // here in case it has changed.
          String target = data.getTarget();
  
          // With this target template we start by rendering
          // the appropriate layout template and everything
          // goes from there.
  
          // Now I think we have to find a page template based
          // on the content type. What other criterion could
          // we use. Maybe you might want to change it if
          // you were branding ...
          Renderer r = new Renderer();
          TemplateContext context = Module.getTemplateContext(data);
          // FIXME: Remove hard coding!
          context.put("renderer", r);
          context.put("template", target);
          context.put("runner", runner);
  
          // now we can use the renderer here
          // use the renderer to start the whole shabang
          String layoutTemplate = Turbine.getResolver()
              .getTemplate("layouts", target);
          String out = r.render(data, layoutTemplate);
          data.getOut().print(out);
  
          // Note that the target is not yet rendered in the classic
          // Turbine 2.x -- $screen_placeholder held the result of
          // r.render(data, data.getTarget()).
      }
  
      /**
       * Perform clean up.
       *
       * @param data The run-time data.
       */
      protected void finished(RunData data)
          throws Exception
      {
          TemplateContext context = Module.getTemplateContext(data);
          Module.requestFinished(context);
  
          // If a module has set data.acl = null, remove acl from
          // the session.
          if (data.getACL() == null)
          {
              try
              {
                  data.getSession().removeValue
                      (AccessControlList.SESSION_KEY);
              }
              catch (IllegalStateException invalidatedSession)
              {
                  // Web was used to shut us down. Trying to clean up
                  // our stuff, but it's already been done for us.
              }
          }
      }
  }
  
  
  

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