You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/02/21 21:45:57 UTC

svn commit: r510192 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/services/ site/apt/guide/ test/app1/WEB-INF/ test/java/org/apache/tapestry/integration/ test/java/org/a...

Author: hlship
Date: Wed Feb 21 12:45:55 2007
New Revision: 510192

URL: http://svn.apache.org/viewvc?view=rev&rev=510192
Log:
Support return values from activate event handler methods.  The return value is a "navigational result" (a page instance or page name, etc.).

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java
      - copied, changed from r508273, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Protected.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/SecurityAlert.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java
      - copied, changed from r508273, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandler.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandlerImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderer.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Dispatcher.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/request.apt
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java

Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java (from r508273, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java?view=diff&rev=510192&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java&r1=508273&p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java Wed Feb 21 12:45:55 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -25,11 +25,11 @@
  * Processes component action events sent as requests from the client. Action events include an
  * event type, identify a page and a component, and may provide additional context strings.
  */
-public class ComponentEventDispatcher implements Dispatcher
+public class ComponentActionDispatcher implements Dispatcher
 {
     private final ActionLinkHandler _actionLinkHandler;
 
-    public ComponentEventDispatcher(ActionLinkHandler actionLinkHandler)
+    public ComponentActionDispatcher(ActionLinkHandler actionLinkHandler)
     {
         _actionLinkHandler = actionLinkHandler;
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandler.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandler.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandler.java Wed Feb 21 12:45:55 2007
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.services.ActionResponseGenerator;
+
 /**
  * Handles a invocation related to rendering out a pages complete content.
  * <p>
@@ -21,7 +23,28 @@
  */
 public interface PageLinkHandler
 {
-    void handle(String logicalPageName, String[] context, PageRenderer renderer);
+    /**
+     * Invoked to activate and render a page. The return value of the event handler method(s) for
+     * the activate event may result in an action response generator being returned.
+     * 
+     * @param logicalPageName
+     *            the logical name of the page to activate and render
+     * @param context
+     *            context data, supplied by the page at render time, extracted from the render URL
+     * @param renderer
+     *            callback responsible for rendering the page
+     * @return an action response generator, or null if the page simply rendered
+     */
+    ActionResponseGenerator handle(String logicalPageName, String[] context, PageRenderer renderer);
 
-    void handle(ComponentInvocation invocation, PageRenderer renderer);
+    /**
+     * Invoked to handle the particular invocation. Triggers the activate event on the page; the
+     * event handler may return a value, in which case, this method will return a corresponding
+     * {@link ActionResponseGenerator}.
+     * 
+     * @param invocation
+     * @param renderer
+     * @return an action response generator, or null if the page simply rendered
+     */
+    ActionResponseGenerator handle(ComponentInvocation invocation, PageRenderer renderer);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandlerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandlerImpl.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandlerImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLinkHandlerImpl.java Wed Feb 21 12:45:55 2007
@@ -14,9 +14,15 @@
 
 package org.apache.tapestry.internal.services;
 
+import static org.apache.tapestry.ioc.internal.util.Defense.cast;
+
+import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.TapestryConstants;
 import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.internal.util.Holder;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ActionResponseGenerator;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
 
 /**
  * Handles a PageLink as specified by a PageLinkPathSource by activating and then rendering the
@@ -26,32 +32,62 @@
 {
     private final RequestPageCache _cache;
 
-    public PageLinkHandlerImpl(RequestPageCache cache)
+    private final ComponentEventResultProcessor _resultProcessor;
+
+    public PageLinkHandlerImpl(RequestPageCache cache, ComponentEventResultProcessor resultProcessor)
     {
         _cache = cache;
+        _resultProcessor = resultProcessor;
     }
 
-    public void handle(String logicalPageName, String[] context, PageRenderer renderer)
+    public ActionResponseGenerator handle(String logicalPageName, String[] context,
+            PageRenderer renderer)
     {
         PageLinkTarget target = new PageLinkTarget(logicalPageName);
         ComponentInvocation invocation = new ComponentInvocation(target, context);
 
-        handle(invocation, renderer);
+        return handle(invocation, renderer);
     }
 
-    public void handle(ComponentInvocation invocation, PageRenderer renderer)
+    public ActionResponseGenerator handle(ComponentInvocation invocation, PageRenderer renderer)
     {
         InvocationTarget target = invocation.getTarget();
-        PageLinkTarget pageLinkTarget = Defense.cast(target, PageLinkTarget.class, "target");
+        // I really don't like this cast; there must be a way to get rid of it?
+        PageLinkTarget pageLinkTarget = cast(target, PageLinkTarget.class, "target");
         Page page = _cache.get(pageLinkTarget.getPageName());
-        // Fire a notification so that the page can set itself up for the given context
+
+        // Fire a notification so that the page can set itself up for the given context.
+
+        // This duplicates some code from ActionLinkHandlerImpl.
+
+        final Holder<ActionResponseGenerator> holder = new Holder<ActionResponseGenerator>();
+
+        ComponentEventHandler handler = new ComponentEventHandler()
+        {
+            @SuppressWarnings("unchecked")
+            public boolean handleResult(Object result, Component component, String methodDescription)
+            {
+                ActionResponseGenerator generator = _resultProcessor.processComponentEvent(
+                        result,
+                        component,
+                        methodDescription);
+
+                holder.put(generator);
+
+                return true; // abort the event
+            }
+        };
 
         page.getRootElement().triggerEvent(
                 TapestryConstants.ACTIVATE_EVENT,
                 invocation.getContext(),
-                null);
+                handler);
+
+        if (holder.hasValue())
+            return holder.get();
 
         renderer.renderPage(page);
 
+        return null;
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java Wed Feb 21 12:45:55 2007
@@ -17,6 +17,7 @@
 import java.io.IOException;
 
 import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.ActionResponseGenerator;
 import org.apache.tapestry.services.ComponentClassResolver;
 import org.apache.tapestry.services.Dispatcher;
 import org.apache.tapestry.services.Request;
@@ -81,11 +82,16 @@
                         {
                             new RuntimeException(ex);
                         }
-
                     }
                 };
 
-                _handler.handle(pageName, context, renderer);
+                ActionResponseGenerator responseGenerator = _handler.handle(
+                        pageName,
+                        context,
+                        renderer);
+
+                if (responseGenerator != null)
+                    responseGenerator.sendClientResponse(response);
 
                 return true;
             }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderer.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderer.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderer.java Wed Feb 21 12:45:55 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,16 +12,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
-
+package org.apache.tapestry.internal.services;
+
 import org.apache.tapestry.internal.structure.Page;
-
-/**
- * Service responsible for writing a full page markup response.
- * 
- * 
- */
-public interface PageRenderer
-{
-    void renderPage(Page page);
-}
+import org.apache.tapestry.services.Response;
+
+/**
+ * Callback interface, responsible for writing a full page markup response. This acts as a wrapper
+ * around {@link PageResponseRenderer} and {@link Response}.
+ */
+public interface PageRenderer
+{
+    void renderPage(Page page);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java Wed Feb 21 12:45:55 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,19 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
-
-import java.io.IOException;
-
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.services.Response;
-
-/**
- * Service responsible for writing a full page markup response.
- * 
- * 
- */
-public interface PageResponseRenderer
-{
-    void renderPageResponse(Page page, Response response) throws IOException;
-}
+package org.apache.tapestry.internal.services;
+
+import java.io.IOException;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.Response;
+
+/**
+ * Service responsible for writing a full page markup response.
+ * 
+ * @see PageRenderer
+ */
+public interface PageResponseRenderer
+{
+    void renderPageResponse(Page page, Response response) throws IOException;
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Dispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Dispatcher.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Dispatcher.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Dispatcher.java Wed Feb 21 12:45:55 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,14 +17,16 @@
 import java.io.IOException;
 
 /**
- * A dispatcher is responsible for recognizing an incoming request.  Dispatchers form a chain of command.
+ * A dispatcher is responsible for recognizing an incoming request. Dispatchers form an ordered
+ * chain of command, with each dispatcher responsible for recognizing requests that it can process.
  */
 public interface Dispatcher
 {
     /**
      * Analyzes the incoming request and performs an appropriate operation for each.
      * 
-     * @return true if a response was delivered
+     * @return true if a response was delivered, false if the servlet container should be allowed to
+     *         handle the request
      */
     boolean dispatch(Request request, Response response) throws IOException;
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Wed Feb 21 12:45:55 2007
@@ -75,7 +75,7 @@
 import org.apache.tapestry.internal.services.CommonResourcesInjectionProvider;
 import org.apache.tapestry.internal.services.ComponentClassLocatorImpl;
 import org.apache.tapestry.internal.services.ComponentClassResolverImpl;
-import org.apache.tapestry.internal.services.ComponentEventDispatcher;
+import org.apache.tapestry.internal.services.ComponentActionDispatcher;
 import org.apache.tapestry.internal.services.ComponentInstanceResultProcessor;
 import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
 import org.apache.tapestry.internal.services.ComponentInvocationMap;
@@ -654,14 +654,16 @@
                 pageLinkHandler, _pageResponseRenderer));
 
         configuration.add(
-                "ComponentEvent",
-                new ComponentEventDispatcher(actionLinkHandler),
+                "ComponentAction",
+                new ComponentActionDispatcher(actionLinkHandler),
                 "after:PageRender");
     }
 
-    public PageLinkHandler buildPageLinkHandler()
+    public PageLinkHandler buildPageLinkHandler(
+            @Inject("infrastructure:ComponentEventResultProcessor")
+            ComponentEventResultProcessor resultProcessor)
     {
-        return new PageLinkHandlerImpl(_requestPageCache);
+        return new PageLinkHandlerImpl(_requestPageCache, resultProcessor);
     }
 
     public ActionLinkHandler buildActionLinkHandler(

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/request.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/request.apt?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/request.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/request.apt Wed Feb 21 12:45:55 2007
@@ -92,21 +92,25 @@
   treated as {{{event.html}activation context}} (generally speaking, the primary key of some related entity object), allowing the page to
   reconstruct the state it will need to succesfully render itself.
   
+  The event handler method for the activate event may return a value; this is treated the same as the return value from a component action request; typically
+  this will result in a redirect to another page. In this way, the activate event can perform simple validation at the page level ("can the user
+  see this page?").
+  
   Page render URLs consist of the logical name of the page plus additional path elements for the activation context.  The dispatcher
   here strips terms off of the path until it finds a known page name. Thus, "/mypage/27" would look first for a page whose name was "mypage/27", then look for 
   a page name "mypage". Assuming the second search was succesful, the page would be activated with the context "27".  If no logical page name
   can be identified, control passes to the next dispatcher.
 
-* tapestry.ComponentEvent
+* tapestry.ComponentAction
 
-  The component event dispatcher is used to trigger events in components.
+  The component action dispatcher is used to trigger events in components.
   
   The URL identifies the name of the page, then a series of component ids (the path from the page down to the specific component), then the name of the event to be
   triggered on the component. The remaining path elements are used as the context for the <event> (not for the page activation, which
   does not currently apply). For example, "/griddemo.FOO.BAR.action/3" would locate page "griddemo", then component "FOO.BAR", and trigger an event named "action", with
   the context "3".
   
-  The response from a component event is typically, but not universally, used to send a redirect to the client; the redirect URL is a page render URL
+  The response from a component action request is typically, but not universally, used to send a redirect to the client; the redirect URL is a page render URL
   to display the response to the event.  
    
    

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Protected.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Protected.html?view=auto&rev=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Protected.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Protected.html Wed Feb 21 12:45:55 2007
@@ -0,0 +1,8 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+<h1>Protected Page</h1>
+
+<p>It should never be possible to see this, as the onActivate() event handler method prevents it.</p>
+    
+    
+</html>

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/SecurityAlert.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/SecurityAlert.html?view=auto&rev=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/SecurityAlert.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/SecurityAlert.html Wed Feb 21 12:45:55 2007
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <h1>Security Alert</h1>
+    
+    <p>
+        Security exception: ${message}
+    </p>    
+    
+</html>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html Wed Feb 21 12:45:55 2007
@@ -50,17 +50,17 @@
                     <li>
                         <a t:type="PageLink" page="AssetDemo">AssetDemo</a> -- declaring an using
                         Assets </li>
-
-                </ul>
-            </td>
-            <td>
-                <ul>
                     <li>
                         <a t:type="PageLink" page="ExpansionSubclass">ExpansionSubclass</a> --
                         components can inherit templates from base classes </li>
                     <li>
                         <a href="InjectComponentMismatch">InjectComponentMismatch</a> -- check error
                         reporting when @InjectComponent doesn't match the actual field type </li>
+                </ul>
+            </td>
+            <td>
+                <ul>
+              
                     <li>
                         <a t:type="PageLink" page="ParameterDefault">ParameterDefault</a> --
                         defaulter methods for component parameters </li>
@@ -106,6 +106,10 @@
                         <a t:type="ActionLink" t:id="textStreamResponse">Text Stream Response</a> --
                         component event that directly returns a stream of character (rather than a
                         redirect) </li>
+                    <li>
+                        <a t:type="PageLink" page="protected">Protected Page</a> -- Demonstrate result of non-void return from
+                        a page's activate method.
+                    </li>
                 </ul>
             </td>
         </tr>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Wed Feb 21 12:45:55 2007
@@ -314,9 +314,9 @@
 
         clickAndWait("//input[@type='submit']");
 
-        assertValue("userName", "howard");
+        assertFieldValue("userName", "howard");
         // Verify that password fields do not render a non-blank password, even when it is known.
-        assertValue("password", "");
+        assertFieldValue("password", "");
 
         assertTextPresent("[howard]");
         assertTextPresent("[wrong-password]");
@@ -460,11 +460,11 @@
         assertText("//label[@id='l5']", "Department");
         assertText("//label[@id='l6']", "Urgent Processing Requested");
 
-        assertValue("email", "");
-        assertValue("message", "");
-        assertValue("operatingSystem", "osx");
-        assertValue("department", "ACCOUNTING");
-        assertValue("urgent", "on");
+        assertFieldValue("email", "");
+        assertFieldValue("message", "");
+        assertFieldValue("operatingSystem", "osx");
+        assertFieldValue("department", "ACCOUNTING");
+        assertFieldValue("urgent", "on");
 
         _selenium.type("email", "foo@bar.baz");
         _selenium.type("message", "Message for you, sir!");
@@ -474,9 +474,9 @@
 
         clickAndWait("//input[@type='submit']");
 
-        assertValue("email", "foo@bar.baz");
-        assertValue("message", "Message for you, sir!");
-        assertValue("urgent", "off");
+        assertFieldValue("email", "foo@bar.baz");
+        assertFieldValue("message", "Message for you, sir!");
+        assertFieldValue("urgent", "off");
 
         // Tried to use "email:" and "exact:email:" but Selenium 0.8.1 doesn't seem to accept that.
 
@@ -616,7 +616,7 @@
         }
     }
 
-    private void assertValue(String locator, String expected)
+    private void assertFieldValue(String locator, String expected)
     {
         assertEquals(_selenium.getValue(locator), expected);
     }
@@ -658,9 +658,9 @@
         clickAndWait("link=" + linkLabel);
         clickAndWait("reset");
 
-        assertValue("title", "End World Hunger");
-        assertValue("title_0", "Develop Faster-Than-Light Travel");
-        assertValue("title_1", "Cure Common Cold");
+        assertFieldValue("title", "End World Hunger");
+        assertFieldValue("title_0", "Develop Faster-Than-Light Travel");
+        assertFieldValue("title_1", "Cure Common Cold");
 
         _selenium.type("title", "End World Hunger - today");
         _selenium.type("title_0", "Develop Faster-Than-Light Travel - immediately");
@@ -668,9 +668,9 @@
 
         clickAndWait("//input[@value='Update ToDos']");
 
-        assertValue("title", "End World Hunger - today");
-        assertValue("title_0", "Develop Faster-Than-Light Travel - immediately");
-        assertValue("title_1", "Cure Common Cold - post haste");
+        assertFieldValue("title", "End World Hunger - today");
+        assertFieldValue("title_0", "Develop Faster-Than-Light Travel - immediately");
+        assertFieldValue("title_1", "Cure Common Cold - post haste");
 
         clickAndWait("addNew");
 
@@ -678,10 +678,10 @@
 
         clickAndWait("//input[@value='Update ToDos']");
 
-        assertValue("title", "End World Hunger - today");
-        assertValue("title_0", "Develop Faster-Than-Light Travel - immediately");
-        assertValue("title_1", "Cure Common Cold - post haste");
-        assertValue("title_2", "Conquer World");
+        assertFieldValue("title", "End World Hunger - today");
+        assertFieldValue("title_0", "Develop Faster-Than-Light Travel - immediately");
+        assertFieldValue("title_1", "Cure Common Cold - post haste");
+        assertFieldValue("title_2", "Conquer World");
     }
 
     /**
@@ -870,6 +870,20 @@
         clickAndWait("link=Null Grid");
 
         assertTextPresent("There is no data to display.");
+    }
+
+    @Test
+    public void navigation_response_from_page_activate() throws Exception
+    {
+        _selenium.open(BASE_URL);
+
+        clickAndWait("link=Protected Page");
+
+        assertText("//h1", "Security Alert");
+
+        // The message is set by Protected, but is rendered by SecurityAlert.
+
+        assertTextPresent("Access to Protected page is denied");
     }
 
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java?view=auto&rev=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java Wed Feb 21 12:45:55 2007
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.InjectPage;
+
+public class Protected
+{
+    @InjectPage
+    private SecurityAlert _alertPage;
+
+    Object onActivate()
+    {
+        _alertPage.setMessage("Access to Protected page is denied.");
+
+        return _alertPage;
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java?view=auto&rev=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java Wed Feb 21 12:45:55 2007
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.Persist;
+
+public class SecurityAlert
+{
+    @Persist("flash")
+    private String _message;
+
+    public String getMessage()
+    {
+        return _message;
+    }
+
+    public void setMessage(String mesasge)
+    {
+        _message = mesasge;
+    }
+
+}

Copied: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java (from r508273, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java?view=diff&rev=510192&p1=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java&r1=508273&p2=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java Wed Feb 21 12:45:55 2007
@@ -26,7 +26,7 @@
 import org.easymock.EasyMock;
 import org.testng.annotations.Test;
 
-public class ComponentEventDispatcherTest extends InternalBaseTestCase
+public class ComponentActionDispatcherTest extends InternalBaseTestCase
 {
     @Test
     public void no_dot_in_path() throws Exception
@@ -39,7 +39,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler);
+        Dispatcher dispatcher = new ComponentActionDispatcher(handler);
 
         assertFalse(dispatcher.dispatch(request, response));
 
@@ -106,7 +106,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler);
+        Dispatcher dispatcher = new ComponentActionDispatcher(handler);
 
         assertTrue(dispatcher.dispatch(request, response));
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java?view=diff&rev=510192&r1=510191&r2=510192
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java Wed Feb 21 12:45:55 2007
@@ -16,7 +16,7 @@
 
 import static org.easymock.EasyMock.aryEq;
 import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.same;
+import static org.easymock.EasyMock.isA;
 
 import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.TapestryConstants;
@@ -24,6 +24,7 @@
 import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
 import org.apache.tapestry.services.Dispatcher;
 import org.apache.tapestry.services.Request;
 import org.apache.tapestry.services.Response;
@@ -37,7 +38,7 @@
         ComponentClassResolver resolver = newComponentClassResolver();
         PageResponseRenderer renderer = newPageResponseRenderer();
         RequestPageCache cache = newRequestPageCache();
-        PageLinkHandler handler = new PageLinkHandlerImpl(cache);
+        PageLinkHandler handler = new PageLinkHandlerImpl(cache, null);
         Request request = newRequest();
         Response response = newResponse();
 
@@ -60,7 +61,7 @@
         ComponentClassResolver resolver = newComponentClassResolver();
         PageResponseRenderer renderer = newPageResponseRenderer();
         RequestPageCache cache = newRequestPageCache();
-        PageLinkHandler handler = new PageLinkHandlerImpl(cache);
+        ComponentEventResultProcessor processor = newComponentEventResultProcessor();
         Request request = newRequest();
         Response response = newResponse();
         Page page = newPage();
@@ -85,6 +86,8 @@
 
         replay();
 
+        PageLinkHandler handler = new PageLinkHandlerImpl(cache, processor);
+
         Dispatcher d = new PageRenderDispatcher(resolver, handler, renderer);
 
         assertTrue(d.dispatch(request, response));
@@ -95,10 +98,10 @@
     @Test
     public void context_passed_in_path() throws Exception
     {
+        ComponentEventResultProcessor processor = newComponentEventResultProcessor();
         ComponentClassResolver resolver = newComponentClassResolver();
         PageResponseRenderer renderer = newPageResponseRenderer();
         RequestPageCache cache = newRequestPageCache();
-        PageLinkHandler handler = new PageLinkHandlerImpl(cache);
         Request request = newRequest();
         Response response = newResponse();
         Page page = newPage();
@@ -119,6 +122,8 @@
 
         replay();
 
+        PageLinkHandler handler = new PageLinkHandlerImpl(cache, processor);
+
         Dispatcher d = new PageRenderDispatcher(resolver, handler, renderer);
 
         assertTrue(d.dispatch(request, response));
@@ -126,10 +131,18 @@
         verify();
     }
 
+    protected ComponentEventResultProcessor newComponentEventResultProcessor()
+    {
+        return newMock(ComponentEventResultProcessor.class);
+    }
+
     private void train_triggerEvent(ComponentPageElement element, String eventType,
             Object[] context, ComponentEventHandler handler, boolean handled)
     {
-        expect(element.triggerEvent(eq(eventType), aryEq(context), same(handler))).andReturn(
-                handled);
+        expect(
+                element.triggerEvent(
+                        eq(eventType),
+                        aryEq(context),
+                        isA(ComponentEventHandler.class))).andReturn(handled);
     }
 }