Author: hlship
Date: Mon Feb 22 18:20:33 2010
New Revision: 915002

URL: http://svn.apache.org/viewvc?rev=915002&view=rev
Log:
TAP5-1024: Add support for returning a navigation result from Submit event 
handler methods

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/TrackableComponentEventCallback.java
   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemo.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemoMessage.tml
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemo.java
   (with props)
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemoMessage.java
   (with props)
Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ComponentEventCallback.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/FormInjector.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ProgressiveDisplay.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxComponentEventRequestHandler.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventRequestHandlerImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResultProcessorWrapper.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageRenderRequestHandlerImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventResultProcessor.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ComponentEventCallback.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ComponentEventCallback.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ComponentEventCallback.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ComponentEventCallback.java
 Mon Feb 22 18:20:33 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 2010 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
+// 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,
@@ -15,22 +15,26 @@
 package org.apache.tapestry5;
 
 /**
- * Callback interface for a {...@linkplain org.apache.tapestry5.runtime.Event 
render phase event) or {...@link
- * org.apache.tapestry5.runtime.ComponentEvent}, notified when a non-null 
value is returned from some event handler
- * method.
+ * Callback interface for a {...@linkplain org.apache.tapestry5.runtime.Event 
render phase event) or
+ * 
+ * @link org.apache.tapestry5.runtime.ComponentEvent}, notified when a 
non-null value is returned from some event
+ *       handler method.
  */
 public interface ComponentEventCallback<T>
 {
     /**
      * Invoked to handle a non-null event handler method result. The handler 
should determine whether the value is
-     * acceptible, and throw an exception if not.  Any thrown exception will 
be wrapped to identify the component and
+     * acceptable, and throw an exception if not. Any thrown exception will be 
wrapped to identify the component and
      * method from which the value was returned.
      * <p/>
-     * Boolean values are <em>not</em> passed to the handler.  Booleans are 
used to indicate that the event has been
-     * handled (true) or that a further search for handlers should continue 
(true).  If a component event method returns
-     * true, then {...@link org.apache.tapestry5.runtime.Event#isAborted()} 
will return true.
-     *
-     * @param result the result value return from the event handler method
+     * Boolean values are <em>not</em> passed to the handler. Booleans are 
used to indicate that the event has been
+     * handled (true, meaning the event is handled and aborted) or that a 
further search for handlers should continue
+     * (false, meaning the event was not handler, is not aborted, and the 
search up the component heirarchy for event
+     * handler methods should continue). If a component event method returns 
true, then
+     * {...@link org.apache.tapestry5.runtime.Event#isAborted()} will return 
true.
+     * 
+     * @param result
+     *            the result value return from the event handler method
      * @return true if the event is aborted, false if the event may continue
      */
     boolean handleResult(T result);

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/TrackableComponentEventCallback.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/TrackableComponentEventCallback.java?rev=915002&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/TrackableComponentEventCallback.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/TrackableComponentEventCallback.java
 Mon Feb 22 18:20:33 2010
@@ -0,0 +1,44 @@
+// Copyright 2010 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.tapestry5;
+
+import java.io.IOException;
+
+import org.apache.tapestry5.annotations.Environmental;
+import org.apache.tapestry5.services.ComponentEventResultProcessor;
+import org.apache.tapestry5.services.Traditional;
+
+/**
+ * Extends {...@link ComponentEventCallback} with a way to determine if the 
underlying event has been aborted
+ * due to a some event returning an acceptable, non-null value. The standard 
implementation of this
+ * is a wrapper around either the {...@linkplain Traditional traditional} or 
{...@linkplain Ajax} versions
+ * of the {...@link ComponentEventResultProcessor} service, i.e., they allow 
for a navigational result.
+ * <p>
+ * Instances of this are made available via the {...@link Environmental} 
annotation.
+ * 
+ * @since 5.2.0
+ */
+public interface TrackableComponentEventCallback<T> extends 
ComponentEventCallback<T>
+{
+    /**
+     * Returns true if a return value from an event handler method was 
processed.
+     */
+    boolean isAborted();
+
+    /**
+     * If processing a return value threw an IOException, invoking this method 
will rethrow it.
+     */
+    void rethrow() throws IOException;
+}

Propchange: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/TrackableComponentEventCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
 Mon Feb 22 18:20:33 2010
@@ -131,12 +131,9 @@
     @Inject
     private BeanModelSource beanModelSource;
 
-    /**
-     * Set up via the traditional or Ajax component event request handler
-     */
     @SuppressWarnings("unchecked")
     @Environmental
-    private ComponentEventResultProcessor componentEventResultProcessor;
+    private TrackableComponentEventCallback eventCallback;
 
     void onPrepareFromForm()
     {
@@ -187,10 +184,10 @@
 
     boolean onSelectedFromCancel() throws IOException
     {
-        ComponentResultProcessorWrapper callback = new 
ComponentResultProcessorWrapper(componentEventResultProcessor);
-
-        resources.triggerEvent(EventConstants.CANCELED, null, callback);
+        resources.triggerEvent(EventConstants.CANCELED, null, eventCallback);
 
-        return callback.isAborted();
+        // Prevent further event handlers.
+        
+        return true;
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
 Mon Feb 22 18:20:33 2010
@@ -32,7 +32,6 @@
 import org.apache.tapestry5.dom.Element;
 import org.apache.tapestry5.internal.BeanValidationContext;
 import org.apache.tapestry5.internal.BeanValidationContextImpl;
-import org.apache.tapestry5.internal.services.ComponentResultProcessorWrapper;
 import org.apache.tapestry5.internal.services.HeartbeatImpl;
 import org.apache.tapestry5.internal.util.AutofocusValidationDecorator;
 import org.apache.tapestry5.ioc.Location;
@@ -46,7 +45,6 @@
 import org.apache.tapestry5.runtime.Component;
 import org.apache.tapestry5.services.ClientBehaviorSupport;
 import org.apache.tapestry5.services.ClientDataEncoder;
-import org.apache.tapestry5.services.ComponentEventResultProcessor;
 import org.apache.tapestry5.services.ComponentSource;
 import org.apache.tapestry5.services.Environment;
 import org.apache.tapestry5.services.FormSupport;
@@ -77,8 +75,8 @@
  */
 @Events(
 { EventConstants.PREPARE_FOR_RENDER, EventConstants.PREPARE, 
EventConstants.PREPARE_FOR_SUBMIT,
-        EventConstants.VALIDATE, EventConstants.VALIDATE_FORM, 
EventConstants.SUBMIT,
-        EventConstants.FAILURE, EventConstants.SUCCESS })
+        EventConstants.VALIDATE, EventConstants.VALIDATE_FORM, 
EventConstants.SUBMIT, EventConstants.FAILURE,
+        EventConstants.SUCCESS })
 public class Form implements ClientElement, FormValidationControl
 {
     /**
@@ -235,15 +233,12 @@
     @Mixin
     private RenderInformals renderInformals;
 
-    /**
-     * Set up via the traditional or Ajax component event request handler
-     */
-    @SuppressWarnings("unchecked")
     @Environmental
-    private ComponentEventResultProcessor componentEventResultProcessor;
+    private ClientBehaviorSupport clientBehaviorSupport;
 
+    @SuppressWarnings("unchecked")
     @Environmental
-    private ClientBehaviorSupport clientBehaviorSupport;
+    private TrackableComponentEventCallback eventCallback;
 
     @Inject
     private ClientDataEncoder clientDataEncoder;
@@ -418,11 +413,10 @@
      *            used to allocate unique ids
      * @return form support object
      */
-    InternalFormSupport createRenderTimeFormSupport(String name, 
ComponentActionSink actionSink,
-            IdAllocator allocator)
+    InternalFormSupport createRenderTimeFormSupport(String name, 
ComponentActionSink actionSink, IdAllocator allocator)
     {
-        return new FormSupportImpl(resources, name, actionSink, 
clientBehaviorSupport,
-                clientValidation, allocator, validationId);
+        return new FormSupportImpl(resources, name, actionSink, 
clientBehaviorSupport, clientValidation, allocator,
+                validationId);
     }
 
     void afterRender(MarkupWriter writer)
@@ -438,8 +432,7 @@
 
         writer.end(); // form
 
-        div.element("input", "type", "hidden", "name", FORM_DATA, "value", 
actionSink
-                .getClientData());
+        div.element("input", "type", "hidden", "name", FORM_DATA, "value", 
actionSink.getClientData());
 
         if (autofocus)
             environment.pop(ValidationDecorator.class);
@@ -481,17 +474,14 @@
 
         try
         {
-            ComponentResultProcessorWrapper callback = new 
ComponentResultProcessorWrapper(
-                    componentEventResultProcessor);
-
-            resources.triggerContextEvent(EventConstants.PREPARE_FOR_SUBMIT, 
context, callback);
+            resources.triggerContextEvent(EventConstants.PREPARE_FOR_SUBMIT, 
context, eventCallback);
 
-            if (callback.isAborted())
+            if (eventCallback.isAborted())
                 return true;
 
-            resources.triggerContextEvent(EventConstants.PREPARE, context, 
callback);
+            resources.triggerContextEvent(EventConstants.PREPARE, context, 
eventCallback);
 
-            if (callback.isAborted())
+            if (eventCallback.isAborted())
                 return true;
 
             executeStoredActions();
@@ -500,9 +490,9 @@
 
             formSupport.executeDeferred();
 
-            fireValidateFormEvent(context, callback);
+            fireValidateFormEvent(context, eventCallback);
 
-            if (callback.isAborted())
+            if (eventCallback.isAborted())
                 return true;
 
             // Let the listeners know about overall success or failure. Most
@@ -518,17 +508,17 @@
                 activeTracker.clear();
 
             resources.triggerContextEvent(activeTracker.getHasErrors() ? 
EventConstants.FAILURE
-                    : EventConstants.SUCCESS, context, callback);
+                    : EventConstants.SUCCESS, context, eventCallback);
 
             // Lastly, tell anyone whose interested that the form is completely
             // submitted.
 
-            if (callback.isAborted())
+            if (eventCallback.isAborted())
                 return true;
 
-            resources.triggerContextEvent(EventConstants.SUBMIT, context, 
callback);
+            resources.triggerContextEvent(EventConstants.SUBMIT, context, 
eventCallback);
 
-            return callback.isAborted();
+            return eventCallback.isAborted();
         }
         finally
         {
@@ -543,8 +533,8 @@
         }
     }
 
-    private void fireValidateFormEvent(EventContext context,
-            ComponentResultProcessorWrapper callback) throws IOException
+    private void fireValidateFormEvent(EventContext context, 
TrackableComponentEventCallback callback)
+            throws IOException
     {
         fireValidateEvent(EventConstants.VALIDATE, context, callback);
 
@@ -554,8 +544,7 @@
         fireValidateEvent(EventConstants.VALIDATE_FORM, context, callback);
     }
 
-    private void fireValidateEvent(String eventName, EventContext context,
-            ComponentResultProcessorWrapper callback)
+    private void fireValidateEvent(String eventName, EventContext context, 
TrackableComponentEventCallback callback)
     {
         try
         {
@@ -608,7 +597,7 @@
             {
                 ois = clientDataEncoder.decodeClientData(clientEncodedActions);
 
-                while (true)
+                while (!eventCallback.isAborted())
                 {
                     String componentId = ois.readUTF();
                     ComponentAction action = (ComponentAction) 
ois.readObject();
@@ -628,8 +617,7 @@
             }
             catch (Exception ex)
             {
-                Location location = component == null ? null : 
component.getComponentResources()
-                        .getLocation();
+                Location location = component == null ? null : 
component.getComponentResources().getLocation();
 
                 throw new TapestryException(ex.getMessage(), location, ex);
             }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/FormInjector.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/FormInjector.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/FormInjector.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/FormInjector.java
 Mon Feb 22 18:20:33 2010
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -79,7 +79,6 @@
     @Parameter(defaultPrefix = BindingConstants.LITERAL)
     private String element;
 
-
     @Environmental
     private RenderSupport renderSupport;
 
@@ -92,10 +91,9 @@
     @Environmental
     private Heartbeat heartbeat;
 
-    @Inject
-    @Ajax
-    private ComponentEventResultProcessor componentEventResultProcessor;
-
+    @SuppressWarnings("unchecked")
+    @Environmental
+    private TrackableComponentEventCallback eventCallback;
 
     @Inject
     private PageRenderQueue pageRenderQueue;
@@ -152,7 +150,6 @@
         clientElement.addClassName("t-forminjector");
     }
 
-
     /**
      * Returns the unique client-side id of the rendered element.
      */
@@ -174,18 +171,16 @@
     private ClientDataEncoder clientDataEncoder;
 
     /**
-     * Invoked via an Ajax request.  Triggers an action event and captures the 
return value. The return value from the
-     * event notification is what will ultimately render (typically, its a 
Block).  However, we do a <em>lot</em> of
+     * Invoked via an Ajax request. Triggers an action event and captures the 
return value. The return value from the
+     * event notification is what will ultimately render (typically, its a 
Block). However, we do a <em>lot</em> of
      * tricks to provide the desired FormSupport around the what renders.
      */
     void onInject(EventContext context) throws IOException
     {
-        ComponentResultProcessorWrapper callback = new 
ComponentResultProcessorWrapper(
-                componentEventResultProcessor);
-
-        resources.triggerContextEvent(EventConstants.ACTION, context, 
callback);
+        resources.triggerContextEvent(EventConstants.ACTION, context, 
eventCallback);
 
-        if (!callback.isAborted()) return;
+        if (!eventCallback.isAborted())
+            return;
 
         // Here's where it gets very, very tricky.
 
@@ -205,7 +200,7 @@
 
                 // Kind of ugly, but the only way to ensure we don't have name 
collisions on the
                 // client side is to force a unique id into each name (as well 
as each id, but that's
-                // RenderSupport's job).  It would be nice if we could agree 
on the uid, but
+                // RenderSupport's job). It would be nice if we could agree on 
the uid, but
                 // not essential.
 
                 String uid = Long.toHexString(System.currentTimeMillis());
@@ -216,8 +211,8 @@
 
                 reply.put("elementId", clientId);
 
-                InternalFormSupport formSupport =
-                        form.createRenderTimeFormSupport(formClientId, 
actionSink, idAllocator);
+                InternalFormSupport formSupport = 
form.createRenderTimeFormSupport(formClientId, actionSink,
+                        idAllocator);
 
                 environment.push(FormSupport.class, formSupport);
                 environment.push(ValidationTracker.class, new 
ValidationTrackerImpl());
@@ -233,12 +228,11 @@
                 environment.pop(ValidationTracker.class);
                 environment.pop(FormSupport.class);
 
-                hiddenFieldPositioner.getElement().attributes(
-                        "type", "hidden",
+                hiddenFieldPositioner.getElement().attributes("type", "hidden",
 
-                        "name", Form.FORM_DATA,
+                "name", Form.FORM_DATA,
 
-                        "value", actionSink.getClientData());
+                "value", actionSink.getClientData());
             }
         };
 
@@ -251,8 +245,7 @@
 
         if (InternalUtils.isBlank(value))
             throw new RuntimeException(String.format(
-                    "Query parameter '%s' was blank, but should have been 
specified in the request.",
-                    parameterName));
+                    "Query parameter '%s' was blank, but should have been 
specified in the request.", parameterName));
 
         return value;
     }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ProgressiveDisplay.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ProgressiveDisplay.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ProgressiveDisplay.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ProgressiveDisplay.java
 Mon Feb 22 18:20:33 2010
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -35,12 +35,10 @@
  * results in much faster page loads. You can
  * even nest these!
  * <p/>
- * The component simply does not render its body on initial render. On the
- * subsequent action event request, it fires a
- * {...@link org.apache.tapestry5.EventConstants#PROGRESSIVE_DISPLAY} event to
- * inform the container about the (optional) event context. The event handler
- * method may return a renderable object; if not then the component's body is
- * rendered as the partial markup response.
+ * The component simply does not render its body on initial render. On the 
subsequent action event request, it fires a
+ * {...@link org.apache.tapestry5.EventConstants#PROGRESSIVE_DISPLAY} event to 
inform the container about the (optional)
+ * event context. The event handler method may return a renderable object; if 
not then the component's body is rendered
+ * as the partial markup response.
  * 
  * @since 5.1.0.1
  */
@@ -70,8 +68,9 @@
     @Environmental
     private RenderSupport renderSupport;
 
+    @SuppressWarnings("unchecked")
     @Environmental
-    private ComponentEventResultProcessor resultProcessor;
+    private TrackableComponentEventCallback eventCallback;
 
     /**
      * Name of a function on the client-side Tapestry.ElementEffect object that
@@ -98,7 +97,8 @@
 
         JSONObject spec = new JSONObject();
 
-        if (InternalUtils.isNonBlank(update)) spec.put("update", 
update.toLowerCase());
+        if (InternalUtils.isNonBlank(update))
+            spec.put("update", update.toLowerCase());
 
         spec.put("element", clientId);
         spec.put("url", link.toAbsoluteURI());
@@ -110,12 +110,10 @@
 
     Object onAction(EventContext context) throws IOException
     {
-        ComponentResultProcessorWrapper wrapper = new 
ComponentResultProcessorWrapper(
-                resultProcessor);
+        resources.triggerContextEvent(EventConstants.PROGRESSIVE_DISPLAY, 
context, eventCallback);
 
-        resources.triggerContextEvent(EventConstants.PROGRESSIVE_DISPLAY, 
context, wrapper);
-
-        if (wrapper.isAborted()) return null;
+        if (eventCallback.isAborted())
+            return null;
 
         return getBody();
     }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
 Mon Feb 22 18:20:33 2010
@@ -98,6 +98,10 @@
 
     @Inject
     private JavascriptSupport javascriptSupport;
+    
+    @SuppressWarnings("unchecked")
+    @Environmental
+    private TrackableComponentEventCallback eventCallback;
 
     private Element element;
 
@@ -172,7 +176,8 @@
         {
             public void run()
             {
-                resources.triggerEvent(event, context, null);
+                // TAP5-1024: allow for navigation result from the event 
callback
+                resources.triggerEvent(event, context, eventCallback);
             }
         };
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxComponentEventRequestHandler.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxComponentEventRequestHandler.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxComponentEventRequestHandler.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxComponentEventRequestHandler.java
 Mon Feb 22 18:20:33 2010
@@ -1,10 +1,10 @@
-// Copyright 2007, 2008 The Apache Software Foundation
+// Copyright 2007, 2008, 2010 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
+// 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,
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry5.internal.services;
 
+import org.apache.tapestry5.TrackableComponentEventCallback;
 import org.apache.tapestry5.ContentType;
 import org.apache.tapestry5.EventConstants;
 import org.apache.tapestry5.internal.InternalConstants;
@@ -30,6 +31,7 @@
  * Similar to {...@link ComponentEventRequestHandlerImpl}, but built around 
the Ajax request cycle, where the action
  * request sends back an immediate JSON response containing the new content.
  */
+...@suppresswarnings("unchecked")
 public class AjaxComponentEventRequestHandler implements 
ComponentEventRequestHandler
 {
     private final RequestPageCache cache;
@@ -46,10 +48,9 @@
 
     private final AjaxPartialResponseRenderer partialRenderer;
 
-    public AjaxComponentEventRequestHandler(RequestPageCache cache, Request 
request, PageRenderQueue queue,
-                                            @Ajax 
ComponentEventResultProcessor resultProcessor,
-                                            PageContentTypeAnalyzer 
pageContentTypeAnalyzer, Environment environment,
-                                            AjaxPartialResponseRenderer 
partialRenderer)
+    public AjaxComponentEventRequestHandler(RequestPageCache cache, Request 
request, PageRenderQueue queue, @Ajax
+    ComponentEventResultProcessor resultProcessor, PageContentTypeAnalyzer 
pageContentTypeAnalyzer,
+            Environment environment, AjaxPartialResponseRenderer 
partialRenderer)
     {
         this.cache = cache;
         this.queue = queue;
@@ -79,11 +80,14 @@
 
         ComponentResultProcessorWrapper callback = new 
ComponentResultProcessorWrapper(interceptor);
 
-        
activePage.getRootElement().triggerContextEvent(EventConstants.ACTIVATE,
-                                                        
parameters.getPageActivationContext(), callback);
+        
activePage.getRootElement().triggerContextEvent(EventConstants.ACTIVATE, 
parameters.getPageActivationContext(),
+                callback);
 
-
-        if (callback.isAborted()) return;
+        if (callback.isAborted())
+        {
+            callback.rethrow();
+            return;
+        }
 
         // If we end up doing a partial render, the page render queue service 
needs to know the
         // page that will be rendered (for logging purposes, if nothing else).
@@ -103,14 +107,16 @@
         // This is certainly the case for forms.
 
         environment.push(ComponentEventResultProcessor.class, interceptor);
+        environment.push(TrackableComponentEventCallback.class, callback);
 
-        boolean handled = 
element.triggerContextEvent(parameters.getEventType(), 
parameters.getEventContext(),
-                                                      callback);
+        boolean handled = element
+                .triggerContextEvent(parameters.getEventType(), 
parameters.getEventContext(), callback);
 
         if (!handled)
             throw new 
TapestryException(ServicesMessages.eventNotHandled(element, 
parameters.getEventType()), element,
-                                        null);
+                    null);
 
+        environment.pop(TrackableComponentEventCallback.class);
         environment.pop(ComponentEventResultProcessor.class);
 
         if (queue.isPartialRenderInitialized())
@@ -119,10 +125,11 @@
             return;
         }
 
-        // If  some other form of return value that's not a partial page 
render was send through to the
+        // If some other form of return value that's not a partial page render 
was send through to the
         // Ajax ComponentEventResultProcessor, then there's nothing more to do.
 
-        if (resultProcessorInvoked.get()) return;
+        if (resultProcessorInvoked.get())
+            return;
 
         // Send an empty JSON reply if no value was returned from the 
component event handler method.
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventRequestHandlerImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventRequestHandlerImpl.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventRequestHandlerImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventRequestHandlerImpl.java
 Mon Feb 22 18:20:33 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 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
+// 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,
@@ -14,15 +14,22 @@
 
 package org.apache.tapestry5.internal.services;
 
+import java.io.IOException;
+
+import org.apache.tapestry5.TrackableComponentEventCallback;
 import org.apache.tapestry5.EventConstants;
 import org.apache.tapestry5.internal.structure.ComponentPageElement;
 import org.apache.tapestry5.internal.structure.Page;
 import org.apache.tapestry5.ioc.annotations.Primary;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
-import org.apache.tapestry5.services.*;
-
-import java.io.IOException;
+import org.apache.tapestry5.services.ComponentEventRequestHandler;
+import org.apache.tapestry5.services.ComponentEventRequestParameters;
+import org.apache.tapestry5.services.ComponentEventResultProcessor;
+import org.apache.tapestry5.services.Environment;
+import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.Traditional;
 
+...@suppresswarnings("unchecked")
 public class ComponentEventRequestHandlerImpl implements 
ComponentEventRequestHandler
 {
     private final ComponentEventResultProcessor resultProcessor;
@@ -35,15 +42,15 @@
 
     private final Environment environment;
 
-    public ComponentEventRequestHandlerImpl(
-            @Traditional @Primary
-            ComponentEventResultProcessor resultProcessor,
+    public ComponentEventRequestHandlerImpl(@Traditional
+    @Primary
+    ComponentEventResultProcessor resultProcessor,
 
-            RequestPageCache cache, Response response,
+    RequestPageCache cache, Response response,
 
-            ActionRenderResponseGenerator generator,
+    ActionRenderResponseGenerator generator,
 
-            Environment environment)
+    Environment environment)
     {
         this.resultProcessor = resultProcessor;
         this.cache = cache;
@@ -56,33 +63,44 @@
     {
         Page activePage = cache.get(parameters.getActivePageName());
 
-        ComponentResultProcessorWrapper callback = new 
ComponentResultProcessorWrapper(resultProcessor);
+        TrackableComponentEventCallback callback = new 
ComponentResultProcessorWrapper(resultProcessor);
+
+        environment.push(ComponentEventResultProcessor.class, resultProcessor);
+        environment.push(TrackableComponentEventCallback.class, callback);
 
         // If activating the page returns a "navigational result", then don't 
trigger the action
         // on the component.
 
-        
activePage.getRootElement().triggerContextEvent(EventConstants.ACTIVATE,
-                                                        
parameters.getPageActivationContext(), callback);
+        
activePage.getRootElement().triggerContextEvent(EventConstants.ACTIVATE, 
parameters.getPageActivationContext(),
+                callback);
 
-        if (callback.isAborted()) return;
+        if (callback.isAborted())
+        {
+            callback.rethrow();
+            return;
+        }
 
         Page containerPage = cache.get(parameters.getContainingPageName());
 
         ComponentPageElement element = 
containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
 
-        environment.push(ComponentEventResultProcessor.class, resultProcessor);
-
-        boolean handled = 
element.triggerContextEvent(parameters.getEventType(), 
parameters.getEventContext(),
-                                                      callback);
+        boolean handled = element
+                .triggerContextEvent(parameters.getEventType(), 
parameters.getEventContext(), callback);
 
         if (!handled)
             throw new 
TapestryException(ServicesMessages.eventNotHandled(element, 
parameters.getEventType()), element,
-                                        null);
+                    null);
 
+        environment.pop(TrackableComponentEventCallback.class);
         environment.pop(ComponentEventResultProcessor.class);
 
-        if (callback.isAborted()) return;
+        if (callback.isAborted())
+        {
+            callback.rethrow();
+            return;
+        }
 
-        if (!response.isCommitted()) generator.generateResponse(activePage);
+        if (!response.isCommitted())
+            generator.generateResponse(activePage);
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResultProcessorWrapper.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResultProcessorWrapper.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResultProcessorWrapper.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResultProcessorWrapper.java
 Mon Feb 22 18:20:33 2010
@@ -1,10 +1,10 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2010 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
+// 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,
@@ -14,15 +14,16 @@
 
 package org.apache.tapestry5.internal.services;
 
-import org.apache.tapestry5.ComponentEventCallback;
-import org.apache.tapestry5.services.ComponentEventResultProcessor;
-
 import java.io.IOException;
 
+import org.apache.tapestry5.TrackableComponentEventCallback;
+import org.apache.tapestry5.services.ComponentEventResultProcessor;
+
 /**
  * A wrapper around {...@link ComponentEventResultProcessor} that encapsulates 
capturing the exception.
  */
-public class ComponentResultProcessorWrapper implements ComponentEventCallback
+...@suppresswarnings("unchecked")
+public class ComponentResultProcessorWrapper implements 
TrackableComponentEventCallback
 {
     private boolean aborted;
 
@@ -37,6 +38,10 @@
 
     public boolean handleResult(Object result)
     {
+        if (aborted)
+            throw new IllegalStateException(
+                    "Event callback has already received and processed a 
result value and can not do so again.");
+
         try
         {
             processor.processResultValue(result);
@@ -54,14 +59,18 @@
     /**
      * Returns true if {...@link 
org.apache.tapestry5.ComponentEventCallback#handleResult(Object)} was invoked, 
false
      * otherwise.
-     *
+     * 
      * @return true if the event was aborted
-     * @throws IOException if {...@link 
ComponentEventResultProcessor#processResultValue(Object)} threw an IOException
      */
-    public boolean isAborted() throws IOException
+    public boolean isAborted()
     {
-        if (exception != null) throw exception;
-
         return aborted;
     }
+
+    public void rethrow() throws IOException
+    {
+        if (exception != null)
+            throw exception;
+    }
+
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageRenderRequestHandlerImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageRenderRequestHandlerImpl.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageRenderRequestHandlerImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageRenderRequestHandlerImpl.java
 Mon Feb 22 18:20:33 2010
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -14,23 +14,23 @@
 
 package org.apache.tapestry5.internal.services;
 
+import java.io.IOException;
+
+import org.apache.tapestry5.TrackableComponentEventCallback;
 import org.apache.tapestry5.EventConstants;
-import org.apache.tapestry5.internal.InternalConstants;
 import org.apache.tapestry5.internal.structure.Page;
 import org.apache.tapestry5.ioc.annotations.Primary;
 import org.apache.tapestry5.services.ComponentEventResultProcessor;
 import org.apache.tapestry5.services.PageRenderRequestHandler;
 import org.apache.tapestry5.services.PageRenderRequestParameters;
-import org.apache.tapestry5.services.Request;
 import org.apache.tapestry5.services.Traditional;
 
-import java.io.IOException;
-
 /**
  * Handles a page render request by activating and then rendering the page.
  * 
  * @see org.apache.tapestry5.internal.services.PageRenderDispatcher
  */
+...@suppresswarnings("unchecked")
 public class PageRenderRequestHandlerImpl implements PageRenderRequestHandler
 {
     private final RequestPageCache cache;
@@ -52,16 +52,17 @@
     {
         Page page = cache.get(parameters.getLogicalPageName());
 
-        ComponentResultProcessorWrapper callback = new 
ComponentResultProcessorWrapper(
-                resultProcessor);
+        TrackableComponentEventCallback callback = new 
ComponentResultProcessorWrapper(resultProcessor);
 
-        page.getRootElement().triggerContextEvent(EventConstants.ACTIVATE,
-                parameters.getActivationContext(), callback);
+        page.getRootElement().triggerContextEvent(EventConstants.ACTIVATE, 
parameters.getActivationContext(), callback);
 
         // The handler will have asked the result processor to send a response.
 
         if (callback.isAborted())
+        {
+            callback.rethrow();
             return;
+        }
 
         if (!parameters.isLoopback())
             page.pageReset();

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventResultProcessor.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventResultProcessor.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventResultProcessor.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventResultProcessor.java
 Mon Feb 22 18:20:33 2010
@@ -22,9 +22,9 @@
  * Responsible for handling the return value provided by a component event 
handler method.
  * <p/>
  * There are two services built into Tapestry that implement this interface: 
ComponentEventResultProcessor (used for
- * ordinary page-oriented requests, and distinguished by the @{...@link 
org.apache.tapestry5.services.Traditional}  and/or
- *
- * @{...@link org.apache.tapestry5.ioc.annotations.Primary} marker 
annotations) and AjaxComponentEventResultProcessor, used
+ * ordinary page-oriented requests, and distinguished by the @{...@link 
org.apache.tapestry5.services.Traditional}
+ * and/or @{...@link org.apache.tapestry5.ioc.annotations.Primary} marker 
annotations) and 
+ * AjaxComponentEventResultProcessor, used
  * for Ajax requests (which typically return a partially rendered page), 
distinguished by the @{...@link
  * org.apache.tapestry5.services.Ajax} marker annotation.
  * @param <T>

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemo.tml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemo.tml?rev=915002&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemo.tml Mon Feb 
22 18:20:33 2010
@@ -0,0 +1,16 @@
+<html t:type="Border" 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
+
+  <h1>Cancel Demo</h1>
+
+  <t:form t:id="form">
+    <t:errors/>
+    <t:label for="requiredText"/>
+    <t:textfield t:id="requiredText"/>
+
+    <br/>
+
+    <t:submit mode="cancel" t:id="cancel" text="Cancel Form"/>
+    <t:linksubmit mode="cancel" t:id="cancelLink">Cancel Form</t:linksubmit>
+
+  </t:form>
+</html>
\ No newline at end of file

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemoMessage.tml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemoMessage.tml?rev=915002&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemoMessage.tml 
(added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/CancelDemoMessage.tml 
Mon Feb 22 18:20:33 2010
@@ -0,0 +1,12 @@
+<html t:type="Border" 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
+
+  <h1>Cancel Demo Message</h1>
+
+  <p>
+    <strong id="message">${message}</strong>
+  </p>
+
+  <p>
+    <t:pagelink page="canceldemo">back</t:pagelink>
+  </p>
+</html>
\ No newline at end of file

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
 Mon Feb 22 18:20:33 2010
@@ -682,11 +682,11 @@
     public void link_submit_component()
     {
         clickThru("LinkSubmit Demo");
-        
+
         // Wait a moment for the page to initialize.
-        
+
         sleep(250);
-        
+
         // 
         click("link=Fred");
 
@@ -827,4 +827,23 @@
         assertFalse(isTextPresent("You must provide a value for Username"));
         assertFalse(isTextPresent("You must provide a value for Password"));
     }
+
+    /** TAP5-1024 */
+    @Test
+    public void use_of_cancel_mode_on_submit_button()
+    {
+        clickThru("Cancel Demo");
+
+        clickAndWait("//inp...@type='submit']");
+
+        assertText("message", "onSelectedFromCancel() invoked.");
+    }
+
+    @Test
+    public void use_of_cancel_mode_with_submitlink()
+    {
+        clickThru("Cancel Demo", "Cancel Form");
+
+        assertText("message", "onSelectedFromCancelLink() invoked.");
+    }
 }

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemo.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemo.java?rev=915002&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemo.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemo.java
 Mon Feb 22 18:20:33 2010
@@ -0,0 +1,55 @@
+// Copyright 2010 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.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.InjectPage;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.beaneditor.Validate;
+import org.apache.tapestry5.corelib.components.Form;
+
+/**
+ * Demo the use of the cancel option on Submit.
+ */
+public class CancelDemo
+{
+    @Property
+    @Validate("required")
+    private String requiredText;
+
+    @InjectPage
+    private CancelDemoMessage page;
+
+    @InjectComponent
+    private Form form;
+
+    Object onSelectedFromCancel()
+    {
+        form.clearErrors();
+
+        page.setMessage("onSelectedFromCancel() invoked.");
+
+        return page;
+    }
+
+    Object onSelectedFromCancelLink()
+    {
+        form.clearErrors();
+
+        page.setMessage("onSelectedFromCancelLink() invoked.");
+
+        return page;
+    }
+}

Propchange: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemoMessage.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemoMessage.java?rev=915002&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemoMessage.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemoMessage.java
 Mon Feb 22 18:20:33 2010
@@ -0,0 +1,36 @@
+// Copyright 2010 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.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.PersistenceConstants;
+import org.apache.tapestry5.annotations.Persist;
+
+public class CancelDemoMessage
+{
+    @Persist(PersistenceConstants.FLASH)
+    private String message;
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public void setMessage(String message)
+    {
+        this.message = message;
+    }
+    
+    
+}

Propchange: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/CancelDemoMessage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=915002&r1=915001&r2=915002&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
 Mon Feb 22 18:20:33 2010
@@ -66,6 +66,8 @@
 
     private static final List<Item> ITEMS = CollectionFactory
             .newList(
+                    
+                    new Item("CancelDemo", "Cancel Demo", "Use of the cancel 
option with Submit"),
 
                     new Item("PageResetDemo", "PageReset Annotation Demo",
                             "Use of PageReset annotation to re-initialize page 
state"),


Reply via email to