You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/01/16 03:33:12 UTC

svn commit: r612337 [1/3] - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry/ main/java/org/apache/tapestry/corelib/components/ main/java/org/apache/tapestry/corelib/mixins/ main/java/org/apache/tapestry/internal/ main/java...

Author: hlship
Date: Tue Jan 15 18:33:09 2008
New Revision: 612337

URL: http://svn.apache.org/viewvc?rev=612337&view=rev
Log:
TAPESTRY-2044: Component action requests are not capable of handling the case where the active page and the page containing the component are different

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java
      - copied, changed from r602673, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/NotificationEventCallback.java
      - copied, changed from r594255, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/NotificationEventHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestParameters.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/BlockCaller.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/BlockHolder.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockCaller.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockHolder.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/NotificationEventCallbackTest.java
      - copied, changed from r594255, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/util/NotificationEventHandlerTest.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StreamResponseResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/Event.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidationSupportImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java

Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java (from r602673, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventHandler.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventHandler.java&r1=602673&r2=612337&rev=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventHandler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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,21 +17,19 @@
 import org.apache.tapestry.runtime.Component;
 
 /**
- * Handler for a a {@linkplain org.apache.tapestry.runtime.Event render phase event) or
- * {@link org.apache.tapestry.runtime.ComponentEvent }, notified when a non-null value is returned from some event
- * handler method.
+ * Callback interface for a {@linkplain org.apache.tapestry.runtime.Event render phase event) or {@link
+ * org.apache.tapestry.runtime.ComponentEvent}, notified when a non-null value is returned from some event handler
+ * method.
  */
-public interface ComponentEventHandler<T>
+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.
+     * 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.
      * <p/>
-     * <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.tapestry.runtime.Event#isAborted()} will return true.
+     * 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.tapestry.runtime.Event#isAborted()} will return true.
      *
      * @param result            the result value provided by a method
      * @param component         the component from which the result was obtained

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java Tue Jan 15 18:33:09 2008
@@ -22,17 +22,16 @@
 import org.apache.tapestry.runtime.PageLifecycleListener;
 
 /**
- * Provides a component instance with the resources provided by the framework. In many
- * circumstances, the resources object can be considered the component itself; in others, it is the
- * {@link #getComponent() component property}, and instance of a class provided by the application
- * developer (though transformed in many ways while being loaded) that is the true component. In
- * reality, it is the combination of the resources object with the lifecycle instance.
+ * Provides a component instance with the resources provided by the framework. In many circumstances, the resources
+ * object can be considered the component itself; in others, it is the {@link #getComponent() component property}, and
+ * instance of a class provided by the application developer (though transformed in many ways while being loaded) that
+ * is the true component. In reality, it is the combination of the resources object with the lifecycle instance.
  */
 public interface ComponentResources extends ComponentResourcesCommon
 {
     /**
-     * Returns the base resource for the component, which will represent the class's location within
-     * the classpath (this is used to resolve relative assets).
+     * Returns the base resource for the component, which will represent the class's location within the classpath (this
+     * is used to resolve relative assets).
      */
     Resource getBaseResource();
 
@@ -47,28 +46,27 @@
     Component getComponent();
 
     /**
-     * Returns the component which contains this component, or null for the root component.
-     * For mixins, this returns the componet to which the mixin is attached.
+     * Returns the component which contains this component, or null for the root component. For mixins, this returns the
+     * componet to which the mixin is attached.
      */
     Component getContainer();
 
     /**
-     * Returns the {@link ComponentResources} for the container, or null if the this is the root
-     * component (that has no container). As a special case, for a mixin, this returns the core
-     * component's resources.
+     * Returns the {@link ComponentResources} for the container, or null if the this is the root component (that has no
+     * container). As a special case, for a mixin, this returns the core component's resources.
      */
     ComponentResources getContainerResources();
 
     /**
-     * Returns the {@link Messages} from the container, or null if this is the root component (with
-     * no container). As a special case, for a mixin, this return the core component's messages.
+     * Returns the {@link Messages} from the container, or null if this is the root component (with no container). As a
+     * special case, for a mixin, this return the core component's messages.
      */
     Messages getContainerMessages();
 
     /**
-     * Returns the page that contains this component. Technically, the page itself is an internal
-     * object in Tapestry and this returns the root component of the actual page, but from an
-     * application developer point of view, this is the page.
+     * Returns the page that contains this component. Technically, the page itself is an internal object in Tapestry and
+     * this returns the root component of the actual page, but from an application developer point of view, this is the
+     * page.
      */
     Component getPage();
 
@@ -87,8 +85,8 @@
     boolean isBound(String parameterName);
 
     /**
-     * Indentifies all parameters that are not formal parameters and writes each as a
-     * attribute/value pair into the current element of the markup writer.
+     * Indentifies all parameters that are not formal parameters and writes each as a attribute/value pair into the
+     * current element of the markup writer.
      *
      * @param writer to which {@link MarkupWriter#attributes(Object[]) attributes} will be written
      */
@@ -100,11 +98,10 @@
     Messages getMessages();
 
     /**
-     * Returns the actual type of the bound parameter, or null if the parameter is not bound. This
-     * is primarily used with property bindings, and is used to determine the actual type of the
-     * property, rather than the type of parameter (remember that type coercion automatically
-     * occurs, which can mask significant differences between the parameter type and the bound
-     * property type).
+     * Returns the actual type of the bound parameter, or null if the parameter is not bound. This is primarily used
+     * with property bindings, and is used to determine the actual type of the property, rather than the type of
+     * parameter (remember that type coercion automatically occurs, which can mask significant differences between the
+     * parameter type and the bound property type).
      *
      * @param parameterName used to select the parameter (case is ignored)
      * @return the type of the bound parameter, or null if the parameter is not bound
@@ -153,16 +150,16 @@
 
 
     /**
-     * Creates a component action request link as a callback for this component. The event type
-     * and context (as well as the page name and nested component id) will be encoded into a URL. A request for the
-     * URL will {@linkplain #triggerEvent(String, Object[], ComponentEventHandler)}  trigger} the named event
-     * on the component.
-     *
-     * @param eventType the type of event to be triggered.  Event types should be Java identifiers (contain only letters, numbers and the underscore).
-     * @param forForm   if true, the link will be used as the eventType for an HTML form submission, which
-     *                  may affect what information is encoded into the link
-     * @param context   additional objects to be encoded into the path portion of the link; each is
-     *                  converted to a string and URI encoded
+     * Creates a component action request link as a callback for this component. The event type and context (as well as
+     * the page name and nested component id) will be encoded into a URL. A request for the URL will {@linkplain
+     * #triggerEvent(String, Object[], ComponentEventCallback)}  trigger} the named event on the component.
+     *
+     * @param eventType the type of event to be triggered.  Event types should be Java identifiers (contain only
+     *                  letters, numbers and the underscore).
+     * @param forForm   if true, the link will be used as the eventType for an HTML form submission, which may affect
+     *                  what information is encoded into the link
+     * @param context   additional objects to be encoded into the path portion of the link; each is converted to a
+     *                  string and URI encoded
      * @return link object for the callback
      */
     Link createActionLink(String eventType, boolean forForm, Object... context);
@@ -171,10 +168,10 @@
      * Creates a render request link to a specific page.
      *
      * @param pageName the logical name of the page to link to
-     * @param override if true, the context is used even if empty (normally, the target page is allowed
-     *                 to passivate, providing a context, when the provided context is empty)
-     * @param context  the activation context for the page. If omitted, the activation context is
-     *                 obtained from the target paget
+     * @param override if true, the context is used even if empty (normally, the target page is allowed to passivate,
+     *                 providing a context, when the provided context is empty)
+     * @param context  the activation context for the page. If omitted, the activation context is obtained from the
+     *                 target paget
      */
     Link createPageLink(String pageName, boolean override, Object... context);
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java Tue Jan 15 18:33:09 2008
@@ -25,29 +25,28 @@
 import java.util.Locale;
 
 /**
- * Operations shared by the public {@link ComponentResources} interface and
- * {@link ComponentPageElement} interface (on the internal side).
+ * Operations shared by the public {@link ComponentResources} interface and {@link ComponentPageElement} interface (on
+ * the internal side).
  */
 public interface ComponentResourcesCommon extends Locatable
 {
     /**
-     * Returns the id of the component. The id will be unique within the component's immediate
-     * container. For a page's root component, the value null is returned.
+     * Returns the id of the component. The id will be unique within the component's immediate container. For a page's
+     * root component, the value null is returned.
      */
     String getId();
 
     /**
-     * Return a string consisting the concatinated ids of all containing components, separated by
-     * periods. In addition, nested ids are always all lower case. I.e., "foo.bar.baz". Returns null
-     * for the root component of a  page.
+     * Return a string consisting the concatinated ids of all containing components, separated by periods. In addition,
+     * nested ids are always all lower case. I.e., "foo.bar.baz". Returns null for the root component of a  page.
      */
     String getNestedId();
 
 
     /**
-     * Returns a string consisting of the logical name of the containing page, and the
-     * {@link #getNestedId() nested id} of this component, separated by a colon. I.e.,
-     * "mypage:foo.bar.baz". For a page, returns just the page's logical name.
+     * Returns a string consisting of the logical name of the containing page, and the {@link #getNestedId() nested id}
+     * of this component, separated by a colon. I.e., "mypage:foo.bar.baz". For a page, returns just the page's logical
+     * name.
      * <p/>
      * This value is often used to obtain an equivalent component instance in a later request.
      *
@@ -57,39 +56,35 @@
     String getCompleteId();
 
     /**
-     * Triggers a component event. A search for an event handling method will occur, first in the
-     * component, then its container, and so on. When a matching event handler method is located, it
-     * is invoked. If the method returns a value, the value is passed to the handler (if handler is
-     * null, then it is an error for a method to return a non-null value).
+     * Triggers a component event. A search for an event handling method will occur, first in the component, then its
+     * container, and so on. When a matching event handler method is located, it is invoked. If the method returns a
+     * value, the value is passed to the handler (if handler is null, then it is an error for a method to return a
+     * non-null value).
      * <p/>
      * Resolution of event type to event handler methods is case insensitive.
      *
      * @param eventType event type (as determined from the request, or otherwise by design)
-     * @param context   the context (as extracted from the request, or provided by the triggering
-     *                  component); these values may be provided to event handler methods via their
-     *                  parameters (may be null)
-     * @param handler   the handler to be informed of the result, or null if the event is a notification
-     *                  that does not support return values from event handler methods (the value true is
-     *                  allowed even if the handler is null).
-     * @return true if any event handler was invoked (even if no event handler method returns a
-     *         non-null value)
+     * @param context   the context (as extracted from the request, or provided by the triggering component); these
+     *                  values may be provided to event handler methods via their parameters (may be null)
+     * @param callback  the handler to be informed of the result, or null if the event is a notification that does not
+     *                  support return values from event handler methods (the value true is allowed even if the handler
+     *                  is null).
+     * @return true if any event handler was invoked (even if no event handler method returns a non-null value)
      * @throws org.apache.tapestry.runtime.ComponentEventException
-     *          if an event handler method throws a checked
-     *          or unchecked exception
+     *          if an event handler method throws a checked or unchecked exception
      * @see OnEventWorker
      * @see OnEvent
      */
-    boolean triggerEvent(String eventType, Object[] context, ComponentEventHandler handler);
+    boolean triggerEvent(String eventType, Object[] context, ComponentEventCallback callback);
 
     /**
-     * Returns true if the component is currently rendering, false otherwise. This is most often
-     * used to determine if parameter values should be cached.
+     * Returns true if the component is currently rendering, false otherwise. This is most often used to determine if
+     * parameter values should be cached.
      */
     boolean isRendering();
 
     /**
-     * Returns the log instance associated with the component (which is based on the component or
-     * mixin's class name).
+     * Returns the log instance associated with the component (which is based on the component or mixin's class name).
      *
      * @see ComponentModel#getLogger()
      */
@@ -101,8 +96,8 @@
     Locale getLocale();
 
     /**
-     * Returns the name of element that represents the component in its template, or null if the
-     * element was a component type (in the Tapestry namespace).
+     * Returns the name of element that represents the component in its template, or null if the element was a component
+     * type (in the Tapestry namespace).
      *
      * @return the element name
      */
@@ -127,8 +122,8 @@
     Block findBlock(String blockId);
 
     /**
-     * Returns the <em>logical</em> name of the page containing this component. This is the short
-     * name (it often appears in URLs)
+     * Returns the <em>logical</em> name of the page containing this component. This is the short name (it often appears
+     * in URLs)
      *
      * @return the logical name of the page which contains this component
      */

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -24,10 +24,10 @@
 import org.apache.tapestry.dom.Element;
 import org.apache.tapestry.internal.TapestryInternalUtils;
 import org.apache.tapestry.internal.services.ComponentInvocationMap;
+import org.apache.tapestry.internal.services.ComponentResultProcessorWrapper;
 import org.apache.tapestry.internal.services.HeartbeatImpl;
 import org.apache.tapestry.internal.util.Base64ObjectInputStream;
 import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
-import org.apache.tapestry.internal.util.Holder;
 import org.apache.tapestry.ioc.annotations.Inject;
 import org.apache.tapestry.ioc.internal.util.TapestryException;
 import org.apache.tapestry.runtime.Component;
@@ -42,84 +42,77 @@
 /**
  * An HTML form, which will enclose other components to render out the various types of fields.
  * <p/>
- * A Form emits several notification events; when it renders it sends a {@link #PREPARE prepare}
- * notification event, to allow any listeners to set up the state of the page prior to rendering out
- * the form's content.
+ * A Form emits several notification events; when it renders it sends a {@link #PREPARE prepare} notification event, to
+ * allow any listeners to set up the state of the page prior to rendering out the form's content.
  * <p/>
- * When the form is submitted, the component emits four notifications: first another prepare event
- * to allow the page to update its state as necessary to prepare for the form submission, then
- * (after components enclosed by the form have operated), a "validate" event is emitted, to allow
- * for cross-form validation. After that, either a "success" or "failure" event (depending on
- * whether the {@link ValidationTracker} has recorded any errors). Lastly, a "submit" event, for any
- * listeners that care only about form submission, regardless of success or failure.
+ * When the form is submitted, the component emits four notifications: first another prepare event to allow the page to
+ * update its state as necessary to prepare for the form submission, then (after components enclosed by the form have
+ * operated), a "validate" event is emitted, to allow for cross-form validation. After that, either a "success" or
+ * "failure" event (depending on whether the {@link ValidationTracker} has recorded any errors). Lastly, a "submit"
+ * event, for any listeners that care only about form submission, regardless of success or failure.
  * <p/>
- * For all of these notifications, the event context is derived from the <strong>context</strong>
- * parameter. This context is encoded into the form's action URI (the parameter is not read when the
- * form is submitted, instead the values encoded into the form are used).
+ * For all of these notifications, the event context is derived from the <strong>context</strong> parameter. This
+ * context is encoded into the form's action URI (the parameter is not read when the form is submitted, instead the
+ * values encoded into the form are used).
  */
 public class Form implements ClientElement, FormValidationControl
 {
     /**
-     * Invoked to let the containing component(s) prepare for the form rendering or the form
-     * submission.
+     * Invoked to let the containing component(s) prepare for the form rendering or the form submission.
      */
     public static final String PREPARE = "prepare";
 
     /**
-     * Event type for a notification after the form has submitted. This event notification occurs on
-     * any form submit, without respect to "success" or "failure".
+     * Event type for a notification after the form has submitted. This event notification occurs on any form submit,
+     * without respect to "success" or "failure".
      */
     public static final String SUBMIT = "submit";
 
     /**
-     * Event type for a notification to perform validation of submitted data. This allows a listener
-     * to perform cross-field validation. This occurs before the {@link #SUCCESS} or
-     * {@link #FAILURE} notification.
+     * Event type for a notification to perform validation of submitted data. This allows a listener to perform
+     * cross-field validation. This occurs before the {@link #SUCCESS} or {@link #FAILURE} notification.
      */
     public static final String VALIDATE = "validate";
 
     /**
-     * Event type for a notification after the form has submitted, when there are no errors in the
-     * validation tracker. This occurs before the {@link #SUBMIT} event.
+     * Event type for a notification after the form has submitted, when there are no errors in the validation tracker.
+     * This occurs before the {@link #SUBMIT} event.
      */
     public static final String SUCCESS = "success";
 
     /**
-     * Event type for a notification after the form has been submitted, when there are errors in the
-     * validation tracker. This occurs before the {@link #SUBMIT} event.
+     * Event type for a notification after the form has been submitted, when there are errors in the validation tracker.
+     * This occurs before the {@link #SUBMIT} event.
      */
     public static final String FAILURE = "failure";
 
     /**
-     * The context for the link (optional parameter). This list of values will be converted into
-     * strings and included in the URI. The strings will be coerced back to whatever their values
-     * are and made available to event handler methods.
+     * The context for the link (optional parameter). This list of values will be converted into strings and included in
+     * the URI. The strings will be coerced back to whatever their values are and made available to event handler
+     * methods.
      */
     @Parameter
     private List<?> _context;
 
     /**
-     * The object which will record user input and validation errors. The object must be persistent
-     * between requests (since the form submission and validation occurs in an component event
-     * request and the subsequent render occurs in a render request). The default is a persistent
-     * property of the Form component and this is sufficient for nearly all purposes (except when a
-     * Form is rendered inside a loop).
+     * The object which will record user input and validation errors. The object must be persistent between requests
+     * (since the form submission and validation occurs in an component event request and the subsequent render occurs
+     * in a render request). The default is a persistent property of the Form component and this is sufficient for
+     * nearly all purposes (except when a Form is rendered inside a loop).
      */
     @Parameter("defaultTracker")
     private ValidationTracker _tracker;
 
     /**
-     * Query parameter name storing form data (the serialized commands needed to process a form
-     * submission).
+     * Query parameter name storing form data (the serialized commands needed to process a form submission).
      */
     public static final String FORM_DATA = "t:formdata";
 
     /**
-     * If true (the default) then client validation is enabled for the form, and the default set of
-     * JavaScript libraries (Prototype, Scriptaculous and the Tapestry library) will be added to the
-     * rendered page, and the form will register itself for validation. This may be turned off when
-     * client validation is not desired; for example, when many validations are used that do not
-     * operate on the client side at all.
+     * If true (the default) then client validation is enabled for the form, and the default set of JavaScript libraries
+     * (Prototype, Scriptaculous and the Tapestry library) will be added to the rendered page, and the form will
+     * register itself for validation. This may be turned off when client validation is not desired; for example, when
+     * many validations are used that do not operate on the client side at all.
      */
     @Parameter("true")
     private boolean _clientValidation;
@@ -279,7 +272,7 @@
     }
 
     @SuppressWarnings({"unchecked", "InfiniteLoopStatement"})
-    Object onAction(Object[] context)
+    Object onAction(Object[] context) throws IOException
     {
         _tracker.clear();
 
@@ -296,35 +289,11 @@
 
         try
         {
-            final Holder<Object> holder = Holder.create();
+            ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(_eventResultProcessor);
 
-            ComponentEventHandler handler = new ComponentEventHandler()
-            {
-                public boolean handleResult(Object result, Component component, String methodDescription)
-                {
-                    // We want to process the event here, so that the component and method description are
-                    // properly identified. But that's going to cause a headache aborting the
-                    // event.
-
-                    try
-                    {
-                        _eventResultProcessor.processComponentEvent(result, component, methodDescription);
-                    }
-                    catch (IOException e)
-                    {
-                        throw new RuntimeException(e);
-                    }
-
-                    holder.put(true);
-
-                    return true; // Abort other event processing.
-                }
-            };
-
-            _resources.triggerEvent(PREPARE, context, handler);
+            _resources.triggerEvent(PREPARE, context, callback);
 
-            //
-            if (holder.hasValue()) return holder.get();
+            if (callback.isAborted()) return true;
 
             // TODO: Ajax stuff will eventually mean there are multiple values for this parameter
             // name
@@ -375,9 +344,9 @@
 
             _tracker = tracker;
 
-            _resources.triggerEvent(VALIDATE, context, handler);
+            _resources.triggerEvent(VALIDATE, context, callback);
 
-            if (holder.hasValue()) return holder.get();
+            if (callback.isAborted()) return true;
 
             _formSupport.executeDeferred();
 
@@ -390,15 +359,15 @@
 
             if (!_tracker.getHasErrors()) _tracker.clear();
 
-            _resources.triggerEvent(tracker.getHasErrors() ? FAILURE : SUCCESS, context, handler);
+            _resources.triggerEvent(tracker.getHasErrors() ? FAILURE : SUCCESS, context, callback);
 
             // Lastly, tell anyone whose interested that the form is completely submitted.
 
-            if (holder.hasValue()) return holder.get();
+            if (callback.isAborted()) return true;
 
-            _resources.triggerEvent(SUBMIT, context, handler);
+            _resources.triggerEvent(SUBMIT, context, callback);
 
-            return holder.get();
+            return callback.isAborted();
         }
         finally
         {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java Tue Jan 15 18:33:09 2008
@@ -36,17 +36,16 @@
  * A mixin for a text field that allows for autocompletion of text fields. This is based on Prototype's autocompleter
  * control.
  * <p/>
- * The mixin renders an (initially invisible) progress indicator after the field (it will also be after
- * the error icon most fields render). The progress indicator is made visible during the request to the server.
- * The mixin then renders a &lt;div&gt; that will be filled in on the client
- * side with dynamically obtained selections.
+ * The mixin renders an (initially invisible) progress indicator after the field (it will also be after the error icon
+ * most fields render). The progress indicator is made visible during the request to the server. The mixin then renders
+ * a &lt;div&gt; that will be filled in on the client side with dynamically obtained selections.
  * <p/>
- * Multiple selection on the client is enabled by binding the tokens parameter (however, the mixin doesn't
- * help split multiple selections up on the server, that is still your code's responsibility).
+ * Multiple selection on the client is enabled by binding the tokens parameter (however, the mixin doesn't help split
+ * multiple selections up on the server, that is still your code's responsibility).
  * <p/>
- * The container is responsible for providing an event handler for event "providecompletions".  The context
- * will be the partial input string sent from the client.  The return value should be an array or list of
- * completions, in presentation order.  I.e.
+ * The container is responsible for providing an event handler for event "providecompletions".  The context will be the
+ * partial input string sent from the client.  The return value should be an array or list of completions, in
+ * presentation order.  I.e.
  * <p/>
  * <pre>
  * String[] onProvideCompletionsFromMyField(String input)
@@ -101,15 +100,15 @@
 
 
     /**
-     * Overrides the default check frequency for determining whether to send a server request.
-     * The default is .4 seconds.
+     * Overrides the default check frequency for determining whether to send a server request. The default is .4
+     * seconds.
      */
     @Parameter(defaultPrefix = "literal")
     private double _frequency;
 
     /**
-     * If given, then the autocompleter will support multiple input values, seperated by
-     * any of the individual characters in the string.
+     * If given, then the autocompleter will support multiple input values, seperated by any of the individual
+     * characters in the string.
      */
     @Parameter(defaultPrefix = "literal")
     private String _tokens;
@@ -120,8 +119,8 @@
     }
 
     /**
-     * Mixin afterRender phrase occurs after the component itself. This is where we write the &lt;div&gt;
-     * element and the JavaScript.
+     * Mixin afterRender phrase occurs after the component itself. This is where we write the &lt;div&gt; element and
+     * the JavaScript.
      *
      * @param writer
      */
@@ -185,7 +184,7 @@
 
         matchesHolder.put(Collections.emptyList());
 
-        ComponentEventHandler handler = new ComponentEventHandler()
+        ComponentEventCallback callback = new ComponentEventCallback()
         {
             public boolean handleResult(Object result, Component component, String methodDescription)
             {
@@ -197,7 +196,7 @@
             }
         };
 
-        _resources.triggerEvent("providecompletions", new Object[]{input}, handler);
+        _resources.triggerEvent("providecompletions", new Object[]{input}, callback);
 
         ContentType contentType = _responseRenderer.findContentType(this);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -46,6 +46,13 @@
      * The name of the query parameter that stores the page activation context inside an action request.
      */
     public static final String PAGE_CONTEXT_NAME = "t:ac";
+
+    /**
+     * The name of a query parameter that stores the active page (used in action links when the page containing the
+     * component is not the same as the page that was rendering).
+     */
+    public static final String ACTIVE_PAGE_NAME = "t:ap";
+
 
     public static final String OBJECT_RENDER_DIV_SECTION = "t-env-data-section";
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -14,112 +14,74 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.ContentType;
 import org.apache.tapestry.TapestryConstants;
 import org.apache.tapestry.internal.InternalConstants;
 import org.apache.tapestry.internal.structure.ComponentPageElement;
 import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.internal.util.Holder;
 import org.apache.tapestry.json.JSONObject;
-import org.apache.tapestry.runtime.Component;
 import org.apache.tapestry.services.*;
 
 import java.io.IOException;
 
 /**
- * Similar to {@link ComponentActionRequestHandlerImpl}, but built around the Ajax request cycle, where the action request
- * sends back an immediate JSON response containing the new content.
+ * Similar to {@link ComponentActionRequestHandlerImpl}, but built around the Ajax request cycle, where the action
+ * request sends back an immediate JSON response containing the new content.
  */
 public class AjaxComponentActionRequestHandler implements ComponentActionRequestHandler
 {
     private final RequestPageCache _cache;
 
-    private final MarkupWriterFactory _factory;
-
-    private final AjaxPartialResponseRenderer _renderer;
-
     private final Request _request;
 
-    private final Response _response;
-
     private final PageRenderQueue _queue;
 
     private final ComponentEventResultProcessor _resultProcessor;
 
     private final PageContentTypeAnalyzer _pageContentTypeAnalyzer;
 
-    public AjaxComponentActionRequestHandler(RequestPageCache cache, MarkupWriterFactory factory,
-                                             AjaxPartialResponseRenderer renderer, Request request, Response response,
-                                             PageRenderQueue queue, @Ajax ComponentEventResultProcessor resultProcessor,
+    public AjaxComponentActionRequestHandler(RequestPageCache cache, Request request, PageRenderQueue queue,
+                                             @Ajax ComponentEventResultProcessor resultProcessor,
                                              PageContentTypeAnalyzer pageContentTypeAnalyzer)
     {
         _cache = cache;
-        _factory = factory;
-        _renderer = renderer;
-        _response = response;
         _queue = queue;
         _resultProcessor = resultProcessor;
         _pageContentTypeAnalyzer = pageContentTypeAnalyzer;
         _request = request;
     }
 
-    public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                       String[] activationContext) throws IOException
+    public void handle(ComponentActionRequestParameters parameters) throws IOException
     {
-        Page page = _cache.get(logicalPageName);
+        Page activePage = _cache.get(parameters.getActivePageName());
 
-        // 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).
-
-        _queue.initializeForCompletePage(page);
+        ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(_resultProcessor);
 
-        ContentType contentType = _pageContentTypeAnalyzer.findContentType(page);
+        activePage.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT,
+                                                 parameters.getPageActivationContext(), callback);
 
-        _request.setAttribute(InternalConstants.CONTENT_TYPE_ATTRIBUTE_NAME, contentType);
+        if (callback.isAborted()) return;
 
-        ComponentPageElement element = page.getComponentElementByNestedId(nestedComponentId);
-
-        final Holder<Boolean> holder = Holder.create();
-        final Holder<IOException> exceptionHolder = Holder.create();
-
-        ComponentEventHandler handler = new ComponentEventHandler()
-        {
-            @SuppressWarnings("unchecked")
-            public boolean handleResult(Object result, Component component, String methodDescription)
-            {
-                try
-                {
-                    _resultProcessor.processComponentEvent(result, component, methodDescription);
-                }
-                catch (IOException ex)
-                {
-                    // Jump through some hoops to escape this block, which doesn't
-                    // declare IOException
-                    exceptionHolder.put(ex);
-                }
-
-                holder.put(true);
+        // 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).
 
-                return true;
-            }
-        };
+        _queue.initializeForCompletePage(activePage);
 
-        page.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT, activationContext, handler);
+        ContentType contentType = _pageContentTypeAnalyzer.findContentType(activePage);
 
-        if (exceptionHolder.hasValue()) throw exceptionHolder.get();
+        _request.setAttribute(InternalConstants.CONTENT_TYPE_ATTRIBUTE_NAME, contentType);
 
-        if (holder.hasValue()) return;
+        Page containerPage = _cache.get(parameters.getContainingPageName());
 
-        element.triggerEvent(eventType, context, handler);
+        ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
 
-        if (exceptionHolder.hasValue()) throw exceptionHolder.get();
+        element.triggerEvent(parameters.getEventType(), parameters.getEventContext(), callback);
 
-        if (holder.hasValue()) return;
+        if (callback.isAborted()) return;
 
         JSONObject reply = new JSONObject();
 
-        _resultProcessor.processComponentEvent(reply, null, null);
+        _resultProcessor.processResultValue(reply, null, null);
 
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -36,7 +36,7 @@
         _cache = cache;
     }
 
-    public void processComponentEvent(Component value, Component component, String methodDescripion) throws IOException
+    public void processResultValue(Component value, Component component, String methodDescripion) throws IOException
     {
         ComponentResources resources = value.getComponentResources();
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -14,17 +14,13 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.services.Ajax;
-import org.apache.tapestry.services.ComponentActionRequestFilter;
-import org.apache.tapestry.services.ComponentActionRequestHandler;
-import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.*;
 
 import java.io.IOException;
 
 /**
- * A filter that intercepts Ajax-oriented requests, thos that originate on the client-side using
- * XmlHttpRequest. In these cases, the action processing occurs normally, but the response is quite
- * different.
+ * A filter that intercepts Ajax-oriented requests, thos that originate on the client-side using XmlHttpRequest. In
+ * these cases, the action processing occurs normally, but the response is quite different.
  */
 public class AjaxFilter implements ComponentActionRequestFilter
 {
@@ -38,13 +34,12 @@
         _ajaxHandler = ajaxHandler;
     }
 
-
-    public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                       String[] activationContext, ComponentActionRequestHandler handler) throws IOException
+    public void handle(ComponentActionRequestParameters parameters, ComponentActionRequestHandler handler)
+            throws IOException
     {
         ComponentActionRequestHandler next = _request.isXHR() ? _ajaxHandler : handler;
 
-        next.handle(logicalPageName, nestedComponentId, eventType, context, activationContext);
+        next.handle(parameters);
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java Tue Jan 15 18:33:09 2008
@@ -41,7 +41,7 @@
         _generator = generator;
     }
 
-    public void processComponentEvent(Class value, Component component, String methodDescripion) throws IOException
+    public void processResultValue(Class value, Component component, String methodDescripion) throws IOException
     {
         String className = value.getName();
         String pageName = _resolver.resolvePageClassNameToPageName(className);

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -24,24 +24,21 @@
 import java.util.regex.Pattern;
 
 /**
- * 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.
+ * 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.
  * <p/>
  * <p/>
- * Forms:
- * <ul>
- * <li>/context/pagename:eventname -- event on the page, no action context</li>
+ * Forms: <ul> <li>/context/pagename:eventname -- event on the page, no action context</li>
  * <li>/context/pagename:eventname/foo/bar -- event on the page with action context "foo", "bar"</li>
  * <li>/context/pagename.foo.bar -- event on component foo.bar within the page, default event, no action context</li>
- * <li>/context/pagename.foo.bar/baz.gnu -- event on component foo.bar within the page, default event, with action context "baz", "gnu"</li>
- * <li>/context/pagename.bar.baz:eventname/foo/gnu -- event on component bar.baz within the page with action context "foo"
- * , "gnu"</li>
- * </ul>
+ * <li>/context/pagename.foo.bar/baz.gnu -- event on component foo.bar within the page, default event, with action
+ * context "baz", "gnu"</li> <li>/context/pagename.bar.baz:eventname/foo/gnu -- event on component bar.baz within the
+ * page with action context "foo" , "gnu"</li> </ul>
  * <p/>
  * <p/>
- * The page name portion may itself consist of a series of folder names, i.e., "admin/user/create".  The context portion isn't the concern
- * of this code, since {@link org.apache.tapestry.services.Request#getPath()} will already have stripped that off.  We can act as if the context is
- * always "/" (the path always starts with a slash).
+ * The page name portion may itself consist of a series of folder names, i.e., "admin/user/create".  The context portion
+ * isn't the concern of this code, since {@link org.apache.tapestry.services.Request#getPath()} will already have
+ * stripped that off.  We can act as if the context is always "/" (the path always starts with a slash).
  * <p/>
  * <p/>
  *
@@ -99,7 +96,7 @@
 
         if (!matcher.matches()) return false;
 
-        String logicalPageName = matcher.group(LOGICAL_PAGE_NAME);
+        String containingPageName = matcher.group(LOGICAL_PAGE_NAME);
 
         String nestedComponentId = matcher.group(NESTED_ID);
 
@@ -107,7 +104,7 @@
 
         if (nestedComponentId == null && eventType == null) return false;
 
-        if (!_componentClassResolver.isPageName(logicalPageName)) return false;
+        if (!_componentClassResolver.isPageName(containingPageName)) return false;
 
         String[] eventContext = decodeContext(matcher.group(CONTEXT));
 
@@ -122,8 +119,18 @@
 
         if (nestedComponentId == null) nestedComponentId = "";
 
-        _componentActionRequestHandler.handle(logicalPageName, nestedComponentId, eventType, eventContext,
-                                              activationContext);
+        String activePageName = request.getParameter(InternalConstants.ACTIVE_PAGE_NAME);
+
+        if (activePageName == null) activePageName = containingPageName;
+
+
+        ComponentActionRequestParameters parameters = new ComponentActionRequestParameters(activePageName,
+                                                                                           containingPageName,
+                                                                                           nestedComponentId, eventType,
+                                                                                           activationContext,
+                                                                                           eventContext);
+
+        _componentActionRequestHandler.handle(parameters);
 
         return true;
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java Tue Jan 15 18:33:09 2008
@@ -14,16 +14,10 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.TapestryConstants;
 import org.apache.tapestry.internal.structure.ComponentPageElement;
 import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.internal.util.Holder;
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.services.ComponentActionRequestHandler;
-import org.apache.tapestry.services.ComponentEventResultProcessor;
-import org.apache.tapestry.services.Response;
-import org.apache.tapestry.services.Traditional;
+import org.apache.tapestry.services.*;
 
 import java.io.IOException;
 
@@ -47,53 +41,28 @@
         _generator = generator;
     }
 
-    public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                       String[] activationContext) throws IOException
+    public void handle(ComponentActionRequestParameters parameters) throws IOException
     {
-        Page page = _cache.get(logicalPageName);
+        Page activePage = _cache.get(parameters.getActivePageName());
 
-        // This is the active page, until we know better.
-
-        ComponentPageElement element = page.getComponentElementByNestedId(nestedComponentId);
-
-        final Holder<Boolean> holder = Holder.create();
-        final Holder<IOException> exceptionHolder = Holder.create();
-
-        ComponentEventHandler handler = new ComponentEventHandler()
-        {
-            @SuppressWarnings("unchecked")
-            public boolean handleResult(Object result, Component component, String methodDescription)
-            {
-                try
-                {
-                    _resultProcessor.processComponentEvent(result, component, methodDescription);
-                }
-                catch (IOException ex)
-                {
-                    exceptionHolder.put(ex);
-                }
-
-                holder.put(true);
-
-                return true;
-            }
-        };
+        ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(_resultProcessor);
 
         // If activating the page returns a "navigational result", then don't trigger the action
         // on the component.
 
-        page.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT, activationContext, handler);
+        activePage.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT,
+                                                 parameters.getPageActivationContext(), callback);
 
-        if (exceptionHolder.hasValue()) throw exceptionHolder.get();
+        if (callback.isAborted()) return;
 
-        if (holder.hasValue()) return;
+        Page containerPage = _cache.get(parameters.getContainingPageName());
 
-        element.triggerEvent(eventType, context, handler);
+        ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
 
-        if (exceptionHolder.hasValue()) throw exceptionHolder.get();
+        element.triggerEvent(parameters.getEventType(), parameters.getEventContext(), callback);
 
-        if (holder.hasValue()) return;
+        if (callback.isAborted()) return;
 
-        if (!_response.isCommitted()) _generator.generateResponse(page);
+        if (!_response.isCommitted()) _generator.generateResponse(activePage);
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java Tue Jan 15 18:33:09 2008
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.ComponentEventCallback;
 import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.runtime.ComponentEvent;
 
@@ -38,11 +38,12 @@
      *                               parameters
      * @param handler                invoked when a non-null return value is obtained from an event handler method
      * @param typeCoercer            used when coercing context values to parameter types
-     * @param classLoader            loader used when resolving a class name to a class  (ultimately, this
-     *                               is the class loader used to create the component class; that loader's parent is the Thread's context class loader).
+     * @param classLoader            loader used when resolving a class name to a class  (ultimately, this is the class
+     *                               loader used to create the component class; that loader's parent is the Thread's
+     *                               context class loader).
      */
     public ComponentEventImpl(String eventType, String originatingComponentId, Object[] context,
-                              ComponentEventHandler handler, TypeCoercer typeCoercer,
+                              ComponentEventCallback handler, TypeCoercer typeCoercer,
                               ComponentClassCache componentClassCache)
     {
         super(handler);

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java Tue Jan 15 18:33:09 2008
@@ -38,7 +38,7 @@
         _generator = generator;
     }
 
-    public void processComponentEvent(Component value, Component component, String methodDescription) throws IOException
+    public void processResultValue(Component value, Component component, String methodDescription) throws IOException
     {
         ComponentResources resources = value.getComponentResources();
 

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java?rev=612337&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java Tue Jan 15 18:33:09 2008
@@ -0,0 +1,69 @@
+// Copyright 2008 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.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+
+/**
+ * A wrapper around {@link ComponentEventResultProcessor} that encapsulates capturing the exception.
+ */
+public class ComponentResultProcessorWrapper implements ComponentEventCallback
+{
+    private boolean _aborted;
+
+    private IOException _exception;
+
+    private final ComponentEventResultProcessor _processor;
+
+    public ComponentResultProcessorWrapper(ComponentEventResultProcessor processor)
+    {
+        _processor = processor;
+    }
+
+    public boolean handleResult(Object result, Component component, String methodDescription)
+    {
+        try
+        {
+            _processor.processResultValue(result, component, methodDescription);
+        }
+        catch (IOException ex)
+        {
+            _exception = ex;
+        }
+
+        _aborted = true;
+
+        return true;
+    }
+
+    /**
+     * Returns true if {@link #handleResult(Object, org.apache.tapestry.runtime.Component, String)} was invoked, false
+     * otherwise.
+     *
+     * @return true if the event was aborted
+     * @throws IOException if {@link ComponentEventResultProcessor#processResultValue(Object,
+     *                     org.apache.tapestry.runtime.Component, String)} threw an IOException
+     */
+    public boolean isAborted() throws IOException
+    {
+        if (_exception != null) throw _exception;
+
+        return _aborted;
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.ComponentEventCallback;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
 import org.apache.tapestry.runtime.Component;
 import org.apache.tapestry.runtime.Event;
@@ -27,9 +27,9 @@
 
     private String _methodDescription;
 
-    private final ComponentEventHandler _handler;
+    private final ComponentEventCallback _handler;
 
-    public EventImpl(ComponentEventHandler handler)
+    public EventImpl(ComponentEventCallback handler)
     {
         _handler = notNull(handler, "handler");
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -41,7 +41,7 @@
     {
         final Holder<String> resultHolder = Holder.create();
 
-        ComponentEventHandler handler = new ComponentEventHandler()
+        ComponentEventCallback callback = new ComponentEventCallback()
         {
             public boolean handleResult(Object result, Component component, String methodDescription)
             {
@@ -57,7 +57,7 @@
             }
         };
 
-        componentResources.triggerEvent(TO_CLIENT_EVENT, new Object[]{value}, handler);
+        componentResources.triggerEvent(TO_CLIENT_EVENT, new Object[]{value}, callback);
 
         if (resultHolder.hasValue()) return resultHolder.get();
 
@@ -70,7 +70,7 @@
     {
         final Holder<Object> resultHolder = Holder.create();
 
-        ComponentEventHandler handler = new ComponentEventHandler()
+        ComponentEventCallback callback = new ComponentEventCallback()
         {
             public boolean handleResult(Object result, Component component, String methodDescription)
             {
@@ -81,7 +81,7 @@
 
         try
         {
-            componentResources.triggerEvent(PARSE_CLIENT_EVENT, new Object[]{clientValue}, handler);
+            componentResources.triggerEvent(PARSE_CLIENT_EVENT, new Object[]{clientValue}, callback);
         }
         catch (ComponentEventException ex)
         {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java Tue Jan 15 18:33:09 2008
@@ -17,10 +17,7 @@
 import org.apache.tapestry.TapestryConstants;
 import org.apache.tapestry.internal.InternalConstants;
 import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.services.ComponentActionRequestFilter;
-import org.apache.tapestry.services.ComponentActionRequestHandler;
-import org.apache.tapestry.services.Request;
-import org.apache.tapestry.services.Response;
+import org.apache.tapestry.services.*;
 
 import java.io.IOException;
 
@@ -39,10 +36,10 @@
         _response = response;
     }
 
-    public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                       String[] activationContext, ComponentActionRequestHandler handler) throws IOException
+    public void handle(ComponentActionRequestParameters parameters, ComponentActionRequestHandler handler)
+            throws IOException
     {
-        handler.handle(logicalPageName, nestedComponentId, eventType, context, activationContext);
+        handler.handle(parameters);
 
         // If markup or a redirect has already been generated, then we're good.
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -24,9 +24,9 @@
 
 
 /**
- * Implemention of {@link ComponentEventResultProcessor} for {@link org.apache.tapestry.json.JSONObject}, allowing
- * a component event handler to return a JSONObject that will be sent directly to the client as the reply.
- * This is often used with custom components that need a custom JSON response.
+ * Implemention of {@link ComponentEventResultProcessor} for {@link org.apache.tapestry.json.JSONObject}, allowing a
+ * component event handler to return a JSONObject that will be sent directly to the client as the reply. This is often
+ * used with custom components that need a custom JSON response.
  */
 public class JSONObjectEventResultProcessor implements ComponentEventResultProcessor<JSONObject>
 {
@@ -37,7 +37,7 @@
         _response = response;
     }
 
-    public void processComponentEvent(JSONObject value, Component component, String methodDescripion) throws IOException
+    public void processResultValue(JSONObject value, Component component, String methodDescripion) throws IOException
     {
         PrintWriter pw = _response.getPrintWriter("text/javascript");
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java Tue Jan 15 18:33:09 2008
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.ComponentEventCallback;
 import org.apache.tapestry.Link;
 import org.apache.tapestry.TapestryConstants;
 import org.apache.tapestry.internal.InternalConstants;
@@ -49,6 +49,8 @@
 
     private final RequestPathOptimizer _optimizer;
 
+    private final PageRenderQueue _pageRenderQueue;
+
     private final List<LinkFactoryListener> _listeners = newThreadSafeList();
 
     private final StrategyRegistry<PassivateContextHandler> _registry;
@@ -69,7 +71,9 @@
 
                            TypeCoercer typeCoercer,
 
-                           RequestPathOptimizer optimizer)
+                           RequestPathOptimizer optimizer,
+
+                           PageRenderQueue pageRenderQueue)
     {
         _request = request;
         _response = encoder;
@@ -77,6 +81,7 @@
         _pageCache = pageCache;
         _typeCoercer = typeCoercer;
         _optimizer = optimizer;
+        _pageRenderQueue = pageRenderQueue;
 
         Map<Class, PassivateContextHandler> registrations = newMap();
 
@@ -127,18 +132,24 @@
 
         String[] contextStrings = toContextStrings(context);
 
-        String[] activationContext = collectActivationContextForPage(page);
+        Page activePage = _pageRenderQueue.getRenderingPage();
+
+        String[] activationContext = collectActivationContextForPage(activePage);
 
         ComponentInvocation invocation = new ComponentInvocationImpl(target, contextStrings, activationContext);
 
         Link link = new LinkImpl(_response, _optimizer, _request.getContextPath(), invocation, forForm);
 
+        // TAPESTRY-2044: Sometimes the active page drags in components from another page and we
+        // need to differentiate that.
+
+        if (activePage != page)
+            link.addParameter(InternalConstants.ACTIVE_PAGE_NAME, activePage.getLogicalName().toLowerCase());
+
         // Now see if the page has an activation context.
 
         addActivationContextToLink(link, activationContext);
 
-        // TODO: query parameter for case where active page != component page.
-
         _componentInvocationMap.store(link, invocation);
 
         for (LinkFactoryListener listener : _listeners)
@@ -189,14 +200,14 @@
     }
 
     /**
-     * Returns a list of objects acquired by invoking triggering the passivate event on the page's
-     * root element. May return an empty list.
+     * Returns a list of objects acquired by invoking triggering the passivate event on the page's root element. May
+     * return an empty list.
      */
     private String[] collectActivationContextForPage(final Page page)
     {
         final List context = newList();
 
-        ComponentEventHandler handler = new ComponentEventHandler()
+        ComponentEventCallback callback = new ComponentEventCallback()
         {
             @SuppressWarnings("unchecked")
             public boolean handleResult(Object result, Component component, String methodDescription)
@@ -211,7 +222,7 @@
 
         ComponentPageElement rootElement = page.getRootElement();
 
-        rootElement.triggerEvent(TapestryConstants.PASSIVATE_EVENT, null, handler);
+        rootElement.triggerEvent(TapestryConstants.PASSIVATE_EVENT, null, callback);
 
         return toContextStrings(context.toArray());
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -33,7 +33,7 @@
         _configuredClasses = configuredClasses;
     }
 
-    public void processComponentEvent(Object value, Component component, String methodDescripion) throws IOException
+    public void processResultValue(Object value, Component component, String methodDescripion) throws IOException
     {
         String message = ServicesMessages.invalidComponentEventResult(component, value, methodDescripion,
                                                                       _configuredClasses);

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -21,10 +21,9 @@
 
 
 /**
- * A wrapper around {@link org.apache.tapestry.runtime.RenderQueue}, but referencable as
- * a (per-thread) service.     This service is scoped so that we can tell it what to render
- * in one method, then have it do the render in another. Part of an elaborate
- * scheme to keep certain interfaces public and other closely related ones private.
+ * A wrapper around {@link org.apache.tapestry.runtime.RenderQueue}, but referencable as a (per-thread) service. This
+ * service is scoped so that we can tell it what to render in one method, then have it do the render in another. Part of
+ * an elaborate scheme to keep certain interfaces public and other closely related ones private.
  */
 public interface PageRenderQueue
 {
@@ -32,6 +31,11 @@
      * Initializes the queue for rendering of a complete page.
      */
     void initializeForCompletePage(Page page);
+
+    /**
+     * Returns the page that is rendering markup content.
+     */
+    Page getRenderingPage();
 
     /**
      * Initializes the queue for rendering of a portion of a page.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java?rev=612337&r1=612336&r2=612337&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java Tue Jan 15 18:33:09 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -24,8 +24,8 @@
 
 /**
  * This services keeps track of the page being rendered and the root command for the partial render, it is therefore
- * request/thread scoped.  There's a filter pipeline around the rendering, and that gets to be stateless because this service,
- * at the end of the pipeline, is stateful.
+ * request/thread scoped.  There's a filter pipeline around the rendering, and that gets to be stateless because this
+ * service, at the end of the pipeline, is stateful.
  */
 @Scope(PERTHREAD_SCOPE)
 public class PageRenderQueueImpl implements PageRenderQueue
@@ -45,6 +45,11 @@
         if (_page == null) throw new IllegalStateException("Page must be specified before root render command.");
 
         _rootCommand = rootCommand;
+    }
+
+    public Page getRenderingPage()
+    {
+        return _page;
     }
 
     public void render(MarkupWriter writer)