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="[EMAIL PROTECTED]" 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="[EMAIL PROTECTED]" 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
- * [EMAIL PROTECTED] IActionListener listener}.
+ * [EMAIL PROTECTED] 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="[EMAIL
PROTECTED]" 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="[EMAIL
PROTECTED]"
+ * 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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="[EMAIL PROTECTED]" 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();