You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/11/20 22:10:28 UTC
svn commit: r477336 - in /tapestry/tapestry5/tapestry-core/trunk: ./
src/main/java/org/apache/tapestry/
src/main/java/org/apache/tapestry/corelib/components/
src/main/java/org/apache/tapestry/internal/bindings/
src/main/java/org/apache/tapestry/interna...
Author: hlship
Date: Mon Nov 20 13:10:27 2006
New Revision: 477336
URL: http://svn.apache.org/viewvc?view=rev&rev=477336
Log:
Add events for passivating page state (into render URLs) and activating pages (to restore page state from the context).
Added:
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.html
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.html
Modified:
tapestry/tapestry5/tapestry-core/trunk/pom.xml
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentEventHandler.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryConstants.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/StringEventHandler.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
Modified: tapestry/tapestry5/tapestry-core/trunk/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/pom.xml?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/pom.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/pom.xml Mon Nov 20 13:10:27 2006
@@ -131,10 +131,4 @@
</plugin>
</plugins>
</reporting>
- <distributionManagement>
- <site>
- <id>tapestry</id>
- <url>scpexe://apache.org/www/tapestry.apache.org/tapestry5</url>
- </site>
- </distributionManagement>
</project>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentEventHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentEventHandler.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentEventHandler.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentEventHandler.java Mon Nov 20 13:10:27 2006
@@ -12,31 +12,31 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry;
-
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.runtime.ComponentEvent;
-
-/**
- * Handler for a {@link ComponentEvent}, notified when a non-null value is returned from some event
- * handler method.
- * <p>
- * TODO: Allow handler to return boolean (abort vs. don't abort)
- * <p>
- * TODO: Multiple handlers for different result types / strategy pattern?
- */
-public interface ComponentEventHandler<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.
- *
- * @param result
- * the result value provided by a method
- * @param component
- * the component from which the result was obtained
- * @param methodDescription
- * a string description of the class and method name (used when errors occur).
- */
- void handleResult(T result, Component component, String methodDescription);
-}
+package org.apache.tapestry;
+
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.ComponentEvent;
+
+/**
+ * Handler for a {@link ComponentEvent}, notified when a non-null value is returned from some event
+ * handler method.
+ * <p>
+ * TODO: Allow handler to return boolean (abort vs. don't abort)
+ * <p>
+ * TODO: Multiple handlers for different result types / strategy pattern?
+ */
+public interface ComponentEventHandler<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.
+ *
+ * @param result
+ * the result value provided by a method
+ * @param component
+ * the component from which the result was obtained
+ * @param methodDescription
+ * a string description of the class and method name (used when errors occur).
+ */
+ void handleResult(T result, Component component, String methodDescription);
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java Mon Nov 20 13:10:27 2006
@@ -12,85 +12,88 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry;
-
-import org.apache.commons.logging.Log;
-import org.apache.tapestry.internal.structure.ComponentPageElement;
-import org.apache.tapestry.model.ComponentModel;
-import org.apache.tapestry.services.ComponentSource;
-
-/**
- * Operations shared by {@link ComponentResources} and {@link ComponentPageElement}.
- */
-public interface ComponentResourcesCommon
-{
- /**
- * 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. I.e., "foo.bar.baz". Returns null for a page.
- */
-
- String getNestedId();
-
- /**
- * Creates a link that will trigger an action for this component.
- *
- * @param action
- * a name for the action associated with the link
- * @param forForm
- * if true, the link will be used as the action 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 an URI encoded
- */
- Link createActionLink(String action, boolean forForm, Object... context);
-
- /**
- * Returns a string consisting of the fully qualified class name of the containing page, and the
- * {@link #getNestedId() nested id} of this component, separated by a colon. I.e.,
- * "com.foo.pages.MyPage:foo.bar.baz". For a page, returns just the page class name.
- * <p>
- * This value is often used to obtain an equivalent component instance in a later request.
- *
- * @see ComponentSource
- */
-
- 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.
- *
- * @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
- * @param handler
- * the handler to be informed of the result
- * @return true if any event handler was invoked (even if no event handler method returns a
- * non-null value)
- */
- boolean triggerEvent(String eventType, Object[] context, ComponentEventHandler handler);
-
- /**
- * 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).
- *
- * @see ComponentModel#getLog()
- */
- Log getLog();
-}
+package org.apache.tapestry;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ComponentSource;
+
+/**
+ * Operations shared by {@link ComponentResources} and {@link ComponentPageElement}.
+ */
+public interface ComponentResourcesCommon
+{
+ /**
+ * 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. I.e., "foo.bar.baz". Returns null for a page.
+ */
+
+ String getNestedId();
+
+ /**
+ * Creates a link that will trigger an action for this component.
+ *
+ * @param action
+ * a name for the action associated with the link
+ * @param forForm
+ * if true, the link will be used as the action 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 an URI encoded
+ */
+ Link createActionLink(String action, boolean forForm, Object... context);
+
+ /**
+ * Returns a string consisting of the fully qualified class name of the containing page, and the
+ * {@link #getNestedId() nested id} of this component, separated by a colon. I.e.,
+ * "com.foo.pages.MyPage:foo.bar.baz". For a page, returns just the page class name.
+ * <p>
+ * This value is often used to obtain an equivalent component instance in a later request.
+ *
+ * @see ComponentSource
+ */
+
+ 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 vavlue).
+ *
+ * @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
+ * @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
+ * @return true if any event handler was invoked (even if no event handler method returns a
+ * non-null value)
+ */
+ boolean triggerEvent(String eventType, Object[] context, ComponentEventHandler handler);
+
+ /**
+ * 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).
+ *
+ * @see ComponentModel#getLog()
+ */
+ Log getLog();
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryConstants.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryConstants.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryConstants.java Mon Nov 20 13:10:27 2006
@@ -12,17 +12,32 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry;
-
-/**
- * Collection of common constant values used throughout Tapestry.
- */
-public final class TapestryConstants
-{
- /** Default client event name, used in most situations. */
- public static final String DEFAULT_EVENT = "action";
-
- private TapestryConstants()
- {
- }
-}
+package org.apache.tapestry;
+
+/**
+ * Collection of common constant values used throughout Tapestry.
+ */
+public final class TapestryConstants
+{
+ /** Default client event name, used in most situations. */
+ public static final String DEFAULT_EVENT = "action";
+
+ /**
+ * Event triggered when a page is activated (for rendering). The component event handler will be
+ * passed the context provided by the passivate event.
+ */
+
+ public static final String ACTIVATE_EVENT = "activate";
+
+ /**
+ * Event triggered when a link for a page is generated. The event handler for the page may
+ * provide an object, or an array of objects, as the context for the page. These values will
+ * become part of the page's context, and will be provided back when the page is activated.
+ */
+
+ public static final String PASSIVATE_EVENT = "passivate";
+
+ private TapestryConstants()
+ {
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java Mon Nov 20 13:10:27 2006
@@ -12,207 +12,195 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.corelib.components;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-import org.apache.tapestry.ComponentAction;
-import org.apache.tapestry.ComponentEventHandler;
-import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.Link;
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.TapestryConstants;
-import org.apache.tapestry.annotations.AfterRender;
-import org.apache.tapestry.annotations.BeginRender;
-import org.apache.tapestry.annotations.CleanupRender;
-import org.apache.tapestry.annotations.ComponentClass;
-import org.apache.tapestry.annotations.Environmental;
-import org.apache.tapestry.annotations.Inject;
-import org.apache.tapestry.annotations.Mixin;
-import org.apache.tapestry.annotations.OnEvent;
-import org.apache.tapestry.annotations.SetupRender;
-import org.apache.tapestry.corelib.mixins.RenderInformals;
-import org.apache.tapestry.dom.Element;
-import org.apache.tapestry.internal.util.AcceptVoidEventHandler;
-import org.apache.tapestry.internal.util.Base64ObjectInputStream;
-import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.services.ComponentSource;
-import org.apache.tapestry.services.Environment;
-import org.apache.tapestry.services.FormSupport;
-import org.apache.tapestry.services.PageRenderSupport;
-import org.apache.tapestry.services.WebRequest;
-
-/**
- * An HTML form, which will enclose other components to render out the various types of fields.
- */
-@ComponentClass
-public class Form
-{
- /**
- * Invoked to let the containing component(s) prepare for the form rendering or the form
- * submission.
- */
- public static final String PREPARE_EVENT = "prepare";
-
- /** Event type for a notification after the form has submitted. */
- public static final String SUBMIT = "submit";
-
- /**
- * Query parameter name storing form data (the serialized commands needed to process a form
- * submission).
- */
- public static final String FORM_DATA = "t:formdata";
-
- @Inject("infrastructure:environment")
- private Environment _environment;
-
- @Inject
- private ComponentResources _resources;
-
- @Environmental
- private PageRenderSupport _pageRenderSupport;
-
- @Inject("infrastructure:request")
- private WebRequest _request;
-
- @Inject("infrastructure:componentSource")
- private ComponentSource _source;
-
- // Collects a stream of component actions. Each action goes in as a UTF string (the component
- // component id),
- // followed by a ComponentAction
-
- private Base64ObjectOutputStream _actions;
-
-
- @SuppressWarnings("unused")
- @Mixin
- private RenderInformals _renderInformals;
-
- @SetupRender
- void setup()
- {
- try
- {
- _actions = new Base64ObjectOutputStream();
- }
- catch (IOException ex)
- {
- throw new RuntimeException(ex);
- }
-
- FormSupport support = new FormSupportImpl(_actions);
-
- // TODO: Forms should not allow to nest. Perhaps a set() method instead of a push() method
- // for this kind of check?
-
- _environment.push(FormSupport.class, support);
-
- // Now that the environment is setup.
-
- fireNotification(PREPARE_EVENT);
- }
-
- private void fireNotification(String eventType)
- {
- // Use the handler that rejects all non-null return values.
-
- ComponentEventHandler handler = new AcceptVoidEventHandler(eventType, _resources
- .getCompleteId());
-
- _resources.triggerEvent(eventType, null, handler);
- }
-
- private Element _div;
-
- @BeginRender
- void begin(MarkupWriter writer)
- {
- String name = _pageRenderSupport.allocateClientId(_resources.getId());
-
- Link link = _resources.createActionLink(TapestryConstants.DEFAULT_EVENT, true);
-
- writer.element("form", "name", name, "id", name, "method", "post", "action", link
- .toFormURI());
-
- // TODO: Informal parameters
-
- _div = writer.element("div", "style", "invisible");
-
- for (String parameterName : link.getParameterNames())
- {
- String value = link.getParameterValue(parameterName);
-
- writer.element("input", "type", "hidden", "name", parameterName, "value", value);
- writer.end();
- }
-
- writer.end(); // div
-
- }
-
- @AfterRender
- void after(MarkupWriter writer)
- {
- writer.end(); // form
-
- // Now, inject into the div the remaining hidden field (the list of actions).
-
- try
- {
- _actions.close();
- }
- catch (IOException ex)
- {
- throw new RuntimeException(ex);
- }
-
- _div.element("input", "type", "hidden", "name", FORM_DATA, "value", _actions.toBase64());
- }
-
- @CleanupRender
- void cleanup()
- {
- _environment.pop(FormSupport.class);
- }
-
- @SuppressWarnings("unchecked")
- @OnEvent("action")
- void onSubmit()
- {
- // TODO: Ajax stuff will eventually mean there are multiple values for this parameter name
-
- String actionsBase64 = _request.getParameter(FORM_DATA);
-
- try
- {
- ObjectInputStream ois = new Base64ObjectInputStream(actionsBase64);
-
- while (true)
- {
- String componentId = ois.readUTF();
- ComponentAction action = (ComponentAction) ois.readObject();
-
- Component component = _source.getComponent(componentId);
-
- action.execute(component);
- }
- }
- catch (EOFException ex)
- {
- // Expected.
- }
- catch (Exception ex)
- {
- throw new RuntimeException(ex);
- }
-
- // TODO: The return value should be used to control what renders.
-
- fireNotification(SUBMIT);
- }
-
-}
+package org.apache.tapestry.corelib.components;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.annotations.AfterRender;
+import org.apache.tapestry.annotations.BeginRender;
+import org.apache.tapestry.annotations.CleanupRender;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.Mixin;
+import org.apache.tapestry.annotations.OnEvent;
+import org.apache.tapestry.annotations.SetupRender;
+import org.apache.tapestry.corelib.mixins.RenderInformals;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.util.Base64ObjectInputStream;
+import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.PageRenderSupport;
+import org.apache.tapestry.services.WebRequest;
+
+/**
+ * An HTML form, which will enclose other components to render out the various types of fields.
+ */
+@ComponentClass
+public class Form
+{
+ /**
+ * Invoked to let the containing component(s) prepare for the form rendering or the form
+ * submission.
+ */
+ public static final String PREPARE_EVENT = "prepare";
+
+ /** Event type for a notification after the form has submitted. */
+ public static final String SUBMIT = "submit";
+
+ /**
+ * Query parameter name storing form data (the serialized commands needed to process a form
+ * submission).
+ */
+ public static final String FORM_DATA = "t:formdata";
+
+ @Inject("infrastructure:environment")
+ private Environment _environment;
+
+ @Inject
+ private ComponentResources _resources;
+
+ @Environmental
+ private PageRenderSupport _pageRenderSupport;
+
+ @Inject("infrastructure:request")
+ private WebRequest _request;
+
+ @Inject("infrastructure:componentSource")
+ private ComponentSource _source;
+
+ // Collects a stream of component actions. Each action goes in as a UTF string (the component
+ // component id),
+ // followed by a ComponentAction
+
+ private Base64ObjectOutputStream _actions;
+
+ @SuppressWarnings("unused")
+ @Mixin
+ private RenderInformals _renderInformals;
+
+ @SetupRender
+ void setup()
+ {
+ try
+ {
+ _actions = new Base64ObjectOutputStream();
+ }
+ catch (IOException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+
+ FormSupport support = new FormSupportImpl(_actions);
+
+ // TODO: Forms should not allow to nest. Perhaps a set() method instead of a push() method
+ // for this kind of check?
+
+ _environment.push(FormSupport.class, support);
+
+ // Now that the environment is setup, inform the component or other listeners that the form is about to
+ // render.
+
+ _resources.triggerEvent(PREPARE_EVENT, null, null);
+ }
+
+ private Element _div;
+
+ @BeginRender
+ void begin(MarkupWriter writer)
+ {
+ String name = _pageRenderSupport.allocateClientId(_resources.getId());
+
+ Link link = _resources.createActionLink(TapestryConstants.DEFAULT_EVENT, true);
+
+ writer.element("form", "name", name, "id", name, "method", "post", "action", link
+ .toFormURI());
+
+ // TODO: Informal parameters
+
+ _div = writer.element("div", "style", "invisible");
+
+ for (String parameterName : link.getParameterNames())
+ {
+ String value = link.getParameterValue(parameterName);
+
+ writer.element("input", "type", "hidden", "name", parameterName, "value", value);
+ writer.end();
+ }
+
+ writer.end(); // div
+
+ }
+
+ @AfterRender
+ void after(MarkupWriter writer)
+ {
+ writer.end(); // form
+
+ // Now, inject into the div the remaining hidden field (the list of actions).
+
+ try
+ {
+ _actions.close();
+ }
+ catch (IOException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+
+ _div.element("input", "type", "hidden", "name", FORM_DATA, "value", _actions.toBase64());
+ }
+
+ @CleanupRender
+ void cleanup()
+ {
+ _environment.pop(FormSupport.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @OnEvent("action")
+ void onSubmit()
+ {
+ // TODO: Ajax stuff will eventually mean there are multiple values for this parameter name
+
+ String actionsBase64 = _request.getParameter(FORM_DATA);
+
+ try
+ {
+ ObjectInputStream ois = new Base64ObjectInputStream(actionsBase64);
+
+ while (true)
+ {
+ String componentId = ois.readUTF();
+ ComponentAction action = (ComponentAction) ois.readObject();
+
+ Component component = _source.getComponent(componentId);
+
+ action.execute(component);
+ }
+ }
+ catch (EOFException ex)
+ {
+ // Expected.
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(ex);
+ }
+
+ // TODO: The return value should be used to control what renders.
+
+ _resources.triggerEvent(SUBMIT, null, null);
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java Mon Nov 20 13:10:27 2006
@@ -96,7 +96,7 @@
return cons.newBindingInstance(target, toString, location);
}
- catch (Exception ex)
+ catch (Throwable ex)
{
throw new TapestryException(ex.getMessage(), location, ex);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PropertyAccessImpl.java Mon Nov 20 13:10:27 2006
@@ -79,7 +79,7 @@
return new ClassPropertyAdapterImpl(forClass, info.getPropertyDescriptors());
}
- catch (Exception ex)
+ catch (Throwable ex)
{
throw new RuntimeException(ex);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java Mon Nov 20 13:10:27 2006
@@ -12,38 +12,38 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal.services;
-
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.services.ComponentSource;
-
-public class ComponentSourceImpl implements ComponentSource
-{
- private final RequestPageCache _pageCache;
-
- public ComponentSourceImpl(RequestPageCache pageCache)
- {
- _pageCache = pageCache;
- }
-
- public Component getComponent(String componentId)
- {
- int colonx = componentId.indexOf(':');
-
- if (colonx < 0)
- {
- Page page = _pageCache.getByClassName(componentId);
-
- return page.getRootElement().getComponent();
- }
-
- String pageName = componentId.substring(0, colonx);
-
- Page page = _pageCache.getByClassName(pageName);
- String nestedId = componentId.substring(colonx + 1);
-
- return page.getComponentElementByNestedId(nestedId).getComponent();
- }
-
-}
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+
+public class ComponentSourceImpl implements ComponentSource
+{
+ private final RequestPageCache _pageCache;
+
+ public ComponentSourceImpl(RequestPageCache pageCache)
+ {
+ _pageCache = pageCache;
+ }
+
+ public Component getComponent(String componentId)
+ {
+ int colonx = componentId.indexOf(':');
+
+ if (colonx < 0)
+ {
+ Page page = _pageCache.getByClassName(componentId);
+
+ return page.getRootComponent();
+ }
+
+ String pageName = componentId.substring(0, colonx);
+
+ Page page = _pageCache.getByClassName(pageName);
+ String nestedId = componentId.substring(colonx + 1);
+
+ return page.getComponentElementByNestedId(nestedId).getComponent();
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java Mon Nov 20 13:10:27 2006
@@ -47,7 +47,7 @@
{
Page page = _pageCache.get("ExceptionReport");
- ExceptionReporter rootComponent = (ExceptionReporter) page.getRootElement().getComponent();
+ ExceptionReporter rootComponent = (ExceptionReporter) page.getRootComponent();
// Let the page set up for the new exception.
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java Mon Nov 20 13:10:27 2006
@@ -12,80 +12,157 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal.services;
-
-import org.apache.tapestry.Link;
-import org.apache.tapestry.internal.structure.ComponentPageElement;
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.services.ComponentClassResolver;
-import org.apache.tapestry.services.WebRequest;
-import org.apache.tapestry.services.WebResponse;
-import org.apache.tapestry.util.Defense;
-
-public class LinkFactoryImpl implements LinkFactory
-{
- private final WebRequest _request;
-
- private final WebResponse _response;
-
- private final ComponentClassResolver _componentClassResolver;
-
- public LinkFactoryImpl(WebRequest request, WebResponse response,
- ComponentClassResolver componentClassResolver)
- {
- _request = request;
- _response = response;
- _componentClassResolver = componentClassResolver;
- }
-
- public Link createActionLink(ComponentPageElement component, String action, boolean forForm,
- Object... context)
- {
- Defense.notBlank(action, "action");
-
- String pageName = component.getContainingPage().getName();
-
- String logicalPageName = _componentClassResolver.resolvePageClassNameToPageName(pageName);
-
- StringBuilder builder = new StringBuilder();
-
- builder.append(_request.getContextPath());
- builder.append("/");
- builder.append(logicalPageName);
- builder.append(".");
- builder.append(action);
- builder.append("/");
- builder.append(component.getNestedId());
-
- for (Object id : context)
- {
- builder.append("/");
-
- // TODO: Need to encode this for URLs? What if the string contains slashes, etc.?
-
- builder.append(id.toString());
- }
-
- // TODO: Much more: query parameter for case where active page != component page.
- // Letting listeners add extra parameters.
-
- return new LinkImpl(_response, builder.toString());
- }
-
- public Link createPageLink(Page page)
- {
- Defense.notNull(page, "page");
-
- String pageName = page.getName();
- String logicalPageName = _componentClassResolver.resolvePageClassNameToPageName(pageName);
-
- StringBuilder builder = new StringBuilder();
-
- builder.append(_request.getContextPath());
- builder.append("/");
- builder.append(logicalPageName);
- builder.append(".html");
-
- return new LinkImpl(_response, builder.toString());
- }
-}
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.WebRequest;
+import org.apache.tapestry.services.WebResponse;
+import org.apache.tapestry.util.Defense;
+import org.apache.tapestry.util.StrategyRegistry;
+
+public class LinkFactoryImpl implements LinkFactory
+{
+ private final WebRequest _request;
+
+ private final WebResponse _response;
+
+ private final ComponentClassResolver _componentClassResolver;
+
+ private interface PassivateContextHandler<T>
+ {
+ void handle(T result, List context);
+ }
+
+ private final StrategyRegistry<PassivateContextHandler> _registry;
+
+ public LinkFactoryImpl(WebRequest request, WebResponse response,
+ ComponentClassResolver componentClassResolver)
+ {
+ _request = request;
+ _response = response;
+ _componentClassResolver = componentClassResolver;
+
+ Map<Class, PassivateContextHandler> registrations = newMap();
+
+ registrations.put(Object.class, new PassivateContextHandler()
+ {
+ @SuppressWarnings("unchecked")
+ public void handle(Object result, List context)
+ {
+ context.add(result);
+ }
+ });
+
+ registrations.put(Object[].class, new PassivateContextHandler<Object[]>()
+ {
+
+ @SuppressWarnings("unchecked")
+ public void handle(Object[] result, List context)
+ {
+ for (Object o : result)
+ context.add(o);
+ }
+ });
+
+ registrations.put(Collection.class, new PassivateContextHandler<Collection>()
+ {
+ @SuppressWarnings("unchecked")
+ public void handle(Collection result, List context)
+ {
+ context.addAll(result);
+ }
+ });
+
+ _registry = StrategyRegistry.newInstance(PassivateContextHandler.class, registrations);
+ }
+
+ public Link createActionLink(ComponentPageElement component, String action, boolean forForm,
+ Object... context)
+ {
+ Defense.notBlank(action, "action");
+
+ String pageName = component.getContainingPage().getName();
+
+ String logicalPageName = _componentClassResolver.resolvePageClassNameToPageName(pageName);
+
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(_request.getContextPath());
+ builder.append("/");
+ builder.append(logicalPageName);
+ builder.append(".");
+ builder.append(action);
+ builder.append("/");
+ builder.append(component.getNestedId());
+
+ for (Object id : context)
+ {
+ builder.append("/");
+
+ // TODO: Need to encode this for URLs? What if the string contains slashes, etc.?
+
+ builder.append(id.toString());
+ }
+
+ // TODO: Much more: query parameter for case where active page != component page.
+ // Letting listeners add extra parameters.
+
+ return new LinkImpl(_response, builder.toString());
+ }
+
+ public Link createPageLink(final Page page)
+ {
+ Defense.notNull(page, "page");
+
+ String pageName = page.getName();
+ String logicalPageName = _componentClassResolver.resolvePageClassNameToPageName(pageName);
+
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(_request.getContextPath());
+ builder.append("/");
+ builder.append(logicalPageName);
+ builder.append(".html");
+
+ final List context = newList();
+
+ ComponentEventHandler handler = new ComponentEventHandler()
+ {
+ @SuppressWarnings("unchecked")
+ public void handleResult(Object result, Component component, String methodDescription)
+ {
+ PassivateContextHandler contextHandler = _registry.getByInstance(result);
+
+ contextHandler.handle(result, context);
+ }
+ };
+
+ ComponentPageElement rootElement = page.getRootElement();
+
+ rootElement.triggerEvent(TapestryConstants.PASSIVATE_EVENT, null, handler);
+
+ for (Object id : context)
+ {
+ builder.append("/");
+
+ // TODO: Need to encode this for URLs? What if the string contains slashes, etc.?
+
+ builder.append(id.toString());
+ }
+
+ return new LinkImpl(_response, builder.toString());
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java Mon Nov 20 13:10:27 2006
@@ -106,9 +106,11 @@
.getMediumDescription());
boolean isNonVoid = !method.getReturnType().equals("void");
-
+
+ // Store the result, converting primitives to wrappers automatically.
+
if (isNonVoid)
- builder.add("if ($1.storeResult(");
+ builder.add("if ($1.storeResult(($w) ");
builder.add("%s(", method.getMethodName());
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java Mon Nov 20 13:10:27 2006
@@ -12,54 +12,67 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal.services;
-
-import java.io.IOException;
-
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.services.Dispatcher;
-import org.apache.tapestry.services.WebRequest;
-import org.apache.tapestry.services.WebResponse;
-
-/**
- * Dispatches incoming requests whose path ends with ".html". In these cases, the path is
- * interpreted as a page name.
- *
- *
- */
-public class PageRenderDispatcher implements Dispatcher
-{
- private final PageResponseRenderer _renderer;
-
- private final RequestPageCache _cache;
-
- public PageRenderDispatcher(PageResponseRenderer renderer, RequestPageCache cache)
- {
- _renderer = renderer;
- _cache = cache;
- }
-
- public boolean dispatch(WebRequest request, WebResponse response) throws IOException
- {
- String path = request.getPath();
-
- // For the moment, just matching things that end with .html
-
- int pos = path.indexOf(".html");
-
- if (pos < 0)
- return false;
-
- // We have a match!
-
- // The first character will be the leading slash
-
- String logicalPageName = path.substring(1, pos);
-
- Page page = _cache.get(logicalPageName);
-
- _renderer.renderPageResponse(page, response);
-
- return true;
- }
-}
+package org.apache.tapestry.internal.services;
+
+import java.io.IOException;
+
+import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.Dispatcher;
+import org.apache.tapestry.services.WebRequest;
+import org.apache.tapestry.services.WebResponse;
+
+/**
+ * Dispatches incoming requests whose path ends with ".html". In these cases, the path is
+ * interpreted as a page name.
+ */
+public class PageRenderDispatcher implements Dispatcher
+{
+ private final PageResponseRenderer _renderer;
+
+ private final RequestPageCache _cache;
+
+ public PageRenderDispatcher(PageResponseRenderer renderer, RequestPageCache cache)
+ {
+ _renderer = renderer;
+ _cache = cache;
+ }
+
+ public boolean dispatch(WebRequest request, WebResponse response) throws IOException
+ {
+ String path = request.getPath();
+
+ // For the moment, just matching things that end with .html
+
+ int pos = path.indexOf(".html");
+
+ if (pos < 0)
+ return false;
+
+ // We have a match!
+
+ // The first character will be the leading slash
+
+ String logicalPageName = path.substring(1, pos);
+
+ Page page = _cache.get(logicalPageName);
+
+ String[] terms = path.substring(pos).split("/");
+
+ Object[] context = new Object[terms.length - 1];
+
+ for (int i = 1; i < terms.length; i++)
+ {
+ // TODO: Decode strings?
+ context[i - 1] = terms[i];
+ }
+
+ // Fire a notification so that the page can set itself up for the given context
+
+ page.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT, context, null);
+
+ _renderer.renderPageResponse(page, response);
+
+ return true;
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/StringEventHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/StringEventHandler.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/StringEventHandler.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/StringEventHandler.java Mon Nov 20 13:10:27 2006
@@ -1,3 +1,17 @@
+// Copyright 2006 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.ComponentEventHandler;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Mon Nov 20 13:10:27 2006
@@ -32,6 +32,7 @@
import org.apache.tapestry.internal.TapestryException;
import org.apache.tapestry.internal.services.ComponentEventImpl;
import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.internal.util.AcceptVoidEventHandler;
import org.apache.tapestry.internal.util.InternalUtils;
import org.apache.tapestry.ioc.IOCUtilities;
import org.apache.tapestry.ioc.services.TypeCoercer;
@@ -109,7 +110,7 @@
private final RenderCommand _afterRender = new RenderCommand()
{
public void render(final MarkupWriter writer, RenderQueue queue)
-
+
{
final LifecycleEvent<Boolean> event = newEvent(false);
@@ -779,7 +780,7 @@
public Component getPage()
{
- return _page.getRootElement().getComponent();
+ return _page.getRootComponent();
}
public boolean handleEvent(ComponentEvent event)
@@ -860,6 +861,7 @@
_page.persistFieldChange(this, fieldName, newValue);
}
+ /** Generate a toString() for the inner classes that represent render phases. */
private String phaseToString(String phaseName)
{
return String.format("%s[%s]", phaseName, _completeId);
@@ -884,6 +886,11 @@
public boolean triggerEvent(String eventType, Object[] context, ComponentEventHandler handler)
{
boolean result = false;
+
+ // Provide a default handler for when the provided handler is null.
+
+ if (handler == null)
+ handler = new AcceptVoidEventHandler(eventType, _completeId);
ComponentEvent event = new ComponentEventImpl(eventType, _id, context, handler,
_typeCoercer);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Mon Nov 20 13:10:27 2006
@@ -126,7 +126,7 @@
public Component getPage()
{
- return _element.getContainingPage().getRootElement().getComponent();
+ return _element.getContainingPage().getRootComponent();
}
public boolean isInvariant(String parameterName)
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java Mon Nov 20 13:10:27 2006
@@ -14,16 +14,17 @@
package org.apache.tapestry.internal.structure;
-import java.util.Locale;
-
-import org.apache.commons.logging.Log;
-import org.apache.tapestry.Link;
-import org.apache.tapestry.runtime.PageLifecycleListener;
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.PageLifecycleListener;
/**
* Represents a unique page within the application. Pages are part of the <em>internal</em>
* structure of a Tapestry application; end developers who refer to "page" are really referring to
- * the {@link #getRootElement() root component} of the actual page.
+ * the {@link #getRootComponent() root component} of the actual page.
* <p>
* One of the most important aspects of a Page is that it <em>does not</em> have to be coded in a
* thread-safe manner. Pages are always accessed within a single thread, associated with a single
@@ -57,7 +58,11 @@
* The root component of the page. This is the wrapper around the end developer's view of the
* page.
*/
- ComponentPageElement getRootElement();
+ ComponentPageElement getRootElement();
+
+ /** The root component of the page. A convienience over ivoking getRootElement().getComponent(). */
+
+ Component getRootComponent();
/**
* Invoked to inform the page that it is being detached from the current request. This occurs
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java Mon Nov 20 13:10:27 2006
@@ -22,6 +22,7 @@
import org.apache.commons.logging.Log;
import org.apache.tapestry.Link;
import org.apache.tapestry.internal.services.LinkFactory;
+import org.apache.tapestry.runtime.Component;
import org.apache.tapestry.runtime.PageLifecycleListener;
import org.apache.tapestry.services.PersistentFieldBundle;
import org.apache.tapestry.services.PersistentFieldManager;
@@ -92,7 +93,13 @@
{
return _rootElement;
}
-
+
+
+ public Component getRootComponent()
+ {
+ return _rootElement.getComponent();
+ }
+
public void addLifecycleListener(PageLifecycleListener listener)
{
_listeners.add(listener);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Mon Nov 20 13:10:27 2006
@@ -458,4 +458,10 @@
model.getMixinClassNames();
setReturnValue(Arrays.asList(names));
}
+
+ protected final void train_getRootComponent(Page page, Component component)
+ {
+ page.getRootComponent();
+ setReturnValue(component).atLeastOnce();
+ }
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html Mon Nov 20 13:10:27 2006
@@ -42,6 +42,9 @@
<li>
<a href="SimpleForm.html">SimpleForm</a> -- first pass at writing Form and TextField components
</li>
+ <li>
+ <a href="NumberSelect.html">NumberSelect</a> -- passivate/activate page context demo
+ </li>
</ul>
</p>
</body>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Mon Nov 20 13:10:27 2006
@@ -146,7 +146,7 @@
clickAndWait("link=Barney");
assertTextPresent("You clicked Barney.");
-
+
clickAndWait("link=Back");
clickAndWait("link=Wilma");
assertTextPresent("You clicked Wilma.");
@@ -295,6 +295,15 @@
assertTextPresent("[foo@bar.baz]");
assertTextPresent("[Message for you, sir!]");
assertTextPresent("[true]");
+ }
+
+ @Test
+ public void app1_passivate_activate() throws Exception
+ {
+ _selenium.open(BASE_URL);
+ clickAndWait("link=NumberSelect");
+ clickAndWait("link=5");
+ assertTextPresent("You chose 5.");
}
private void assertText(String locator, String expected)
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java?view=auto&rev=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java Mon Nov 20 13:10:27 2006
@@ -0,0 +1,51 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.InjectPage;
+import org.apache.tapestry.annotations.OnEvent;
+
+@ComponentClass
+public class NumberSelect
+{
+ private int _index;
+
+ public int getIndex()
+ {
+ return _index;
+ }
+
+ public void setIndex(int index)
+ {
+ _index = index;
+ }
+
+ public boolean isNotFirst()
+ {
+ return _index != 1;
+ }
+
+ @InjectPage
+ private ShowSelection _showSelection;
+
+ @OnEvent(component = "select")
+ Object doSelect(int index)
+ {
+ _showSelection.setSelected(index);
+
+ return _showSelection;
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java?view=auto&rev=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java Mon Nov 20 13:10:27 2006
@@ -0,0 +1,46 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.OnEvent;
+
+@ComponentClass
+public class ShowSelection
+{
+ private int _selected;
+
+ public int getSelected()
+ {
+ return _selected;
+ }
+
+ public void setSelected(int selected)
+ {
+ _selected = selected;
+ }
+
+ @OnEvent("passivate")
+ int passivate()
+ {
+ return _selected;
+ }
+
+ @OnEvent("activate")
+ void activate(int selected)
+ {
+ _selected = selected;
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java Mon Nov 20 13:10:27 2006
@@ -1,3 +1,17 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
package org.apache.tapestry.integration.app1.pages;
import org.apache.tapestry.annotations.ComponentClass;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java Mon Nov 20 13:10:27 2006
@@ -32,14 +32,11 @@
{
RequestPageCache cache = newRequestPageCache();
Page page = newPage();
- ComponentPageElement element = newComponentPageElement();
Component component = newComponent();
train_getByClassName(cache, PAGE_NAME, page);
- train_getRootElement(page, element);
-
- train_getComponent(element, component);
+ train_getRootComponent(page, component);
replay();
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java?view=diff&rev=477336&r1=477335&r2=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java Mon Nov 20 13:10:27 2006
@@ -12,103 +12,139 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal.services;
-
-import org.apache.tapestry.Link;
-import org.apache.tapestry.internal.structure.ComponentPageElement;
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.internal.test.InternalBaseTestCase;
-import org.apache.tapestry.services.ComponentClassResolver;
-import org.apache.tapestry.services.WebRequest;
-import org.apache.tapestry.services.WebResponse;
-import org.testng.annotations.Test;
-
-public class LinkFactoryImplTest extends InternalBaseTestCase
-{
- private static final String PAGE_LOGICAL_NAME = "sub/MyPage";
-
- private static final String PAGE_CLASS_NAME = "foo.pages.sub.MyPage";
-
- @Test
- public void action_link_root_context_no_ids()
- {
- run(PAGE_CLASS_NAME, PAGE_LOGICAL_NAME, "foo.bar", "", "/sub/MyPage.someaction/foo.bar");
- }
-
- @Test
- public void action_link_root_context_with_ids()
- {
- run(
- PAGE_CLASS_NAME,
- PAGE_LOGICAL_NAME,
- "foo.bar",
- "",
- "/sub/MyPage.someaction/foo.bar/fred/5",
- "fred",
- 5);
- }
-
- @Test
- public void action_link_named_context_no_ids()
- {
- run(
- PAGE_CLASS_NAME,
- PAGE_LOGICAL_NAME,
- "foo.bar",
- "/fred",
- "/fred/sub/MyPage.someaction/foo.bar");
- }
-
- @Test
- public void page_link()
- {
- WebRequest request = newWebRequest();
- WebResponse response = newWebResponse();
- ComponentClassResolver resolver = newComponentClassResolver();
- Page page = newPage();
-
- train_getName(page, PAGE_CLASS_NAME);
- train_resolvePageClassNameToPageName(resolver, PAGE_CLASS_NAME, PAGE_LOGICAL_NAME);
- train_getContextPath(request, "/barney");
-
- train_encodeRedirectURL(response, "/barney/" + PAGE_LOGICAL_NAME + ".html", "*encoded*");
-
- replay();
-
- LinkFactory factory = new LinkFactoryImpl(request, response, resolver);
-
- Link link = factory.createPageLink(page);
-
- assertEquals(link.toRedirectURI(), "*encoded*");
-
- verify();
- }
-
- private void run(String pageClassName, String logicalPageName, String nestedId,
- String contextPath, String expectedURI, Object... context)
- {
- WebRequest request = newWebRequest();
- WebResponse response = newWebResponse();
- ComponentClassResolver resolver = newComponentClassResolver();
- ComponentPageElement element = newComponentPageElement();
- Page page = newPage();
-
- train_getContainingPage(element, page);
- train_getName(page, pageClassName);
- train_resolvePageClassNameToPageName(resolver, pageClassName, logicalPageName);
- train_getContextPath(request, contextPath);
- train_getNestedId(element, nestedId);
-
- train_encodeURL(response, expectedURI, "*encoded*");
-
- replay();
-
- LinkFactory factory = new LinkFactoryImpl(request, response, resolver);
-
- Link link = factory.createActionLink(element, "someaction", false, context);
-
- assertEquals(link.toURI(), "*encoded*");
-
- verify();
- }
-}
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.WebRequest;
+import org.apache.tapestry.services.WebResponse;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.testng.annotations.Test;
+
+public class LinkFactoryImplTest extends InternalBaseTestCase
+{
+ private static final String PAGE_LOGICAL_NAME = "sub/MyPage";
+
+ private static final String PAGE_CLASS_NAME = "foo.pages.sub.MyPage";
+
+ @Test
+ public void action_link_root_context_no_ids()
+ {
+ run(PAGE_CLASS_NAME, PAGE_LOGICAL_NAME, "foo.bar", "", "/sub/MyPage.someaction/foo.bar");
+ }
+
+ @Test
+ public void action_link_root_context_with_ids()
+ {
+ run(
+ PAGE_CLASS_NAME,
+ PAGE_LOGICAL_NAME,
+ "foo.bar",
+ "",
+ "/sub/MyPage.someaction/foo.bar/fred/5",
+ "fred",
+ 5);
+ }
+
+ @Test
+ public void action_link_named_context_no_ids()
+ {
+ run(
+ PAGE_CLASS_NAME,
+ PAGE_LOGICAL_NAME,
+ "foo.bar",
+ "/fred",
+ "/fred/sub/MyPage.someaction/foo.bar");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void page_link()
+ {
+ WebRequest request = newWebRequest();
+ WebResponse response = newWebResponse();
+ ComponentClassResolver resolver = newComponentClassResolver();
+ Page page = newPage();
+ ComponentPageElement rootElement = newComponentPageElement();
+
+ train_getName(page, PAGE_CLASS_NAME);
+ train_resolvePageClassNameToPageName(resolver, PAGE_CLASS_NAME, PAGE_LOGICAL_NAME);
+ train_getContextPath(request, "/barney");
+
+ train_getRootElement(page, rootElement);
+
+ // Answer for triggerEvent() which returns a boolean.
+
+ IAnswer<Boolean> answer = new IAnswer<Boolean>()
+ {
+ public Boolean answer() throws Throwable
+ {
+ ComponentEventHandler handler = (ComponentEventHandler) EasyMock
+ .getCurrentArguments()[2];
+
+ handler.handleResult(new Object[]
+ { "foo", "bar" }, null, null);
+
+ return true;
+ }
+ };
+
+ // Intercept the call to handle component event, and let the IAnswer
+ // do the work.
+
+ rootElement.triggerEvent(
+ EasyMock.eq(TapestryConstants.PASSIVATE_EVENT),
+ (Object[]) EasyMock.isNull(),
+ EasyMock.isA(ComponentEventHandler.class));
+ getMocksControl().andAnswer(answer);
+
+ train_encodeRedirectURL(
+ response,
+ "/barney/" + PAGE_LOGICAL_NAME + ".html/foo/bar",
+ "*encoded*");
+
+ replay();
+
+ LinkFactory factory = new LinkFactoryImpl(request, response, resolver);
+
+ Link link = factory.createPageLink(page);
+
+ assertEquals(link.toRedirectURI(), "*encoded*");
+
+ verify();
+ }
+
+ private void run(String pageClassName, String logicalPageName, String nestedId,
+ String contextPath, String expectedURI, Object... context)
+ {
+ WebRequest request = newWebRequest();
+ WebResponse response = newWebResponse();
+ ComponentClassResolver resolver = newComponentClassResolver();
+ ComponentPageElement element = newComponentPageElement();
+ Page page = newPage();
+
+ train_getContainingPage(element, page);
+ train_getName(page, pageClassName);
+ train_resolvePageClassNameToPageName(resolver, pageClassName, logicalPageName);
+ train_getContextPath(request, contextPath);
+ train_getNestedId(element, nestedId);
+
+ train_encodeURL(response, expectedURI, "*encoded*");
+
+ replay();
+
+ LinkFactory factory = new LinkFactoryImpl(request, response, resolver);
+
+ Link link = factory.createActionLink(element, "someaction", false, context);
+
+ assertEquals(link.toURI(), "*encoded*");
+
+ verify();
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java?view=auto&rev=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java Mon Nov 20 13:10:27 2006
@@ -0,0 +1,136 @@
+// Copyright 2006 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.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.test.InternalBaseTestCase;
+import org.apache.tapestry.services.Dispatcher;
+import org.apache.tapestry.services.WebRequest;
+import org.apache.tapestry.services.WebResponse;
+import org.easymock.EasyMock;
+import org.testng.annotations.Test;
+
+public class PageRenderDispatcherTest extends InternalBaseTestCase
+{
+ @Test
+ public void not_a_page_request() throws Exception
+ {
+ PageResponseRenderer renderer = newPageResponseRenderer();
+ RequestPageCache cache = newRequestPageCache();
+ WebRequest request = newWebRequest();
+ WebResponse response = newWebResponse();
+
+ train_getPath(request, "/foo/Bar.baz");
+
+ replay();
+
+ Dispatcher d = new PageRenderDispatcher(renderer, cache);
+
+ assertFalse(d.dispatch(request, response));
+
+ verify();
+ }
+
+ @Test
+ public void no_extra_context() throws Exception
+ {
+ PageResponseRenderer renderer = newPageResponseRenderer();
+ RequestPageCache cache = newRequestPageCache();
+ WebRequest request = newWebRequest();
+ WebResponse response = newWebResponse();
+ Page page = newPage();
+ ComponentPageElement rootElement = newComponentPageElement();
+
+ train_getPath(request, "/foo/Bar.html");
+
+ train_get(cache, "foo/Bar", page);
+ train_getRootElement(page, rootElement);
+
+ train_triggerEvent(
+ rootElement,
+ TapestryConstants.ACTIVATE_EVENT,
+ new Object[0],
+ null,
+ false);
+
+ renderer.renderPageResponse(page, response);
+
+ replay();
+
+ Dispatcher d = new PageRenderDispatcher(renderer, cache);
+
+ assertTrue(d.dispatch(request, response));
+
+ verify();
+ }
+
+ @Test
+ public void context_passed_in_path() throws Exception
+ {
+ PageResponseRenderer renderer = newPageResponseRenderer();
+ RequestPageCache cache = newRequestPageCache();
+ WebRequest request = newWebRequest();
+ WebResponse response = newWebResponse();
+ Page page = newPage();
+ ComponentPageElement rootElement = newComponentPageElement();
+
+ train_getPath(request, "/foo/Bar.html/zip/zoom");
+
+ train_get(cache, "foo/Bar", page);
+ train_getRootElement(page, rootElement);
+
+ train_triggerEvent(rootElement, TapestryConstants.ACTIVATE_EVENT, new Object[]
+ { "zip", "zoom" }, null, false);
+
+ renderer.renderPageResponse(page, response);
+
+ replay();
+
+ Dispatcher d = new PageRenderDispatcher(renderer, cache);
+
+ assertTrue(d.dispatch(request, response));
+
+ verify();
+ }
+
+ private void train_triggerEvent(ComponentPageElement element, String eventType,
+ Object[] context, ComponentEventHandler handler, boolean handled)
+ {
+ element.triggerEvent(EasyMock.eq(eventType), EasyMock.aryEq(context), EasyMock
+ .same(handler));
+ setReturnValue(handled);
+ }
+
+ protected final void train_get(RequestPageCache cache, String pageName, Page page)
+ {
+ cache.get(pageName);
+ setReturnValue(page).atLeastOnce();
+ }
+
+ protected final PageResponseRenderer newPageResponseRenderer()
+ {
+ return newMock(PageResponseRenderer.class);
+ }
+
+ protected final void train_getPath(WebRequest request, String path)
+ {
+ request.getPath();
+ setReturnValue(path).atLeastOnce();
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.html?view=auto&rev=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.html Mon Nov 20 13:10:27 2006
@@ -0,0 +1,17 @@
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+ <h1>Number Selection</h1>
+
+ <p> Demonstration of passivate/activate page logic.</p>
+
+ <p>
+ Select a number from this list:
+
+ <t:comp type="Loop" source="1..10" value="index">
+ <t:comp type="If" test="notFirst"> - </t:comp>
+ <t:comp type="ActionLink" id="select" context="index">${index}</t:comp>
+ </t:comp>
+ </p>
+
+
+
+</t:comp>
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.html?view=auto&rev=477336
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.html Mon Nov 20 13:10:27 2006
@@ -0,0 +1,10 @@
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+ <h1>Number Selection</h1>
+
+ <p> You chose ${selected}.</p>
+
+ <p>
+ [<a href="/NumberSelect.html">Back</a>]
+ </p>
+
+</t:comp>