Hi,
this is the patch to add "noAsync" parameter to DojoWidget component. It
includes documentation and a test for it (I had to resurrect ActionBinding
test private class for this).
I'm not satisfied with the way url for non async events are generated
(simply by adding a "&bteventname=<dojoevent>" parameter to the
DirectEngineService). Neverthless it works fine, later on might be added
some simple ad hoc mechanism to make more configurable this.
Let me know if the patch is ok or if you need anything more
Martino
Index:
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.java
===================================================================
---
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.java
(revision 654)
+++
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.java
(working copy)
@@ -68,6 +68,13 @@
* <div jwcid="@dojo:Widget" dojoType="..." onClick="listener:onClick"
onMouseDown="listener:onMouseDown"/>
* </pre>
* <p>
+ * It's possible to specify a list of events for which to generate non async
requests specifying the dojo events
+ * list in the noAsync parameter as a comma separated list. This is
particularly useful
+ * with menu/button widget that most of the times need normal requests to be
generated.
+ * <pre>
+ * <div jwcid="@dojo:Widget" dojoType="MenuItem2"
onClick="listener:onMenuClick" noAsync="onClick"/>
+ * </pre>
+ * </p>
* Furthermore it is poossible to connect a client side event to a javascript
function.
* For this purpose use the prefix <code>callback</code>. For example:
* </p>
@@ -137,8 +144,10 @@
renderInformalParameters(jsonWriter, cycle);
JSONObject json = jsonWriter.getAttributes();
+ Map asynclisteners = getAsyncListenerBindings();
Map listeners = getListenerBindings();
Map callbacks = getCallbackBindings();
+ removeListenersFromInputSymbols(json, asynclisteners);
removeListenersFromInputSymbols(json, listeners);
removeListenersFromInputSymbols(json, callbacks);
@@ -143,10 +152,13 @@
removeListenersFromInputSymbols(json, callbacks);
Map parms = new HashMap();
+ String url = getLink().getURL();
parms.put("component", this);
parms.put("type", getDojoType());
- parms.put("url", getLink().getURL());
+ parms.put("url", url);
+ parms.put("asyncurl", url);
parms.put("props", json.toString());
+ parms.put("asynclisteners", asynclisteners);
parms.put("listeners", listeners);
parms.put("callbacks", callbacks);
getScript().execute(this, cycle,
TapestryUtils.getPageRenderSupport(cycle, this), parms);
@@ -185,8 +197,59 @@
* Returns a [EMAIL PROTECTED] Map} of the [EMAIL PROTECTED]
org.apache.tapestry.IBinding bindings} implementing
* the [EMAIL PROTECTED] org.apache.tapestry.IActionListener} interface.
*/
+ private Map getAllListenerBindings(){
+ return getBindingsByClass(getBindingNames(),
IActionListener.class);
+ }
+
+ /**
+ * Returns a [EMAIL PROTECTED] Map} of the [EMAIL PROTECTED]
org.apache.tapestry.IBinding bindings} implementing
+ * the [EMAIL PROTECTED]
org.apache.tapestry.org.apache.tapestry.IActionListener} interface for which to
+ * generate non async requests.
+ */
public Map getListenerBindings(){
- return getBindingsByClass(getBindingNames(),
IActionListener.class);
+ Map listeners = getBindingsByClass(getBindingNames(),
IActionListener.class);
+ Map result = new HashMap();
+ String[] noAsync = constructNoAsync();
+ if (noAsync != null) {
+ for (int i = 0; i < noAsync.length; i++) {
+ if (listeners.get(noAsync[i]) != null) {
+ result.put(noAsync[i],
listeners.get(noAsync[i]));
+ }
+ }
+ }
+ return result;
+ }
+ /**
+ * Returns a [EMAIL PROTECTED] Map} of the [EMAIL PROTECTED]
org.apache.tapestry.IBinding bindings} implementing
+ * the [EMAIL PROTECTED]
org.apache.tapestry.org.apache.tapestry.IActionListener} interface for which
+ * to generate async requests.
+ */
+ public Map getAsyncListenerBindings(){
+ Map listeners = getBindingsByClass(getBindingNames(),
IActionListener.class);
+ String[] noAsync = constructNoAsync();
+ if (noAsync != null) {
+ for (int i = 0; i < noAsync.length; i++) {
+ listeners.remove(noAsync[i]);
+ }
+ }
+ return listeners;
+ }
+
+ /**
+ * Returns an array containing the names of the events for which not to
generate
+ * async requests
+ */
+ private String[] constructNoAsync() {
+ String noAsync = getNoAsync();
+ if (noAsync != null) {
+ if (noAsync.indexOf(",") != -1) {
+ return noAsync.split(",");
+ } else {
+ String[] result = {noAsync};
+ return result;
+ }
+ }
+ return null;
}
/**
@@ -225,6 +288,14 @@
return getEngine().getLink(isStateful(), dsp);
}
+ /** Returns the url to use for a non async event */
+ public String getNoAsyncEventUrl(String eventName){
+ Object[] parameters =
DirectLink.constructServiceParameters(getParameters());
+ DirectServiceParameter dsp = new DirectServiceParameter(this,
parameters);
+ return getEngine().getLink(isStateful(), dsp).getURL() + "&"
+ + BrowserEvent.NAME + "=" + eventName;
+ }
+
/**
* Invoked by the direct service to trigger the application-specific
action by notifying the
* [EMAIL PROTECTED] IActionListener listener}.
@@ -231,7 +302,7 @@
*/
public void trigger(IRequestCycle cycle) {
String event = cycle.getParameter(BrowserEvent.NAME);
- IActionListener listener =
(IActionListener)getListenerBindings().get(event);
+ IActionListener listener =
(IActionListener)getAllListenerBindings().get(event);
if (listener == null)
throw Tapestry.createRequiredParameterException(this, event);
getListenerInvoker().invokeListener(listener, this, cycle);
@@ -256,6 +327,9 @@
/**Returns listener parameters*/
public abstract Object getParameters();
+ /** Returns widget events for which to generate no async requests */
+ public abstract String getNoAsync();
+
/**
* Returns a list of children widgetIds.
* The list is always empty if [EMAIL PROTECTED] #getIsContainer()}
returns <code>false</code>.
Index:
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.jwc
===================================================================
---
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.jwc
(revision 654)
+++
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.jwc
(working copy)
@@ -63,6 +63,13 @@
</parameter>
<parameter name="style"/>
+
+ <parameter name="noAsync">
+ <description>
+ Names of the widget events no to create an async request for as
a comma separated
+ list of event names e.g. "onClick,onValueChanged"
+ </description>
+ </parameter>
<property name="children" initial-value="ognl:new java.util.ArrayList()"/>
Index:
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.script
===================================================================
---
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.script
(revision 654)
+++
C:/Data/workspace/Tacos-4.1/tacos-core/src/java/net/sf/tacos/components/dojo/DojoWidget.script
(working copy)
@@ -21,9 +21,10 @@
<input-symbol key="component" required="yes" />
<input-symbol key="type" required="yes" />
- <input-symbol key="url"/>
+ <input-symbol key="asyncurl"/>
<input-symbol key="props" required="yes" />
<input-symbol key="listeners"/>
+ <input-symbol key="asynclisteners"/>
<input-symbol key="callbacks"/>
<set key="listener" expression="component.listener"/>
@@ -47,13 +48,20 @@
<foreach key="childId" expression="component.children">
${widget}.addChild(dojo.widget.getWidgetById("${childId}"));
</foreach>
- <if expression="listeners">
- <foreach key="key" expression="listeners.keys">
+ <if expression="asynclisteners">
+ <foreach key="key" expression="asynclisteners.keys">
dojo.event.connect(${widget}, "${key}", function(e) {
- tacosLinkOnEvent("${key}",
"${url}","${component.clientId}", false);
+ tacosLinkOnEvent("${key}",
"${asyncurl}","${component.clientId}", false);
});
</foreach>
</if>
+ <if expression="listeners">
+ <foreach key="key" expression="listeners.keys">
+ dojo.event.connect(${widget}, "${key}", function() {
+
location.href="${component.getNoAsyncEventUrl(key)}" }
+ );
+ </foreach>
+ </if>
<if expression="callbacks">
<foreach key="key" expression="callbacks.keys">
dojo.event.connect(${widget}, "${key}",
"${callbacks[key].functionName}");
Index:
C:/Data/workspace/Tacos-4.1/tacos-core/src/test/net/sf/tacos/components/dojo/DojoWidgetTest.java
===================================================================
---
C:/Data/workspace/Tacos-4.1/tacos-core/src/test/net/sf/tacos/components/dojo/DojoWidgetTest.java
(revision 654)
+++
C:/Data/workspace/Tacos-4.1/tacos-core/src/test/net/sf/tacos/components/dojo/DojoWidgetTest.java
(working copy)
@@ -2,6 +2,7 @@
import net.sf.tacos.AbstractComponentTest;
import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.Location;
import org.apache.tapestry.*;
import org.apache.tapestry.engine.DirectServiceParameter;
import org.apache.tapestry.engine.IEngineService;
@@ -22,6 +23,8 @@
@Test
public class DojoWidgetTest extends AbstractComponentTest {
private static final String URL = "http://foo.baz";
+
+ private static final String NOASYNC_EVENT = "OnValueChanged";
private IMarkupWriter writer;
@@ -117,6 +120,29 @@
assertSame(result.get(name), binding);
}
+ public void testAsyncAndNoAsyncBindingOK() {
+ DojoWidget widget = createWidget(false, true);
+ IBinding asyncBinding = new ActionBinding();
+ IBinding noAsyncBinding = new ActionBinding();
+ String noAsyncEvent = NOASYNC_EVENT;
+ String asyncEvent = "onMouseOver";
+ widget.setBinding(noAsyncEvent, noAsyncBinding);
+ widget.setBinding(asyncEvent, asyncBinding);
+ trainSpecificationParameterNames();
+ replay();
+ Map noAsyncResult = widget.getListenerBindings();
+ Map asyncResult = widget.getAsyncListenerBindings();
+ verify();
+ assertFalse(asyncResult.isEmpty());
+ assertTrue(asyncResult.keySet().size() == 1);
+ assertNotNull(asyncResult.get(asyncEvent));
+ assertSame(asyncResult.get(asyncEvent), asyncBinding);
+ assertFalse(noAsyncResult.isEmpty());
+ assertTrue(noAsyncResult.keySet().size() == 1);
+ assertNotNull(noAsyncResult.get(noAsyncEvent));
+ assertSame(noAsyncResult.get(noAsyncEvent), noAsyncBinding);
+ }
+
public void testTriggerOk() {
DojoWidget widget = createWidget(false, true);
String name = "onClick";
@@ -161,7 +187,7 @@
"templateTagName", "templateTagName",
"dojoType", "DojoType",
"style", "style", "script", script,
"isContainer", isContainer,
"engine", engine, "container", containerComp,
"specification", spec,
- "listenerInvoker", listenerInvoker);
+ "listenerInvoker", listenerInvoker, "noAsync",
NOASYNC_EVENT);
container = isContained ? newMock(IDojoContainer.class) : null;
writer = newWriter();
cycle = newRequestCycle();
@@ -194,13 +220,59 @@
private void assertParams(DojoWidget widget) {
Map parms = params.getCaptured();
- assertEquals(parms.size(), 6);
+ assertEquals(parms.size(), 8);
assertEquals(parms.get("component"), widget);
assertEquals(parms.get("type"), widget.getDojoType());
assertEquals(parms.get("url"), URL);
+ assertEquals(parms.get("asyncurl"), URL);
assertEquals(parms.get("props"), new JSONObject().toString());
+ assertEquals(parms.get("asynclisteners"),
Collections.EMPTY_MAP);
+ assertEquals(parms.get("callbacks"), Collections.EMPTY_MAP);
assertEquals(parms.get("listeners"), Collections.EMPTY_MAP);
- assertEquals(parms.get("callbacks"), Collections.EMPTY_MAP);
+ }
+
+ private class ActionBinding implements IBinding, IActionListener{
+
+ public String getDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object getObject() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object getObject(Class type) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isInvariant() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void setObject(Object value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Location getLocation() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void actionTriggered(IComponent component, IRequestCycle
cycle) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public String getMethodName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Tacos-devel mailing list
Tacos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tacos-devel