You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/06/09 23:10:19 UTC
svn commit: r413168 - in /tapestry/tapestry4/trunk/framework/src:
java/org/apache/tapestry/ java/org/apache/tapestry/dojo/html/
java/org/apache/tapestry/form/ java/org/apache/tapestry/internal/event/
java/org/apache/tapestry/services/impl/ test/org/apa...
Author: jkuhnert
Date: Fri Jun 9 14:10:18 2006
New Revision: 413168
URL: http://svn.apache.org/viewvc?rev=413168&view=rev
Log:
Finished connecting EventListener form based events, fixed Any component ID rendering. Still need to re-do
client side validation.
Modified:
tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/AbstractComponent.java
tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java
tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java
tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java
tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java
tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java
tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java
Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/AbstractComponent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/AbstractComponent.java?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/AbstractComponent.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/AbstractComponent.java Fri Jun 9 14:10:18 2006
@@ -54,6 +54,9 @@
private static final Map EMPTY_MAP = Collections.unmodifiableMap(new HashMap(1));
+ /** @since 4.1 */
+ protected String _clientId;
+
/**
* The page that contains the component, possibly itself (if the component is in fact, a page).
*/
@@ -300,6 +303,16 @@
*/
protected void renderIdAttribute(IMarkupWriter writer, IRequestCycle cycle)
{
+ // try to generate a client id if needed/possible
+ if (_clientId == null) {
+ String id = getBoundId();
+ if (id == null) id = getId();
+
+ _clientId =
+ cycle.getUniqueId(TapestryUtils
+ .convertTapestryIdToNMToken(id));
+ }
+
String id = getClientId();
if (id != null)
writer.attribute("id", id);
@@ -432,12 +445,24 @@
*/
public String getClientId()
{
- if (_bindings == null)
+ if (_clientId != null)
+ return _clientId;
+
+ String boundId = getBoundId();
+ if (boundId == null)
return getId();
+ return boundId;
+ }
+
+ String getBoundId()
+ {
+ if (_bindings == null)
+ return null;
+
IBinding id = (IBinding)_bindings.get("id");
if (id == null)
- return getId();
+ return null;
return id.getObject().toString();
}
Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script Fri Jun 9 14:10:18 2006
@@ -37,7 +37,6 @@
<foreach expression="formEvent[1]" key="formName">
tapestry.form.submitAsync("${formName}", "test", content);
- dojo.log.debug("Need to submit to form ${formName}");
</foreach>
});
</foreach>
Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java Fri Jun 9 14:10:18 2006
@@ -15,6 +15,7 @@
package org.apache.tapestry.form;
import org.apache.tapestry.FormBehavior;
+import org.apache.tapestry.IForm;
import org.apache.tapestry.IRender;
import org.apache.tapestry.engine.ILink;
@@ -59,4 +60,11 @@
* {@link FormConstants#SUBMIT_CANCEL} or {@link FormConstants#SUBMIT_REFRESH}.
*/
String rewind();
+
+ /**
+ * Gets a reference to the previously stored {@link IForm}.
+ * @return The form this object is managing/supporting.
+ * @since 4.1
+ */
+ IForm getForm();
}
Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java Fri Jun 9 14:10:18 2006
@@ -190,6 +190,14 @@
}
/**
+ * {@inheritDoc}
+ */
+ public IForm getForm()
+ {
+ return _form;
+ }
+
+ /**
* Adds an event handler for the form, of the given type.
*/
@@ -559,7 +567,7 @@
// New, handles cases where an eventlistener
// causes a form submission.
BrowserEvent event = new BrowserEvent(_cycle);
- _form.getEventInvoker().invokeListeners(_form, _cycle, event);
+ _form.getEventInvoker().invokeFormListeners(this, _cycle, event);
int expected = _allocatedIds.size();
Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java Fri Jun 9 14:10:18 2006
@@ -19,6 +19,8 @@
import java.util.Map;
import java.util.Set;
+import org.apache.tapestry.event.BrowserEvent;
+
/**
* Represents a configured listener/event(s) binding for a
@@ -156,5 +158,33 @@
return _formEventMap.keySet();
}
-
+ /**
+ * Creates a list of listeners bound to a particular form
+ * and client side browser event.
+ *
+ * @param formId
+ * The form to find listeners for.
+ * @param event
+ * The browser event that generated the request.
+ * @param append
+ * The optional list to add the listeners to.
+ * @return The list of listeners to invoke for the form and event passed in,
+ * will be empty if none found.
+ */
+ public List getFormEventListeners(String formId, BrowserEvent event, List append)
+ {
+ List ret = (append == null) ? new ArrayList() : append;
+
+ List listeners = (List)_formEventMap.get(event.getName());
+ if (listeners == null)
+ return ret;
+
+ for (int i=0; i < listeners.size(); i++) {
+ EventBoundListener listener = (EventBoundListener)listeners.get(i);
+ if (listener.getFormId().equals(formId))
+ ret.add(listener);
+ }
+
+ return ret;
+ }
}
Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java Fri Jun 9 14:10:18 2006
@@ -13,16 +13,20 @@
// limitations under the License.
package org.apache.tapestry.services.impl;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.hivemind.util.Defense;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IForm;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.event.BrowserEvent;
import org.apache.tapestry.event.ResetEventListener;
+import org.apache.tapestry.form.FormSupport;
import org.apache.tapestry.internal.event.ComponentEventProperty;
import org.apache.tapestry.internal.event.EventBoundListener;
import org.apache.tapestry.listener.ListenerInvoker;
@@ -95,6 +99,45 @@
}
/**
+ * Causes the configured listeners for the passed {@link FormSupport}'s {@link IForm) to
+ * be invoked, if mapped to this request/event.
+ *
+ * @param formSupport
+ * The form support object being rendered.
+ * @param cycle
+ * The associated request.
+ * @param event
+ * The event that started it all.
+ */
+ public void invokeFormListeners(FormSupport formSupport, final IRequestCycle cycle,
+ BrowserEvent event)
+ {
+ IForm component = formSupport.getForm();
+ String id = component.getId();
+
+ List listeners = getFormEvents(id, event);
+
+ for (int i=0; i < listeners.size(); i++) {
+ EventBoundListener eventListener = (EventBoundListener)listeners.get(i);
+
+ final IComponent container =
+ (component.getContainer() == null) ? component : component.getContainer();
+
+ final IActionListener listener =
+ container.getListeners().getListener(eventListener.getMethodName());
+
+ // defer execution until after form is done rewinding
+ component.addDeferredRunnable(new Runnable()
+ {
+ public void run()
+ {
+ _invoker.invokeListener(listener, container, cycle);
+ }
+ });
+ }
+ }
+
+ /**
* Adds a deferred event listener binding for the specified component.
*
* @param componentId
@@ -176,6 +219,38 @@
}
return prop;
+ }
+
+ /**
+ * Listeners mapped with a submitForm=formId binding are a special case for the
+ * invokers, as we can't just invoke them but must plug the EventListener in to
+ * the normal form rewind logic. This handles mapping an incoming form submission
+ * to our pre-mapped form event invokers.
+ *
+ * @param id
+ * The component id of the form.
+ * @param event
+ * The browser event based on.
+ * @return List of listeners on specified form/event combination, will be empty
+ * list if none found.
+ */
+ List getFormEvents(String id, BrowserEvent event)
+ {
+ List ret = new ArrayList();
+
+ Iterator it = _components.values().iterator();
+ while (it.hasNext()) {
+ ComponentEventProperty prop = (ComponentEventProperty)it.next();
+ prop.getFormEventListeners(id, event, ret);
+ }
+
+ it = _elements.values().iterator();
+ while (it.hasNext()) {
+ ComponentEventProperty prop = (ComponentEventProperty)it.next();
+ prop.getFormEventListeners(id, event, ret);
+ }
+
+ return ret;
}
/**
Modified: tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java (original)
+++ tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java Fri Jun 9 14:10:18 2006
@@ -16,6 +16,7 @@
import java.util.List;
import org.apache.hivemind.test.HiveMindTestCase;
+import org.apache.tapestry.event.BrowserEvent;
/**
@@ -62,6 +63,25 @@
assertNotNull(prop.getFormEventListeners("onFoo"));
List listeners = prop.getFormEventListeners("onFoo");
+ assertEquals(1, listeners.size());
+
+ EventBoundListener listener = (EventBoundListener)listeners.get(0);
+ assertEquals("compid", listener.getComponentId());
+ assertEquals("formid", listener.getFormId());
+ assertFalse(listener.isValidateForm());
+
+ assertEquals("doFoo", listener.getMethodName());
+ }
+
+ public void testGetFormEvents()
+ {
+ String[] events = {"onFoo"};
+ ComponentEventProperty prop = new ComponentEventProperty("compid");
+ BrowserEvent event = new BrowserEvent("onFoo", null);
+
+ prop.addListener(events, "doFoo", "formid", false);
+
+ List listeners = prop.getFormEventListeners("formid", event, null);
assertEquals(1, listeners.size());
EventBoundListener listener = (EventBoundListener)listeners.get(0);
Modified: tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java?rev=413168&r1=413167&r2=413168&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java (original)
+++ tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java Fri Jun 9 14:10:18 2006
@@ -17,12 +17,17 @@
import java.util.List;
import java.util.Map;
+import org.apache.hivemind.test.AggregateArgumentsMatcher;
+import org.apache.hivemind.test.ArgumentMatcher;
import org.apache.tapestry.BaseComponentTestCase;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IForm;
import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.IgnoreMatcher;
import org.apache.tapestry.event.BrowserEvent;
import org.apache.tapestry.event.EventTarget;
+import org.apache.tapestry.form.FormSupport;
import org.apache.tapestry.internal.event.ComponentEventProperty;
import org.apache.tapestry.listener.ListenerInvoker;
import org.apache.tapestry.listener.ListenerMap;
@@ -126,6 +131,53 @@
replayControls();
invoker.invokeListeners(comp, cycle, event);
+
+ verifyControls();
+ }
+
+ public void testInvokeFormListener()
+ {
+ IRequestCycle cycle = newCycle();
+ IForm form = newForm();
+ FormSupport formSupport = (FormSupport) newMock(FormSupport.class);
+ Runnable runnable = (Runnable)newMock(Runnable.class);
+
+ ListenerInvoker listenerInvoker = (ListenerInvoker)newMock(ListenerInvoker.class);
+ ListenerMap listenerMap = (ListenerMap)newMock(ListenerMap.class);
+ IActionListener listener = (IActionListener)newMock(IActionListener.class);
+
+ Map tprops = new HashMap();
+ tprops.put("id", "testId");
+ BrowserEvent event = new BrowserEvent("onSelect", new EventTarget(tprops));
+
+ ComponentEventInvoker invoker = new ComponentEventInvoker();
+ invoker.setListenerInvoker(listenerInvoker);
+
+ invoker.addEventListener("testId", new String[] { "onSelect" }, "fooListener",
+ "form1", false);
+
+ formSupport.getForm();
+ setReturnValue(formSupport, form);
+ form.getId();
+ setReturnValue(form, "form1");
+
+ form.getContainer();
+ setReturnValue(form, form);
+ form.getContainer();
+ setReturnValue(form, form);
+ form.getListeners();
+ setReturnValue(form, listenerMap);
+
+ listenerMap.getListener("fooListener");
+ setReturnValue(listenerMap, listener);
+
+ form.addDeferredRunnable(runnable);
+ ArgumentMatcher ignore = new IgnoreMatcher();
+ getControl(form).setMatcher(new AggregateArgumentsMatcher(new ArgumentMatcher[] { ignore }));
+
+ replayControls();
+
+ invoker.invokeFormListeners(formSupport, cycle, event);
verifyControls();
}