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 2010/06/25 02:06:05 UTC
svn commit: r957763 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/annotations/
main/java/org/apache/tapestry5/internal/transform/
main/java/org/apache/tapestry5/services/ test/app1/ test/conf/
test/groovy/org/apache/t...
Author: hlship
Date: Fri Jun 25 00:06:04 2010
New Revision: 957763
URL: http://svn.apache.org/viewvc?rev=957763&view=rev
Log:
TAP5-1190: Add @QueryParameterMapped annotation and supporting logic
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameterMapped.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/QueryParameterMappedWorker.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/QueryParameterMappedDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/
tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/
tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/QueryParameterMappedTests.groovy
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/QueryParameterMappedDemo.java (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Persist.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameter.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/conf/testng-limited.xml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Persist.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Persist.java?rev=957763&r1=957762&r2=957763&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Persist.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Persist.java Fri Jun 25 00:06:04 2010
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@ import org.apache.tapestry5.ioc.annotati
*
* @see org.apache.tapestry5.services.MetaDataLocator
* @see org.apache.tapestry5.PersistenceConstants
+ * @see QueryParameterMapped
*/
@Target(FIELD)
@Documented
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameter.java?rev=957763&r1=957762&r2=957763&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameter.java Fri Jun 25 00:06:04 2010
@@ -24,6 +24,7 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
+import org.apache.tapestry5.internal.transform.OnEventWorker;
import org.apache.tapestry5.ioc.annotations.UseWith;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.services.Request;
@@ -31,12 +32,15 @@ import org.apache.tapestry5.services.Req
/**
* Annotation that may be placed on parameters of event handler methods.
* Annotated parameters will be {@linkplain Request#getParameter(String) extracted from the request},
- * then {@linkplain TypeCoercer coerced} to the type of the parameter. Such parameters are seperate
+ * then {@linkplain TypeCoercer coerced} to the type of the parameter. Such parameters are separate
* from ordinary context parameters (extracted from the Request path). Typically, this is used when
* client-side JavaScript adds a query parameter to a request to communicate some information from the client
* side to the server side.
+ * <p>
+ * Individual fields may also be directly mapped to query parameters using the {@link QueryParameterMapped} annotation.
*
* @since 5.2.0
+ * @see OnEventWorker
*/
@Target(
{ PARAMETER })
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameterMapped.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameterMapped.java?rev=957763&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameterMapped.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameterMapped.java Fri Jun 25 00:06:04 2010
@@ -0,0 +1,67 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.annotations;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.apache.tapestry5.ioc.annotations.AnnotationUseContext.PAGE;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.EventConstants;
+import org.apache.tapestry5.Link;
+import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.ioc.annotations.UseWith;
+import org.apache.tapestry5.services.ValueEncoderSource;
+
+/**
+ * Marks a field of a page (not a component) as persistent within the URL. The field is mapped
+ * to a query parameter. When component event or page render links are generated for the page,
+ * additional values will be added to the {@link Link} (via the {@link EventConstants#DECORATE_COMPONENT_EVENT_LINK} or
+ * {@link EventConstants#DECORATE_PAGE_RENDER_LINK} events).
+ * <p>
+ * Care must be taken that the query parameter name does not clash with a query parameter name generated for a form
+ * field.
+ * <p>
+ * The field may be of any type; a {@link ValueEncoder} (from the {@link ValueEncoderSource}) will be used to convert
+ * between client-side and server-side representations. Null values are not added as query parameters (just non-null).
+ * <p>
+ * When a page is activated, the mapped fields will receive their values before an {@linkplain EventConstants#ACTIVATE
+ * activate} event handler method is invoked.
+ * <p>
+ * This annotation is an alternative to {@link Persist}.
+ * <p>
+ * Fields annotated with QueryParameterMapped are <em>not</em> considered persistent (its a process parallel to the one
+ * related to the {@link Persist} annotation). Invoking {@link ComponentResources#discardPersistentFieldChanges()} will
+ * <em>not</em> affect annotated fields, only assigning them back to null will.
+ *
+ * @see QueryParameter
+ */
+@Target(
+{ ElementType.FIELD })
+@Retention(RUNTIME)
+@Documented
+@UseWith(
+{ PAGE })
+public @interface QueryParameterMapped
+{
+ /** The name of the query parameter, which defaults to the name of the field. */
+ String value() default "";
+
+ // TODO: Attributes to limit it to just render links, or just component event links?
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/QueryParameterMapped.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/QueryParameterMappedWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/QueryParameterMappedWorker.java?rev=957763&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/QueryParameterMappedWorker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/QueryParameterMappedWorker.java Fri Jun 25 00:06:04 2010
@@ -0,0 +1,163 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.transform;
+
+import org.apache.tapestry5.EventConstants;
+import org.apache.tapestry5.Link;
+import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.annotations.QueryParameterMapped;
+import org.apache.tapestry5.internal.services.ComponentClassCache;
+import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.runtime.ComponentEvent;
+import org.apache.tapestry5.services.*;
+
+/**
+ * Hooks the activate event handler on the component (presumably, a page) to
+ * extract query parameters, and hooks the link decoration events to extract values
+ * and add them to the {@link Link}.
+ *
+ * @see QueryParameterMapped
+ * @since 5.2.0
+ */
+public class QueryParameterMappedWorker implements ComponentClassTransformWorker
+{
+ private final Request request;
+
+ private final ComponentClassCache classCache;
+
+ private final ValueEncoderSource valueEncoderSource;
+
+ interface EventHandler
+ {
+ void invoke(Component component, ComponentEvent event);
+ }
+
+ public QueryParameterMappedWorker(Request request, ComponentClassCache classCache,
+ ValueEncoderSource valueEncoderSource)
+ {
+ this.request = request;
+ this.classCache = classCache;
+ this.valueEncoderSource = valueEncoderSource;
+ }
+
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ for (TransformField field : transformation.matchFieldsWithAnnotation(QueryParameterMapped.class))
+ {
+ mapFieldToQueryParameter(field, transformation, model);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void mapFieldToQueryParameter(TransformField field, ClassTransformation transformation,
+ MutableComponentModel model)
+ {
+ QueryParameterMapped annotation = field.getAnnotation(QueryParameterMapped.class);
+
+ String parameterName = getParameterName(field, annotation);
+
+ TransformMethod dispatchMethod = transformation.getOrCreateMethod(TransformConstants.DISPATCH_COMPONENT_EVENT);
+
+ // Assumption: the field type is not one that's loaded by the component class loader, so it's safe
+ // to convert to a hard type during class transformation.
+
+ Class fieldType = classCache.forName(field.getType());
+
+ ValueEncoder encoder = valueEncoderSource.getValueEncoder(fieldType);
+
+ FieldAccess access = field.getAccess();
+
+ setValueFromInitializeEventHandler(access, parameterName, encoder, dispatchMethod, model);
+ decorateLinks(access, parameterName, encoder, dispatchMethod, model);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void setValueFromInitializeEventHandler(final FieldAccess access, final String parameterName,
+ final ValueEncoder encoder, TransformMethod dispatchMethod, MutableComponentModel model)
+ {
+ EventHandler handler = new EventHandler()
+ {
+ public void invoke(Component component, ComponentEvent event)
+ {
+ String clientValue = request.getParameter(parameterName);
+
+ if (clientValue == null)
+ return;
+
+ Object value = encoder.toValue(clientValue);
+
+ access.write(component, value);
+ }
+ };
+
+ add(dispatchMethod, model, EventConstants.ACTIVATE, handler);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void decorateLinks(final FieldAccess access, final String parameterName, final ValueEncoder encoder,
+ TransformMethod dispatchMethod, MutableComponentModel model)
+ {
+ EventHandler handler = new EventHandler()
+ {
+ public void invoke(Component component, ComponentEvent event)
+ {
+ Object value = access.read(component);
+
+ if (value == null)
+ return;
+
+ Link link = event.getEventContext().get(Link.class, 0);
+
+ String clientValue = encoder.toClient(value);
+
+ link.addParameter(parameterName, clientValue);
+ }
+ };
+
+ add(dispatchMethod, model, EventConstants.DECORATE_COMPONENT_EVENT_LINK, handler);
+ add(dispatchMethod, model, EventConstants.DECORATE_PAGE_RENDER_LINK, handler);
+ }
+
+ private void add(TransformMethod dispatchMethod, MutableComponentModel model, final String eventType,
+ final EventHandler handler)
+ {
+ dispatchMethod.addAdvice(new ComponentMethodAdvice()
+ {
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ ComponentEvent event = (ComponentEvent) invocation.getParameter(0);
+
+ if (event.matches(eventType, "", 0))
+ {
+ handler.invoke(invocation.getInstance(), event);
+ }
+
+ invocation.proceed();
+ }
+ });
+
+ model.addEventHandler(eventType);
+ }
+
+ private String getParameterName(TransformField field, QueryParameterMapped annotation)
+ {
+ if (annotation.value().equals(""))
+ return field.getName();
+
+ return annotation.value();
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/QueryParameterMappedWorker.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=957763&r1=957762&r2=957763&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Fri Jun 25 00:06:04 2010
@@ -588,6 +588,8 @@ public final class TapestryModule
* <dd>Checks for the {@link PageReset} annotation
* <dt>HeartbeatDeferred
* <dd>Support for the {@link HeartbeatDeferred} annotation
+ * <dt>QueryParameterMapped
+ * <dd>Support for the {@link QueryParameterMapped} annotation
* </dl>
*/
public static void contributeComponentClassTransformWorker(
@@ -607,6 +609,7 @@ public final class TapestryModule
configuration.add("MixinAfter", new MixinAfterWorker());
configuration.add("Component", new ComponentWorker(resolver));
configuration.add("Mixin", new MixinWorker(resolver));
+ configuration.addInstance("QueryParameterMapped", QueryParameterMappedWorker.class, "before:OnEvent");
configuration.addInstance("OnEvent", OnEventWorker.class);
configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
configuration.addInstance("InjectPage", InjectPageWorker.class);
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/QueryParameterMappedDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/QueryParameterMappedDemo.tml?rev=957763&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/QueryParameterMappedDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/QueryParameterMappedDemo.tml Fri Jun 25 00:06:04 2010
@@ -0,0 +1,25 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <h1>@QueryParameterMapped Demo</h1>
+
+ <dl>
+ <dt>Click count:</dt>
+ <dd id="clickCount">${clickCount}</dd>
+ <dt>Click count set:</dt>
+ <dd id="clickCountSet">${clickCountSet}</dd>
+ <dt>Message:</dt>
+ <dd id="message">${message}</dd>
+ </dl>
+
+ <ul>
+ <li>
+ <t:actionlink t:id="increment">increment count</t:actionlink>
+ </li>
+ <li>
+ <t:actionlink t:id="setMessage">set message</t:actionlink>
+ </li>
+ <li>
+ <t:actionlink t:id="reset">reset</t:actionlink>
+ </li>
+ </ul>
+</html>
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/conf/testng-limited.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/conf/testng-limited.xml?rev=957763&r1=957762&r2=957763&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/conf/testng-limited.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/conf/testng-limited.xml Fri Jun 25 00:06:04 2010
@@ -11,7 +11,7 @@
<class name="org.apache.tapestry5.test.SeleniumLauncher"/>
<!-- Modify classes below as needed. -->
- <class name="org.apache.tapestry5.integration.app1.AjaxTests"/>
+ <class name="org.apache.tapestry5.integration.app1.QueryParameterMappedTests"/>
</classes>
</test>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/QueryParameterMappedTests.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/QueryParameterMappedTests.groovy?rev=957763&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/QueryParameterMappedTests.groovy (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/QueryParameterMappedTests.groovy Fri Jun 25 00:06:04 2010
@@ -0,0 +1,42 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1;
+
+import org.apache.tapestry5.integration.TapestryCoreTestCase
+import org.testng.annotations.Test
+
+class QueryParameterMappedTests extends TapestryCoreTestCase
+{
+ @Test
+ void basic_links()
+ {
+ clickThru "@QueryParameterMapped Demo"
+
+ assertText("clickCount", "")
+ assertText("clickCountSet", "false")
+ assertText("message", "")
+
+ clickAndWait "link=increment count"
+
+ assertText("clickCount", "1")
+ assertText("clickCountSet", "true")
+
+ clickAndWait "link=set message"
+
+ assertText("clickCount", "1")
+ assertText("clickCountSet", "true")
+ assertText("message", "Link clicked!")
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=957763&r1=957762&r2=957763&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java Fri Jun 25 00:06:04 2010
@@ -67,6 +67,9 @@ public class Index
private static final List<Item> ITEMS = CollectionFactory
.newList(
+ new Item("QueryParameterMappedDemo", "@QueryParameterMapped Demo",
+ "Use of @QueryParameterMapped to encode page state into query parameters"),
+
new Item("LibraryMessagesDemo", "Library Messages Demo",
"Demo ability to contribute additional message catalog resources to the application global catalog."),
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/QueryParameterMappedDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/QueryParameterMappedDemo.java?rev=957763&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/QueryParameterMappedDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/QueryParameterMappedDemo.java Fri Jun 25 00:06:04 2010
@@ -0,0 +1,54 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.QueryParameterMapped;
+
+public class QueryParameterMappedDemo
+{
+
+ @Property
+ private boolean clickCountSet;
+
+ @Property
+ @QueryParameterMapped
+ private Integer clickCount;
+
+ @Property
+ @QueryParameterMapped
+ private String message;
+
+ void onActivate()
+ {
+ clickCountSet = clickCount != null;
+ }
+
+ void onActionFromIncrement()
+ {
+ clickCount = clickCount == null ? 1 : clickCount + 1;
+ }
+
+ void onActionFromSetMessage()
+ {
+ message = "Link clicked!";
+ }
+
+ void onActionFromReset()
+ {
+ clickCount = null;
+ message = null;
+ }
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/QueryParameterMappedDemo.java
------------------------------------------------------------------------------
svn:eol-style = native