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 2005/06/19 17:00:46 UTC
cvs commit: jakarta-tapestry/src/documentation/content/xdocs/UsersGuide listenermethods.xml
hlship 2005/06/19 08:00:46
Modified: . status.xml
framework/src/java/org/apache/tapestry/listener
ListenerMapSourceImpl.java
ListenerMethodInvokerImpl.java
framework/src/test/org/apache/tapestry/listener
TestListenerMapSource.java
ListenerMethodHolder.java
src/documentation/content/xdocs index.xml
src/documentation/content/xdocs/UsersGuide
listenermethods.xml
Log:
Listener methods may now return a page name, or a page instance, to activate and render the response.
Revision Changes Path
1.136 +1 -0 jakarta-tapestry/status.xml
Index: status.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/status.xml,v
retrieving revision 1.135
retrieving revision 1.136
diff -u -r1.135 -r1.136
--- status.xml 17 Jun 2005 16:52:19 -0000 1.135
+++ status.xml 19 Jun 2005 15:00:45 -0000 1.136
@@ -84,6 +84,7 @@
<action type="update" dev="HLS">Rework form event management to be primarily a client-side concern.</action>
<action type="add" dev="HLS">Add translator binding prefix.</action>
<action type="add" dev="HLS">Add cancel and refresh listener parameters to Form.</action>
+ <action type="add" dev="HLS">Listener methods may now return a page name, or a page instance, to activate and render the response.</action>
</release>
<release version="4.0-alpha-3" date="May 16 2005">
<action type="add" dev="HLS">Add initial support for the validator: binding prefix.</action>
1.4 +14 -2 jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMapSourceImpl.java
Index: ListenerMapSourceImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMapSourceImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ListenerMapSourceImpl.java 10 May 2005 22:50:57 -0000 1.3
+++ ListenerMapSourceImpl.java 19 Jun 2005 15:00:45 -0000 1.4
@@ -25,6 +25,7 @@
import java.util.Map;
import org.apache.hivemind.util.Defense;
+import org.apache.tapestry.IPage;
import org.apache.tapestry.event.ResetEventListener;
/**
@@ -88,7 +89,8 @@
private Map buildInvokerMapForClass(Class targetClass)
{
// map, keyed on method name, value is List of Method
- // only public void methods go into this map.
+ // only methods that return void, return String, or return
+ // something assignable to IPage are kept.
Map map = new HashMap();
@@ -104,7 +106,7 @@
{
Method m = methods[i];
- if (m.getReturnType() != void.class)
+ if (!isAcceptibleListenerMethodReturnType(m))
continue;
if (Modifier.isStatic(m.getModifiers()))
@@ -118,6 +120,16 @@
return convertMethodListMapToInvokerMap(map);
}
+ boolean isAcceptibleListenerMethodReturnType(Method m)
+ {
+ Class returnType = m.getReturnType();
+
+ if (returnType == void.class || returnType == String.class)
+ return true;
+
+ return IPage.class.isAssignableFrom(returnType);
+ }
+
private Map convertMethodListMapToInvokerMap(Map map)
{
Map result = new HashMap();
1.4 +21 -3 jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMethodInvokerImpl.java
Index: ListenerMethodInvokerImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMethodInvokerImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ListenerMethodInvokerImpl.java 10 May 2005 22:50:57 -0000 1.3
+++ ListenerMethodInvokerImpl.java 19 Jun 2005 15:00:45 -0000 1.4
@@ -19,6 +19,7 @@
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.util.Defense;
+import org.apache.tapestry.IPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
@@ -148,7 +149,24 @@
try
{
- invokeTargetMethod(target, listenerMethod, parameters);
+ Object methodResult = invokeTargetMethod(target, listenerMethod, parameters);
+
+ // void methods return null
+
+ if (methodResult == null)
+ return;
+
+ // The method scanner, inside ListenerMapSourceImpl,
+ // ensures that only methods that return void, String,
+ // or assignable to IPage are considered.
+
+ if (methodResult instanceof String)
+ {
+ cycle.activate((String) methodResult);
+ return;
+ }
+
+ cycle.activate((IPage) methodResult);
}
catch (InvocationTargetException ex)
{
@@ -177,9 +195,9 @@
* invoking the listener method.
*/
- protected void invokeTargetMethod(Object target, Method listenerMethod, Object[] parameters)
+ protected Object invokeTargetMethod(Object target, Method listenerMethod, Object[] parameters)
throws IllegalAccessException, InvocationTargetException
{
- listenerMethod.invoke(target, parameters);
+ return listenerMethod.invoke(target, parameters);
}
}
\ No newline at end of file
1.3 +73 -0 jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/TestListenerMapSource.java
Index: TestListenerMapSource.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/TestListenerMapSource.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestListenerMapSource.java 18 Apr 2005 17:07:52 -0000 1.2
+++ TestListenerMapSource.java 19 Jun 2005 15:00:45 -0000 1.3
@@ -14,8 +14,11 @@
package org.apache.tapestry.listener;
+import java.lang.reflect.Method;
+
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.test.HiveMindTestCase;
+import org.apache.tapestry.IPage;
import org.apache.tapestry.IRequestCycle;
import org.easymock.MockControl;
@@ -39,6 +42,39 @@
return cycle;
}
+ private Method findMethod(Class clazz, String name)
+ {
+ Method[] methods = clazz.getMethods();
+
+ for (int i = 0; i < methods.length; i++)
+ {
+ if (methods[i].getName().equals(name))
+ return methods[i];
+ }
+
+ throw new IllegalArgumentException("No method '" + name + "' in " + clazz + ".");
+ }
+
+ private void attemptReturnType(boolean expected, Class clazz, String methodName)
+ {
+ Method m = findMethod(clazz, methodName);
+
+ ListenerMapSourceImpl lms = new ListenerMapSourceImpl();
+
+ assertEquals(expected, lms.isAcceptibleListenerMethodReturnType(m));
+ }
+
+ public void testAcceptibleListenerMethodReturnTypes()
+ {
+ Class clazz = ListenerMethodHolder.class;
+
+ attemptReturnType(true, clazz, "fred");
+ attemptReturnType(true, clazz, "returnsString");
+ attemptReturnType(true, clazz, "returnsBasePage");
+ attemptReturnType(false, clazz, "returnsObject");
+ attemptReturnType(false, clazz, "returnsInt");
+ }
+
public void testFoundWithParameters()
{
IRequestCycle cycle = newCycle(new Object[]
@@ -120,6 +156,43 @@
verifyControls();
}
+ public void testReturnPageName()
+ {
+ IRequestCycle cycle = newCycle(null);
+ ListenerMethodHolder holder = new ListenerMethodHolder("PageName");
+
+ cycle.activate("PageName");
+
+ replayControls();
+
+ ListenerMapSource source = new ListenerMapSourceImpl();
+
+ ListenerMap map = source.getListenerMapForObject(holder);
+
+ map.getListener("returnsPageName").actionTriggered(null, cycle);
+
+ verifyControls();
+ }
+
+ public void testReturnPageInstance()
+ {
+ IPage page = (IPage) newMock(IPage.class);
+ IRequestCycle cycle = newCycle(null);
+ ListenerMethodHolder holder = new ListenerMethodHolder(page);
+
+ cycle.activate(page);
+
+ replayControls();
+
+ ListenerMapSource source = new ListenerMapSourceImpl();
+
+ ListenerMap map = source.getListenerMapForObject(holder);
+
+ map.getListener("returnsPage").actionTriggered(null, cycle);
+
+ verifyControls();
+ }
+
public void testNoMatch()
{
IRequestCycle cycle = newCycle(new Object[]
1.3 +50 -0 jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/ListenerMethodHolder.java
Index: ListenerMethodHolder.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/ListenerMethodHolder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ListenerMethodHolder.java 18 Apr 2005 17:07:52 -0000 1.2
+++ ListenerMethodHolder.java 19 Jun 2005 15:00:45 -0000 1.3
@@ -16,7 +16,9 @@
import java.util.Map;
+import org.apache.tapestry.IPage;
import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.html.BasePage;
/**
* Used by {@link org.apache.tapestry.listener.TestListenerMapSource}.
@@ -28,6 +30,24 @@
{
private RuntimeException _exception;
+ private String _pageName;
+
+ private IPage _page;
+
+ public ListenerMethodHolder()
+ {
+ }
+
+ public ListenerMethodHolder(String pageName)
+ {
+ _pageName = pageName;
+ }
+
+ public ListenerMethodHolder(IPage page)
+ {
+ _page = page;
+ }
+
public void wrongTypes(Map map)
{
}
@@ -46,6 +66,36 @@
}
+ public String returnsString()
+ {
+ return null;
+ }
+
+ public BasePage returnsBasePage()
+ {
+ return null;
+ }
+
+ public IPage returnsPage()
+ {
+ return _page;
+ }
+
+ public String returnsPageName()
+ {
+ return _pageName;
+ }
+
+ public Object returnsObject()
+ {
+ return null;
+ }
+
+ public int returnsInt()
+ {
+ return 0;
+ }
+
/**
* Tapestry 3.0 and earlier style.
*/
1.13 +6 -0 jakarta-tapestry/src/documentation/content/xdocs/index.xml
Index: index.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/index.xml,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- index.xml 17 Jun 2005 18:04:58 -0000 1.12
+++ index.xml 19 Jun 2005 15:00:45 -0000 1.13
@@ -106,6 +106,12 @@
and leverage J2EE declarative security along the way.
</li>
<li>
+ Listener methods are much easier and more flexible; listener parameters in the URL
+ are automatically mapped to
+ listener method parameters, and listener methods can return the page name or page instance
+ to activate.
+ </li>
+ <li>
Component parameters now <em>just work</em>, without having to worry about
"direction".
</li>
1.5 +14 -7 jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/listenermethods.xml
Index: listenermethods.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/listenermethods.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- listenermethods.xml 15 May 2005 22:56:37 -0000 1.4
+++ listenermethods.xml 19 Jun 2005 15:00:45 -0000 1.5
@@ -50,15 +50,22 @@
</note>
<p>
-A listener method is a public void method. It may take parameters, or may not ... the rules are discussed below.
+A listener method is a public method. It may take parameters, or may not ... the rules are discussed below.
A simple listener method take no parameters, or takes a single parameter of type &IRequestCycle;.
+A listener method may return void, return a string (the name of a page), or return &IPage; (or an object
+assignable to &IPage;). In
+the latter two cases, the returned page will be <em>activated</em> to render the response. This means that
+in the vast majority of cases, you can write listener methods <em>without</em> the &IRequestCycle; object.
+</p>
+
+<p>
When using the &DirectLink; component, you may specify additional <em>listener parameters</em>. The listener parameters
are encoded into the URL and will be available in a later request, when the listener is triggered.
</p>
<note>
In Tapestry 3.0 and earlier, <em>listener parameters</em> were known as <em>service parameters</em>. In addition,
-listener methods had to be in a very fixed form, taking exactly one parameter of type &IRequestCycle;.
+listener methods had to be in a very fixed form, taking exactly one parameter of type &IRequestCycle; and returning void.
</note>
<p>
@@ -121,14 +128,14 @@
</p>
<ul>
- <li>public void <em>method</em>(<em>parameters</em>)</li>
- <li>public void <em>method</em>(IRequestCycle cycle, <em>parameters</em>)</li>
- <li>public void <em>method</em>()</li>
- <li>public void <em>method(IRequestCycle cycle)</em></li>
+ <li>public <em>type</em> <em>method</em>(<em>parameters</em>)</li>
+ <li>public <em>type</em> <em>method</em>(IRequestCycle cycle, <em>parameters</em>)</li>
+ <li>public <em>type</em> <em>method</em>()</li>
+ <li>public <em>type</em> <em>method(IRequestCycle cycle)</em></li>
</ul>
<p>
-Tapestry 3.0 and earlier only accepted the final variation. Don't get too tricky with multiple overloadings
+Tapestry 3.0 and earlier only accepted the final variation (and it had to return void). Don't get too tricky with multiple overloadings
of the method; Tapestry doesn't attempt to match the listener parameter types to the method parameter types (it
works just by comparing the <em>number</em> of parameters). However, you can count on Java boxing and autoboxing
the parameter values (so you can use <code>int</code> and <code>java.lang.Integer</code> interchangeably).
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org