Author: rich
Date: Wed Jul 21 14:18:00 2004
New Revision: 23124

Modified:
   
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java
   
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowJspFilter.java
Log:
Fixed a nasty assert in PageFlowJspFilter, which occurred when a JSP in a page 
flow directory forwarded to another page flow or JSP.

DRT: netui



Modified: 
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java
    (original)
+++ 
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java
    Wed Jul 21 14:18:00 2004
@@ -84,23 +84,39 @@
     private static final String DEFAULT_SIMPLE_ACTION_FORWARD_NAME = 
"_defaultForward";
     
     
-    /**
-     * This member variable stores a reference to the current ServletRequest, 
which is <i>only valid
-     * during a call to [EMAIL PROTECTED] #execute} or [EMAIL PROTECTED] 
#handleException}</i>.
-     */ 
-    private transient HttpServletRequest _request = null;
+    static class PerRequestState
+    {
+        private HttpServletRequest _request;
+        private HttpServletResponse _response;
+        private ActionMapping _actionMapping;
+
+        public PerRequestState( HttpServletRequest request, 
HttpServletResponse response, ActionMapping actionMapping )
+        {
+            _request = request;
+            _response = response;
+            _actionMapping = actionMapping;
+        }
+
+        public HttpServletRequest getRequest()
+        {
+            return _request;
+        }
+
+        public HttpServletResponse getResponse()
+        {
+            return _response;
+        }
+
+        public ActionMapping getActionMapping()
+        {
+            return _actionMapping;
+        }
+    }
 
     /**
-     * This member variable stores a reference to the current ServletResponse, 
which is <i>only valid
-     * during a call to [EMAIL PROTECTED] #execute} or [EMAIL PROTECTED] 
#handleException}</i>.
+     * Stores per-request state, which is <i>only valid during calls to [EMAIL 
PROTECTED] #execute} or [EMAIL PROTECTED] #handleException}</i>.
      */ 
-    private transient HttpServletResponse _response = null;
-    
-    /**
-     * This member variable stores a reference to the current ActionMapping, 
which is <i>only valid
-     * during a call to [EMAIL PROTECTED] #execute} or [EMAIL PROTECTED] 
#handleException}</i>.
-     */     
-    private transient ActionMapping _mapping = null;
+    private transient PerRequestState _perRequestState;
 
     /**
      * We prevent the base class from storing a reference to ActionServlet in 
the non-transient
@@ -215,7 +231,7 @@
                                                           HttpServletResponse 
response )
         throws Exception
     {
-        setRequestMembers( request, response, mapping );
+        PerRequestState prevState = setPerRequestState( new PerRequestState( 
request, response, mapping ) );
         
         try
         {
@@ -228,7 +244,7 @@
         }
         finally
         {
-            nullRequestMembers( request );
+            setPerRequestState( prevState );
         }
     }
     
@@ -313,11 +329,10 @@
         String actionName = PageFlowUtils.getActionName( mapping );
         boolean gotPastBeforeAction = false;
         ServletContext servletContext = getServlet().getServletContext();
-        
+        PerRequestState prevState = setPerRequestState( new PerRequestState( 
request, response, mapping ) );
+
         try
         {
-            setRequestMembers( request, response, mapping );
-
             //
             // beforeAction callback
             //
@@ -462,35 +477,38 @@
         }
         finally
         {
-            nullRequestMembers( request );  
-
-            ActionForward overrideReturn = null;
-            
-            if ( gotPastBeforeAction )
+            try
             {
+                ActionForward overrideReturn = null;
+                
+                if ( gotPastBeforeAction )
+                {
+                    //
+                    // afterAction callback
+                    //
+                    try
+                    {
+                        afterAction();
+                    }
+                    catch ( Throwable th )
+                    {
+                        overrideReturn = handleException( th, mapping, 
actionName, form, request, response );
+                    }
+                }            
+                
                 //
-                // afterAction callback
+                // Store information on this action for use with 
navigateTo=Jpf.NavigateTo.previousAction.
                 //
-                try
-                {
-                    setRequestMembers( request, response, mapping );
-                    afterAction();
-                }
-                catch ( Throwable th )
+                savePreviousActionInfo( form, request, mapping, 
getServlet().getServletContext() );
+                
+                if ( overrideReturn != null )
                 {
-                    overrideReturn = handleException( th, mapping, actionName, 
form, request, response );
+                    return overrideReturn;
                 }
-            }            
-            
-            
-            //
-            // Store information on this action for use with return-to="action"
-            //
-            savePreviousActionInfo( form, request, mapping, 
getServlet().getServletContext() );
-            
-            if ( overrideReturn != null )
+            }
+            finally
             {
-                return overrideReturn;
+                setPerRequestState( prevState );
             }
         }
     }
@@ -576,7 +594,6 @@
                                     ServletContext servletContext )
     {
         setServlet( InternalUtils.getActionServlet( servletContext ) );
-        setRequestMembers( request, response, null );
         
         //
         // Cache the associated ModuleConfig.  This is used throughout the 
code, in places where the request
@@ -589,7 +606,8 @@
         //
         initJavaControls( request, response );
         
-        
+        PerRequestState prevState = setPerRequestState( new PerRequestState( 
request, response, null ) );
+
         try
         {
             try
@@ -612,7 +630,7 @@
         }
         finally
         {
-            nullRequestMembers( request );
+            setPerRequestState( prevState );
         }
     }
     
@@ -884,15 +902,12 @@
      */
     protected final HttpServletRequest getRequest()
     {
-        if ( _request == null )
+        if ( _perRequestState == null )
         {
-            String message = "getRequest was called outside of a valid 
context.";
-            LocalizedIllegalStateException ex = new 
LocalizedIllegalStateException( message );
-            ex.setLocalizedMessage( Bundle.getString( 
"PageFlow_IllegalStateGet", "getRequest" ) );
-            throw ex;
+            throw new IllegalStateException( "getRequest was called outside of 
a valid context." );
         }
 
-        return _request;
+        return _perRequestState.getRequest();
     }
 
     /**
@@ -907,15 +922,12 @@
      */
     protected final HttpServletResponse getResponse()
     {
-        if ( _response == null )
+        if ( _perRequestState == null )
         {
-            String message = "getResponse was called outside of a valid 
context.";
-            LocalizedIllegalStateException ex = new 
LocalizedIllegalStateException( message );
-            ex.setLocalizedMessage( Bundle.getString( 
"PageFlow_IllegalStateGet", "getResponse" ) );
-            throw ex;
+            throw new IllegalStateException( "getResponse was called outside 
of a valid context." );
         }
 
-        return _response;
+        return _perRequestState.getResponse();
     }
 
     /**
@@ -923,6 +935,7 @@
      * tag that corresponds to the current page flow action being executed.  
This call is only valid
      * during [EMAIL PROTECTED] #execute} (where any user action method is 
invoked), and during the lifecycle
      * methods [EMAIL PROTECTED] #beforeAction} and [EMAIL PROTECTED] 
#afterAction}.
+     * @deprecated Use [EMAIL PROTECTED] #getActionMapping} instead.
      * 
      * @return the current Struts ActionMapping.
      * @throws IllegalStateException if this method is invoked outside of 
action method
@@ -931,15 +944,28 @@
      */
     protected final ActionMapping getMapping()
     {
-        if ( _mapping == null )
+        return getActionMapping();
+    }
+
+    /**
+     * Get the current Struts ActionMapping, which is information from the 
Struts-XML &lt;action&gt;
+     * tag that corresponds to the current page flow action being executed.  
This call is only valid
+     * during [EMAIL PROTECTED] #execute} (where any user action method is 
invoked), and during the lifecycle
+     * methods [EMAIL PROTECTED] #beforeAction} and [EMAIL PROTECTED] 
#afterAction}.
+     * 
+     * @return the current Struts ActionMapping.
+     * @throws IllegalStateException if this method is invoked outside of 
action method
+     *             execution (i.e., outside of the call to [EMAIL PROTECTED] 
#execute}, and outside of
+     *             [EMAIL PROTECTED] #onCreate}, [EMAIL PROTECTED] 
#beforeAction}, [EMAIL PROTECTED] #afterAction}.
+     */
+    protected final ActionMapping getActionMapping()
+    {
+        if ( _perRequestState == null )
         {
-            String message = "getMapping was called outside of a valid 
context.";
-            LocalizedIllegalStateException ex = new 
LocalizedIllegalStateException( message );
-            ex.setLocalizedMessage( Bundle.getString( 
"PageFlow_IllegalStateGet", "getMapping" ) );
-            throw ex;
+            throw new IllegalStateException( "getActionMapping was called 
outside of a valid context." );
         }
 
-        return _mapping;
+        return _perRequestState.getActionMapping();
     }
 
     /**
@@ -954,39 +980,27 @@
      */
     protected final HttpSession getSession()
     {
-        if ( _request == null )
+        if ( _perRequestState == null )
         {
-            String message = "getSession was called outside of a valid 
context.";
-            LocalizedIllegalStateException ex = new 
LocalizedIllegalStateException( message );
-            ex.setLocalizedMessage( Bundle.getString( 
"PageFlow_IllegalStateGet", "getSession" ) );
-            throw ex;
+            throw new IllegalStateException( "getSession was called outside of 
a valid context." );
         }
 
-        return _request.getSession( true );
+        return _perRequestState.getRequest().getSession( true );
     }
 
-    void setRequestMembers( HttpServletRequest request, HttpServletResponse 
response, ActionMapping mapping )
-    {
-        assert request != null;
-        assert response != null;
-        
-        _request = request;
-        _response = response;
-        _mapping = mapping;
-    }
-    
-    void nullRequestMembers( HttpServletRequest request )
+    PerRequestState setPerRequestState( PerRequestState state )
     {
-        assert request == _request : "old request: " + _request + ", new 
request: " + request;
-        
-        if ( request == _request )
+        if ( state != null )
         {
-            _request = null;
-            _response = null;
-            _mapping = null;
+            assert state.getRequest() != null;
+            assert state.getResponse() != null;
         }
+
+        PerRequestState prevState = _perRequestState;
+        _perRequestState = state;
+        return prevState;
     }
-    
+
     /**
      * @exclude
      */ 
@@ -1005,7 +1019,7 @@
             //
             // We'll get into this next block if the requested module path 
differs in case from
             // the "natural" module path for this file (Windows only).  If so, 
we'll parse the
-            // module path from the request.  Note that the request (which 
comes from _request)
+            // module path from the request.  Note that the request (which 
comes from _perRequestState)
             // may be null for Global.app, but because we create the 
Global.app URIs ("/-global"
             // module path), we'll never have a case issue.
             //
@@ -1217,9 +1231,16 @@
      */ 
     public synchronized final void refresh( HttpServletRequest request, 
HttpServletResponse response )
     {
-        setRequestMembers( request, response, null );
-        onRefresh();
-        nullRequestMembers( request );
+        PerRequestState prevState = setPerRequestState( new PerRequestState( 
request, response, null ) );
+
+        try
+        {
+            onRefresh();
+        }
+        finally
+        {
+            setPerRequestState( prevState );
+        }
     }
     
     /**
@@ -1535,10 +1556,9 @@
             ActionMapping actionMapping, HttpServletRequest request, 
HttpServletResponse response, boolean readonly )
         throws Exception
     {
-        setRequestMembers( request, response, actionMapping );
-                        
         ActionForward result = null;
-                        
+        PerRequestState prevState = setPerRequestState( new PerRequestState( 
request, response, actionMapping ) );
+        
         try
         {
             if ( _log.isDebugEnabled() )
@@ -1588,7 +1608,7 @@
         }
         finally
         {
-            nullRequestMembers( request );
+            setPerRequestState( prevState );
         }
                         
         return result;

Modified: 
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowJspFilter.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowJspFilter.java
 (original)
+++ 
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowJspFilter.java
 Wed Jul 21 14:18:00 2004
@@ -175,34 +175,36 @@
                     _log.debug( "Continuing with filter chain..." );
                 }
                 
-                try
+                //
+                // Make sure that the pageflow's getRequest() and 
getResponse() will work while the JSP
+                // is being rendered, since methods on the pageflow may be 
called (through databinding
+                // or tags, or through direct reference).
+                //
+                if ( curJpf != null )
                 {
                     //
-                    // Make sure that the pageflow's getRequest() and 
getResponse() will work while the JSP
-                    // is being rendered, since methods on the pageflow may be 
called (through databinding
-                    // or tags, or through direct reference).
+                    // We're going to bail out if there are too many 
concurrent requests for the same JPF.
+                    // This prevents an attack that takes advantage of the 
fact that we serialize requests
+                    // to the same pageflow.
                     //
-                    if ( curJpf != null )
+                    if ( curJpf.incrementRequestCount( httpRequest, 
httpResponse, _servletContext ) )
                     {
-                        //
-                        // We're going to bail out if there are too many 
concurrent requests for the same JPF.
-                        // This prevents an attack that takes advantage of the 
fact that we serialize requests
-                        // to the same pageflow.
-                        //
-                        if ( curJpf.incrementRequestCount( httpRequest, 
httpResponse, _servletContext ) )
+                        try
                         {
-                            try
+                            //
+                            // Any databinding calls, indirect calls to 
getRequest(), etc. must be protected
+                            // against conflicts from running action methods 
at the same time as rendering 
+                            // the JSP here.  Synchronize on the JPF.
+                            //
+                            synchronized ( curJpf )
                             {
-                                //
-                                // Any databinding calls, indirect calls to 
getRequest(), etc. must be protected
-                                // against conflicts from running action 
methods at the same time as rendering 
-                                // the JSP here.  Synchronize on the JPF.
-                                //
-                                synchronized ( curJpf )
-                                {
-                                    curJpf.setServlet( 
InternalUtils.getActionServlet( _servletContext ) );
-                                    curJpf.setRequestMembers( httpRequest, 
httpResponse, null );
+                                FlowController.PerRequestState newState =
+                                        new FlowController.PerRequestState( 
httpRequest, httpResponse, null );
+                                FlowController.PerRequestState prevState = 
curJpf.setPerRequestState( newState );
+                                curJpf.setServlet( 
InternalUtils.getActionServlet( _servletContext ) );
 
+                                try
+                                {
                                     // @todo: need to wrap this in checks for 
JSP 1.2
                                     // @todo: feature: need to add support for 
chaining in user-code to
                                     //        run when setting implicit 
objects on the request
@@ -215,39 +217,29 @@
 
                                     chain.doFilter( request, response );
                                 }
-                            }
-                            finally
-                            {
-                                curJpf.decrementRequestCount( httpRequest );
+                                finally
+                                {
+                                    curJpf.setPerRequestState( prevState );
+                                }
                             }
                         }
-                        else
+                        finally
                         {
-                            curJpf = null;  // avoid synchronization in 
finally block below
+                            curJpf.decrementRequestCount( httpRequest );
                         }
                     }
-                    else
-                    {
-                        // @todo: need to wrap this in checks for JSP 1.2
-                        // @todo: feature: need to add support for chaining in 
user-code to
-                        //        run when setting implicit objects on the 
request
-                        InternalUtils.ensureGlobalApp(httpRequest, 
httpResponse);
-                        httpRequest.setAttribute("globalApp", 
PageFlowUtils.getGlobalApp(httpRequest));
-                        BundleMap bundleMap = new BundleMap(httpRequest, 
_servletContext, null);
-                        httpRequest.setAttribute("bundle", bundleMap);
-
-                        chain.doFilter( request, response );
-                    }
                 }
-                finally
+                else
                 {
-                    if ( curJpf != null )
-                    {
-                        synchronized ( curJpf )
-                        {
-                            curJpf.nullRequestMembers( httpRequest );
-                        }
-                    }
+                    // @todo: need to wrap this in checks for JSP 1.2
+                    // @todo: feature: need to add support for chaining in 
user-code to
+                    //        run when setting implicit objects on the request
+                    InternalUtils.ensureGlobalApp(httpRequest, httpResponse);
+                    httpRequest.setAttribute("globalApp", 
PageFlowUtils.getGlobalApp(httpRequest));
+                    BundleMap bundleMap = new BundleMap(httpRequest, 
_servletContext, null);
+                    httpRequest.setAttribute("bundle", bundleMap);
+
+                    chain.doFilter( request, response );
                 }
             }
             finally

Reply via email to