You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by bd...@apache.org on 2007/07/27 22:20:29 UTC
svn commit: r560371 - in /tapestry/tapestry4/trunk:
tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/
tapestry-framework/src/java/org/apache/tapestry/
tapestry-framework/src/java/org/apache/tapestry/components/
tapestry-framework/src/java/org...
Author: bdotte
Date: Fri Jul 27 13:20:26 2007
New Revision: 560371
URL: http://svn.apache.org/viewvc?view=rev&rev=560371
Log:
Resolves TAPESTRY-394. For components with a required listener (XTile, DirectLink, InvokeListener, Suggest), add the ability to find an implicit listener whose name is composed of the capitalized component id, prefixed by "do".
Modified:
tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.java
tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.jwc
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/TapestryUtils.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.jwc
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.jwc
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMap.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMapImpl.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMessages.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerStrings.properties
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.jwc
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/TapestryUtilsTest.java
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/listener/TestListenerMap.java
Modified: tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.java (original)
+++ tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.java Fri Jul 27 13:20:26 2007
@@ -20,7 +20,6 @@
import org.apache.tapestry.BaseComponent;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IRequestCycle;
-import org.apache.tapestry.Tapestry;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
@@ -50,7 +49,7 @@
IActionListener listener = getListener();
if (listener == null)
- throw Tapestry.createRequiredParameterException(this, "listener");
+ listener = getContainer().getListeners().getImplicitListener(this);
listener.actionTriggered(this, cycle);
}
Modified: tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.jwc
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.jwc?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.jwc (original)
+++ tapestry/tapestry4/trunk/tapestry-contrib/src/java/org/apache/tapestry/contrib/ajax/XTile.jwc Fri Jul 27 13:20:26 2007
@@ -27,12 +27,14 @@
and receive its response without reloading the page (Ajax)
</description>
- <parameter name="listener" required="yes">
+ <parameter name="listener">
<description>
The listener that will be invoked when the Javascript function with the given name is invoked.
Any parameters passed to the send function will be available from cycle.getServiceParameters().
In addition, the listener can perform cycle.setServiceParameters() to pass an array of
- strings to the JavaScript receive function.
+ strings to the JavaScript receive function. If the listener is not provided, Tapestry will
+ attempt to find a listener with the capitalized id of the component, prefixed by "do". For
+ example, jwcid="clear@XTile" would have a listener called doClear().
</description>
</parameter>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/TapestryUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/TapestryUtils.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/TapestryUtils.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/TapestryUtils.java Fri Jul 27 13:20:26 2007
@@ -14,14 +14,14 @@
package org.apache.tapestry;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.HiveMind;
import org.apache.hivemind.Location;
import org.apache.hivemind.util.Defense;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Constants and static methods.
*
@@ -234,6 +234,18 @@
return (String[]) strings.toArray(new String[strings.size()]);
}
+
+ /**
+ * Capitalize the first letter of the input if at least 1 character.
+ */
+
+ public static String capitalize(String input)
+ {
+ if (input == null || input.length() < 1)
+ return input;
+
+ return input.substring(0, 1).toUpperCase() + input.substring(1);
+ }
/**
* Enquotes a string within single quotes, ready for insertion as part of a block of JavaScript.
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.java Fri Jul 27 13:20:26 2007
@@ -24,7 +24,8 @@
/**
* Invokes a listener method, passing listener parameters. This is used when a
* page or component needs some setup logic that can be best accomplished in
- * Java code.
+ * Java code. If the listener parameter is not bound, attempt to locate an
+ * implicit listener named by the capitalized component id, prefixed by "do".
*
* @author Howard M. Lewis Ship
* @since 4.0
@@ -41,7 +42,12 @@
{
cycle.setListenerParameters(parameters);
- getListenerInvoker().invokeListener(getListener(), this, cycle);
+ IActionListener listener = getListener();
+
+ if (listener == null)
+ listener = getContainer().getListeners().getImplicitListener(this);
+
+ getListenerInvoker().invokeListener(listener, this, cycle);
}
finally
{
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.jwc
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.jwc?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.jwc (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/InvokeListener.jwc Fri Jul 27 13:20:26 2007
@@ -27,7 +27,14 @@
Invokes a listener, with parameters, during the page render.
</description>
- <parameter name="listener" required="yes"/>
+ <parameter name="listener">
+ <description>
+ The listener to be invoked. If none is provided, Tapestry will attempt
+ to find a listener with the capitalized id of the component, prefixed
+ by "do". For example, jwcid="clear@InvokeListener" would have a
+ listener called doClear().
+ </description>
+ </parameter>
<parameter name="parameters">
<description>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.java Fri Jul 27 13:20:26 2007
@@ -14,14 +14,17 @@
package org.apache.tapestry.link;
-import org.apache.tapestry.*;
+import java.util.List;
+
+import org.apache.tapestry.IActionListener;
+import org.apache.tapestry.IDirect;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.IScript;
import org.apache.tapestry.engine.DirectServiceParameter;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.listener.ListenerInvoker;
-import java.util.List;
-
/**
* A component for creating a link using the direct service; used for actions that are not dependant
* on dynamic page state. [ <a href="../../../../../ComponentReference/DirectLink.html">Component
@@ -85,7 +88,8 @@
/**
* Invoked by the direct service to trigger the application-specific action by notifying the
- * {@link IActionListener listener}.
+ * {@link IActionListener listener}. If the listener parameter is not bound, attempt to locate
+ * an implicit listener named by the capitalized component id, prefixed by "do".
*
* @throws org.apache.tapestry.StaleSessionException
* if the component is stateful, and the session is new.
@@ -96,8 +100,8 @@
IActionListener listener = getListener();
if (listener == null)
- throw Tapestry.createRequiredParameterException(this, "listener");
-
+ listener = getContainer().getListeners().getImplicitListener(this);
+
getListenerInvoker().invokeListener(listener, this, cycle);
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.jwc
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.jwc?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.jwc (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLink.jwc Fri Jul 27 13:20:26 2007
@@ -27,7 +27,14 @@
listener.
</description>
- <parameter name="listener" required="yes"/>
+ <parameter name="listener">
+ <description>
+ The listener to be called when the link is clicked. If none is provided,
+ Tapestry will attempt to find a listener with the capitalized id of the
+ component, prefixed by "do". For example, jwcid="clear@DirectLink" would
+ have a listener called doClear().
+ </description>
+ </parameter>
<parameter name="parameters">
<description>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMap.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMap.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMap.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMap.java Fri Jul 27 13:20:26 2007
@@ -18,6 +18,7 @@
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.IActionListener;
+import org.apache.tapestry.IComponent;
/**
* @author Howard M. Lewis Ship
@@ -40,6 +41,20 @@
* if the listener can not be created.
*/
IActionListener getListener(String name);
+
+ /**
+ * Gets a listener on the given component generated from the capitalized
+ * component id, prefixed by "do". For example, jwcid="clear@DirectLink"
+ * would have a listener called doClear().
+ *
+ * @param component
+ * the component whose id is used to make up the name of the
+ * expected listener
+ * @returns an object implementing {@link IActionListener}.
+ * @throws ApplicationRuntimeException
+ * if the listener can not be found on the component
+ */
+ IActionListener getImplicitListener(IComponent component);
/**
* Returns an unmodifiable collection of the names of the listeners
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMapImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMapImpl.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMapImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMapImpl.java Fri Jul 27 13:20:26 2007
@@ -14,15 +14,17 @@
package org.apache.tapestry.listener;
-import org.apache.hivemind.ApplicationRuntimeException;
-import org.apache.hivemind.util.Defense;
-import org.apache.tapestry.IActionListener;
-
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.util.Defense;
+import org.apache.tapestry.IActionListener;
+import org.apache.tapestry.IComponent;
+import org.apache.tapestry.TapestryUtils;
+
/**
* @author Howard M. Lewis Ship
* @since 4.0
@@ -68,7 +70,23 @@
return result;
}
- private IActionListener createListener(String name)
+ public IActionListener getImplicitListener(IComponent component)
+ {
+ IActionListener listener;
+ String generatedName = "do" + TapestryUtils.capitalize(component.getId());
+ try
+ {
+ listener = getListener(generatedName);
+ }
+ catch (ApplicationRuntimeException e)
+ {
+ throw new ApplicationRuntimeException(ListenerMessages.noImplicitListenerMethodFound(generatedName, component), component, null, e);
+ }
+
+ return listener;
+ }
+
+ private IActionListener createListener(String name)
{
ListenerMethodInvoker invoker = (ListenerMethodInvoker) _invokers.get(name);
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMessages.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMessages.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMessages.java Fri Jul 27 13:20:26 2007
@@ -50,4 +50,9 @@
return _formatter.format("no-listener-method-found", name, new Integer(Tapestry
.size(serviceParameters)), target);
}
+
+ static String noImplicitListenerMethodFound(String name, Object target)
+ {
+ return _formatter.format("no-implicit-listener-method-found", name, target);
+ }
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerStrings.properties?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerStrings.properties (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/listener/ListenerStrings.properties Fri Jul 27 13:20:26 2007
@@ -16,3 +16,4 @@
unable-to-invoke-method=Unable to invoke method {0} on {1}: {2}
listener-method-failure=Failure invoking listener method ''{0}'' on {1}: {2}
no-listener-method-found=No listener method named ''{0}'' suitable for {1,choice,0#no listener parameters|1#one listener parameter|1<{1,number} listener parameters} found in {2}.
+no-implicit-listener-method-found=No implicit listener method named ''{0}'' found in {1}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.java Fri Jul 27 13:20:26 2007
@@ -1,8 +1,22 @@
package org.apache.tapestry.scriptaculous;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.util.Defense;
-import org.apache.tapestry.*;
+import org.apache.tapestry.IActionListener;
+import org.apache.tapestry.IDirect;
+import org.apache.tapestry.IForm;
+import org.apache.tapestry.IMarkupWriter;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.IScript;
+import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.coerce.ValueConverter;
import org.apache.tapestry.engine.DirectServiceParameter;
import org.apache.tapestry.engine.IEngineService;
@@ -18,9 +32,6 @@
import org.apache.tapestry.util.SizeRestrictingIterator;
import org.apache.tapestry.valid.ValidatorException;
-import java.text.ParseException;
-import java.util.*;
-
/**
* Implementation of the <a href="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Ajax.Autocompleter</a> in
* the form of a {@link org.apache.tapestry.form.TextField} like component with the additional ability to dynamically suggest
@@ -318,12 +329,14 @@
/**
* Triggers the listener. The parameters passed are the current text
* and those specified in the parameters parameter of the component.
+ * If the listener parameter is not bound, attempt to locate an implicit
+ * listener named by the capitalized component id, prefixed by "do".
*/
public void trigger(IRequestCycle cycle)
{
IActionListener listener = getListener();
if (listener == null)
- throw Tapestry.createRequiredParameterException(this, "listener");
+ listener = getContainer().getListeners().getImplicitListener(this);
Object[] params = cycle.getListenerParameters();
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.jwc
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.jwc?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.jwc (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/scriptaculous/Suggest.jwc Fri Jul 27 13:20:26 2007
@@ -25,11 +25,15 @@
Provides dynamic suggestion list autocompletion for textarea and input text fields.
</description>
- <parameter name="listener" required="true">
+ <parameter name="listener">
<description>
Listener method to invoke for each field search request. This listener
- should expect to get exactly one paramter of type String, which is the value that was typed in to the field. It may additionally
- receive extra parameters if the parameters parameter is used.
+ should expect to get exactly one parameter of type String, which is the
+ value that was typed in to the field. It may additionally receive
+ extra parameters if the parameters parameter is used. If no listener
+ is provided, Tapestry will attempt to find a listener with the
+ capitalized id of the component, prefixed by "do". For example,
+ jwcid="nameSearch@Suggest" would have a listener called doNameSearch().
</description>
</parameter>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/TapestryUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/TapestryUtilsTest.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/TapestryUtilsTest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/TapestryUtilsTest.java Fri Jul 27 13:20:26 2007
@@ -225,6 +225,19 @@
{ "", "fred", "", "barney", "", "" }, TapestryUtils.split(",fred,,barney,,"));
}
+ public void testCapitalizeNothing()
+ {
+ assertEquals(null, TapestryUtils.capitalize(null));
+ assertEquals("", TapestryUtils.capitalize(""));
+ }
+
+ public void testCapitalizeNormal()
+ {
+ assertEquals("Test", TapestryUtils.capitalize("test"));
+ assertEquals("Test", TapestryUtils.capitalize("Test"));
+ assertEquals("123abc", TapestryUtils.capitalize("123abc"));
+ }
+
public void testEnquote()
{
assertEquals("'simple'", TapestryUtils.enquote("simple"));
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/listener/TestListenerMap.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/listener/TestListenerMap.java?view=diff&rev=560371&r1=560370&r2=560371
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/listener/TestListenerMap.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/listener/TestListenerMap.java Fri Jul 27 13:20:26 2007
@@ -21,7 +21,9 @@
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.BaseComponentTestCase;
import org.apache.tapestry.IActionListener;
+import org.apache.tapestry.IComponent;
import org.apache.tapestry.IRequestCycle;
+import static org.easymock.EasyMock.expect;
import org.testng.annotations.Test;
/**
@@ -120,6 +122,59 @@
assertEquals("Object *TARGET* does not implement a listener method named 'foobar'.", ex
.getMessage());
assertSame(target, ex.getComponent());
+ }
+
+ verify();
+ }
+
+ public void test_Get_Implicit_Listener()
+ {
+ Object target = new Object();
+ IRequestCycle cycle = newCycle();
+ ListenerMethodInvoker invoker = newInvoker();
+ IComponent component = newMock(IComponent.class);
+ expect(component.getId()).andReturn("action").times(2);
+ Map map = newMap("doAction", invoker);
+
+ invoker.invokeListenerMethod(target, cycle);
+
+ replay();
+
+ ListenerMap lm = new ListenerMapImpl(target, map);
+
+ IActionListener l1 = lm.getImplicitListener(component);
+
+ l1.actionTriggered(null, cycle);
+
+ IActionListener l2 = lm.getImplicitListener(component);
+
+ verify();
+
+ assertSame(l1, l2);
+ }
+
+ public void test_Missing_Implicit_Listener()
+ {
+ ListenerMethodInvoker invoker = newInvoker();
+ IComponent component = newMock(IComponent.class);
+ expect(component.getLocation()).andReturn(null);
+ expect(component.getId()).andReturn("action");
+ Map map = newMap("method", invoker);
+
+ replay();
+
+ ListenerMap lm = new ListenerMapImpl("test", map);
+
+ try
+ {
+ lm.getImplicitListener(component);
+ unreachable();
+ }
+ catch (ApplicationRuntimeException ex)
+ {
+ assertEquals("No implicit listener method named 'doAction' found in " + component, ex
+ .getMessage());
+ assertSame(component, ex.getComponent());
}
verify();