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/17 18:52:20 UTC
cvs commit: jakarta-tapestry/framework/src/java/org/apache/tapestry/valid IValidationDelegate.java
hlship 2005/06/17 09:52:19
Modified: . status.xml
framework/src/documentation/content/xdocs/tapestry/ComponentReference
Form.xml
framework/src/java/org/apache/tapestry/form
FormSupportImpl.java Form.java Form.jwc
framework/src/test/org/apache/tapestry/form
TestFormSupport.java
framework/src/java/org/apache/tapestry/wml Go.jwc Go.java
src/documentation/content/xdocs index.xml
framework/src/java/org/apache/tapestry FormBehavior.java
framework/src/java/org/apache/tapestry/valid
IValidationDelegate.java
Added: framework/src/java/org/apache/tapestry/form FormSupport.java
FormConstants.java
framework/src/test/org/apache/tapestry/form TestForm.java
Removed: framework/src/java/org/apache/tapestry FormSupport.java
Log:
Add cancel and refresh listener parameters to Form.
Revision Changes Path
1.135 +1 -0 jakarta-tapestry/status.xml
Index: status.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/status.xml,v
retrieving revision 1.134
retrieving revision 1.135
diff -u -r1.134 -r1.135
--- status.xml 16 Jun 2005 20:57:10 -0000 1.134
+++ status.xml 17 Jun 2005 16:52:19 -0000 1.135
@@ -83,6 +83,7 @@
<action type="add" dev="PF">Refactored and expanded validation functionality to include DatePicker, PropertySelection, RadioGroup, Select, TextArea, TextField, Upload, contrib:Palette, and contrib:MultiplePropertySelection.</action>
<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>
</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.3 +89 -9 jakarta-tapestry/framework/src/documentation/content/xdocs/tapestry/ComponentReference/Form.xml
Index: Form.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/documentation/content/xdocs/tapestry/ComponentReference/Form.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Form.xml 6 Jan 2005 02:17:15 -0000 1.2
+++ Form.xml 17 Jun 2005 16:52:19 -0000 1.3
@@ -28,11 +28,17 @@
<body>
-<p> <strong>THIS PAGE UNDER CONSTRUCTION</strong>
+<p> A Form component must enclose the other form element components (such as &TextField; and &Checkbox;).
+ It manages the rendering of the form as well as processing when the form is submitted
+ (known as "rewinding" the form). In traditional web applications, the developer is responsible
+ for providing a name for each form and each form control element; in Tapestry, the Form component
+ generates its own unique name, and unique names for each enclosed component ... this is necessary
+ to support advanced features such as loops within forms.
</p>
<p>
- <strong>See also:</strong>
+ <strong>See also: <link href="&apiroot;/form/Form.html">org.apache.tapestry.form.Form</link>,
+ &IValidationDelegate;</strong>
</p>
<section>
@@ -45,28 +51,102 @@
<th>Direction</th>
<th>Required</th>
<th>Default</th>
+ <th>Default Binding</th>
<th>Description</th>
</tr>
+
+ <tr>
+ <td>method</td> <td>string</td> <td>in</td> <td>no</td> <td>post</td> <td>literal</td>
+ <td>Method used by the form when it is submitted.</td>
+ </tr>
+
+ <tr>
+ <td>listener</td> <td>&IActionListener;</td> <td>in</td> <td>no</td>
+ <td/> <td>listener</td>
+ <td>Default listener to be invoked when the form is submitted. Invoked
+ after the form has rewond (all enclosed components have read query parameters
+ and updated server-side properties), and after any listeners related
+ to submit components (&Submit;, &ImageSubmit;, etc.) have been invoked.</td>
+ </tr>
+
+ <tr>
+ <td>cancel</td> <td>&IActionListener;</td> <td>in</td> <td>no</td>
+ <td/> <td>listener</td>
+ <td>Listener used when a form is cancelled, overriding the default listener. Forms
+ are cancelled by invoking the client-side JavaScript function
+ document.<em>form-name</em>.events.cancel(). A cancelled form <em>does not</em> rewind.
+ If no cancel listener is provided, then the normal listener will be used.</td>
+ </tr>
+
+ <tr>
+ <td>refresh</td> <td>&IActionListener;</td> <td>in</td> <td>no</td>
+ <td/> <td>listener</td>
+ <td>
+ Listener used when a form is refreshed, overriding the default listener. A refreshed form bypasses
+ input field validation on the client side, though validation still
+ occurs on the server side. If no refresh listener is provided, then the normal listener
+ will be used.
+ </td>
+ </tr>
+
+ <tr>
+ <td>stateful</td> <td>boolean</td> <td>in</td> <td>no</td> <td>true</td> <td>ognl</td>
+ <td>
+ If true (the default), then an active session is required when the
+ form is submitted, if there was an active session when the
+ form was rendered.
+ </td>
+ </tr>
+
+ <tr>
+ <td>direct</td> <td>boolean</td> <td>in</td> <td>no</td> <td>true</td> <td>ognl</td>
+ <td> If true (the default), then the more efficient direct service is used.
+ If false, then the action service is used. The action service requires
+ rewinding of the entire page, and is rarely (if ever) used.</td>
+ </tr>
+
+ <tr>
+ <td>delegate</td> <td>&IValidationDelegate;</td> <td>in</td> <td>no</td>
+ <td>default instance</td>
+ <td>ognl</td>
+ <td>
+ An object that tracks user input and input field errors, and decorates
+ fields and field labels. This is typically overriden to provide
+ an application-specific look and feel.
+ </td>
+ </tr>
+
+ <tr>
+ <td>clientValidationEnabled</td>
+ <td>boolean</td> <td>in</td> <td>no</td> <td>false</td> <td>ognl</td>
+ <td>
+ If true, then client-side validation will be enabled for components
+ that support it (such as &TextField;).
+ </td>
+ </tr>
</table>
+
<p>
- Body: <strong>removed / allowed</strong>
+ Body: <strong>allowed</strong>
</p>
<p>
- Informal parameters: <strong>allowed / forbidden</strong>
+ Informal parameters: <strong>allowed</strong>
</p>
<p>
- Reserved parameters: <em>none</em>
+ Reserved parameters: action, enctype, name, onsubmit, onreset
</p>
-</section>
-
-<section>
- <title>Examples</title>
+<p>
+A note about clientValidationEnabled: This refers to the revamped input validation support
+that debuts in Tapestry 4.0. The older validation system, centered around the &ValidField; component,
+still requires that clientScriptingEnabled be set on individual &IValidators;.
+</p>
</section>
+
</body>
</document>
\ No newline at end of file
1.9 +31 -4 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java
Index: FormSupportImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- FormSupportImpl.java 17 Jun 2005 13:28:01 -0000 1.8
+++ FormSupportImpl.java 17 Jun 2005 16:52:19 -0000 1.9
@@ -30,7 +30,6 @@
import org.apache.hivemind.Resource;
import org.apache.hivemind.util.ClasspathResource;
import org.apache.hivemind.util.Defense;
-import org.apache.tapestry.FormSupport;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
@@ -92,6 +91,18 @@
_standardReservedIds = Collections.unmodifiableSet(set);
}
+ private final static Set _submitModes;
+
+ static
+ {
+ Set set = new HashSet();
+ set.add(FormConstants.SUBMIT_CANCEL);
+ set.add(FormConstants.SUBMIT_NORMAL);
+ set.add(FormConstants.SUBMIT_REFRESH);
+
+ _submitModes = Collections.unmodifiableSet(set);
+ }
+
/**
* Used when rewinding the form to figure to match allocated ids (allocated during the rewind)
* against expected ids (allocated in the previous request cycle, when the form was rendered).
@@ -487,12 +498,19 @@
return eventManager;
}
- public void rewind()
+ public String rewind()
{
- reinitializeIdAllocatorForRewind();
-
_form.getDelegate().clear();
+ String mode = _cycle.getParameter(SUBMIT_MODE);
+
+ // On a cancel, don't bother rendering the body or anything else at all.
+
+ if (FormConstants.SUBMIT_CANCEL.equals(mode))
+ return mode;
+
+ reinitializeIdAllocatorForRewind();
+
_form.renderBody(_writer, _cycle);
int expected = _allocatedIds.size();
@@ -510,6 +528,15 @@
}
runDeferredRunnables();
+
+ if (_submitModes.contains(mode))
+ return mode;
+
+ // Either something wacky on the client side, or a client without
+ // javascript enabled.
+
+ return FormConstants.SUBMIT_NORMAL;
+
}
private void runDeferredRunnables()
1.19 +33 -3 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.java
Index: Form.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- Form.java 15 May 2005 22:56:36 -0000 1.18
+++ Form.java 17 Jun 2005 16:52:19 -0000 1.19
@@ -17,7 +17,6 @@
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.tapestry.AbstractComponent;
-import org.apache.tapestry.FormSupport;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IDirect;
@@ -53,6 +52,10 @@
* Starting in release 1.0.2, a Form can use either the direct service or the action service. The
* default is the direct service, even though in earlier releases, only the action service was
* available.
+ * <p>
+ * Release 4.0 adds two new listener, {@link #getCancel()} and {@link #getRefresh()} and
+ * corresponding client-side behavior to force a form to refresh (update, bypassing input field
+ * validation) or cancel (update immediately).
*
* @author Howard Lewis Ship, David Solis
*/
@@ -220,9 +223,11 @@
if (isRewinding())
{
- _formSupport.rewind();
+ String submitType = _formSupport.rewind();
+
+ IActionListener listener = findListener(submitType);
- getListenerInvoker().invokeListener(getListener(), this, cycle);
+ getListenerInvoker().invokeListener(listener, this, cycle);
// Abort the rewind render.
@@ -245,6 +250,25 @@
_formSupport.render(getMethod(), _renderInformalParameters, link);
}
+ IActionListener findListener(String mode)
+ {
+ IActionListener result = null;
+
+ if (mode.equals(FormConstants.SUBMIT_CANCEL))
+ result = getCancel();
+ else if (mode.equals(FormConstants.SUBMIT_REFRESH))
+ result = getRefresh();
+
+ // If not cancel or refresh, or the corresponding listener
+ // is itself null, then use the default listener
+ // (which may be null as well!).
+
+ if (result == null)
+ result = getListener();
+
+ return result;
+ }
+
/**
* Construct a form name for use with the action service. This implementation returns "Form"
* appended with the actionId.
@@ -346,6 +370,12 @@
/** listener parameter, may be null */
public abstract IActionListener getListener();
+ /** cancel parameter, may be null */
+ public abstract IActionListener getCancel();
+
+ /** refresh parameter, may be null */
+ public abstract IActionListener getRefresh();
+
/** method parameter */
public abstract String getMethod();
1.13 +20 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.jwc
Index: Form.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.jwc,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Form.jwc 6 Jun 2005 18:48:41 -0000 1.12
+++ Form.jwc 17 Jun 2005 16:52:19 -0000 1.13
@@ -31,7 +31,7 @@
<parameter name="method" default-value="post" default-binding="literal">
<description>
- The method used by the form when it is submitted, defaults to POST.
+ The method used by the form when it is submitted, defaults to "post".
</description>
</parameter>
@@ -42,6 +42,22 @@
</description>
</parameter>
+ <parameter name="cancel" default-binding="listener">
+ <description>
+ Object invoked when the form is cancelled (a special type of form submission).
+ The cancel listener (if any) overrides the standard listener. Other properties
+ will not be affected by the rewind.
+ </description>
+ </parameter>
+
+ <parameter name="refresh" default-binding="listener">
+ <description>
+ Object invoked when the form is refreshed (a special type of form submission).
+ The refresh listener (if any) overrides the standard listener.
+ Other properties managed by enclosed components will be updated.
+ </description>
+ </parameter>
+
<parameter name="stateful" default-value="true" default-binding="ognl">
<description>
If true (the default), then an active session is required when the
@@ -73,6 +89,9 @@
<reserved-parameter name="action"/>
<reserved-parameter name="name"/>
+ <reserved-parameter name="onsubmit"/>
+ <reserved-parameter name="onreset"/>
+ <reserved-parameter name="enctype"/>
<inject property="directService" object="engine-service:direct"/>
<inject property="actionService" object="engine-service:action"/>
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormSupport.java
Index: FormSupport.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.form;
import org.apache.tapestry.FormBehavior;
import org.apache.tapestry.IRender;
import org.apache.tapestry.engine.ILink;
/**
* Interface for a utility object that encapsulates the majority of the
* {@link org.apache.tapestry.form.Form}'s behavior.
*
* @author Howard M. Lewis Ship
* @since 4.0
*/
public interface FormSupport extends FormBehavior
{
/**
* Invoked when the form is rendering. This should only be invoked by the {@link Form}
* component.
*
* @param method
* the HTTP method ("get" or "post")
* @param informalParametersRenderer
* object that will render informal parameters
* @param link
* The link to which the form will submit (encapsulating the URL and the query
* parameters)
*/
public void render(String method, IRender informalParametersRenderer, ILink link);
/**
* Invoked to rewind the form, which renders the body of the form, allowing form element
* components to pull data from the request and update page properties. This should only be
* invoked by the {@link Form} component.
*
* @return a code indicating why the form was submitted: {@link FormConstants#SUBMIT_NORMAL},
* {@link FormConstants#SUBMIT_CANCEL} or {@link FormConstants#SUBMIT_REFRESH}.
*/
public String rewind();
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormConstants.java
Index: FormConstants.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.form;
/**
* Constants used by the Form component.
*
* @author Howard Lewis Ship
* @since 4.0
*/
public class FormConstants
{
/**
* Normal submit of the form, typically by the user clicking a submit control.
*/
public static final String SUBMIT_NORMAL = "submit";
/**
* Indicates that the form was cancelled. A form is cancelled on the client side when the
* JavaScript function document.<em>form-name</em>.events.cancel() is invoked.
*/
public static final String SUBMIT_CANCEL = "cancel";
/**
* Indicates that the form was submitted to force a refresh. Most client-side submit listeners
* will have been skipped (particularily, those related to validaton). A form is submitted for
* refresh on the client side when the JavaScript function document.<em>form-name</em>.events.refresh()
* is invoked.
*/
public static final String SUBMIT_REFRESH = "refresh";
}
1.9 +123 -19 jakarta-tapestry/framework/src/test/org/apache/tapestry/form/TestFormSupport.java
Index: TestFormSupport.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/form/TestFormSupport.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TestFormSupport.java 17 Jun 2005 13:28:01 -0000 1.8
+++ TestFormSupport.java 17 Jun 2005 16:52:19 -0000 1.9
@@ -18,7 +18,6 @@
import org.apache.hivemind.Location;
import org.apache.hivemind.test.HiveMindTestCase;
import org.apache.hivemind.util.ClasspathResource;
-import org.apache.tapestry.FormSupport;
import org.apache.tapestry.IEngine;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRender;
@@ -246,7 +245,7 @@
replayControls();
- fs.rewind();
+ assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
verifyControls();
}
@@ -335,7 +334,7 @@
trainHidden(writer, "formids", "");
trainHidden(writer, "service", "fred");
trainHidden(writer, "submitmode", "");
-
+
nested.close();
writer.end();
@@ -434,7 +433,7 @@
trainHidden(writer, "formids", "");
trainHidden(writer, "service", "fred");
trainHidden(writer, "submitmode", "");
-
+
nested.close();
writer.end();
@@ -709,7 +708,7 @@
trainHidden(writer, "action", "fred");
trainHidden(writer, "reservedids", "action");
trainHidden(writer, "submitmode", "");
-
+
nested.close();
writer.end();
@@ -804,7 +803,7 @@
trainHidden(writer, "formids", "");
trainHidden(writer, "service", "fred");
trainHidden(writer, "submitmode", "");
-
+
nested.close();
writer.end();
@@ -861,7 +860,7 @@
replayControls();
- fs.rewind();
+ assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
verifyControls();
}
@@ -1146,7 +1145,7 @@
trainHidden(writer, "formids", "barney");
trainHidden(writer, "service", "fred");
trainHidden(writer, "submitmode", "");
-
+
nested.close();
writer.end();
@@ -1158,7 +1157,7 @@
verifyControls();
}
-public void testSimpleRenderWithDeferredRunnable()
+ public void testSimpleRenderWithDeferredRunnable()
{
MockControl writerc = newControl(IMarkupWriter.class);
IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
@@ -1221,7 +1220,7 @@
support.addExternalScript(new ClasspathResource(getClassResolver(),
"/org/apache/tapestry/form/Form.js"));
-
+
support
.addInitializationScript("var myform_events = new FormEventManager(document.myform);");
@@ -1252,7 +1251,7 @@
trainHidden(writer, "formids", "");
trainHidden(writer, "service", "fred");
trainHidden(writer, "submitmode", "");
-
+
// EasyMock can't fully verify that this gets called at the right moment, nor can we truly
// prove (well, except by looking at the code), that the deferred runnables execute at the
// right time.
@@ -1268,7 +1267,9 @@
fs.render("post", render, link);
verifyControls();
- } public void testSimpleRewind()
+ }
+
+ public void testSimpleRewind()
{
IMarkupWriter writer = newWriter();
@@ -1309,7 +1310,99 @@
replayControls();
- fs.rewind();
+ assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
+
+ verifyControls();
+ }
+
+ public void testRefreshRewind()
+ {
+ IMarkupWriter writer = newWriter();
+
+ MockControl cyclec = newControl(IRequestCycle.class);
+ IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
+
+ IValidationDelegate delegate = newDelegate();
+
+ MockControl enginec = newControl(IEngine.class);
+ IEngine engine = (IEngine) enginec.getMock();
+
+ MockForm form = new MockForm(delegate);
+
+ cycle.isRewound(form);
+ cyclec.setReturnValue(true);
+
+ cycle.getEngine();
+ cyclec.setReturnValue(engine);
+
+ engine.getClassResolver();
+ enginec.setReturnValue(getClassResolver());
+
+ replayControls();
+
+ final FormSupport fs = new FormSupportImpl(writer, cycle, form);
+
+ verifyControls();
+
+ delegate.clear();
+
+ trainCycleForRewind(cyclec, cycle, "refresh", "barney", null);
+
+ final IFormComponent component = newFormComponent("barney", "barney");
+
+ IRender body = newComponentRenderBody(fs, component, writer);
+
+ form.setBody(body);
+
+ replayControls();
+
+ assertEquals(FormConstants.SUBMIT_REFRESH, fs.rewind());
+
+ verifyControls();
+ }
+
+ public void testCancelRewind()
+ {
+ IMarkupWriter writer = newWriter();
+
+ MockControl cyclec = newControl(IRequestCycle.class);
+ IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
+
+ IValidationDelegate delegate = newDelegate();
+
+ MockControl enginec = newControl(IEngine.class);
+ IEngine engine = (IEngine) enginec.getMock();
+
+ MockForm form = new MockForm(delegate);
+
+ cycle.isRewound(form);
+ cyclec.setReturnValue(true);
+
+ cycle.getEngine();
+ cyclec.setReturnValue(engine);
+
+ engine.getClassResolver();
+ enginec.setReturnValue(getClassResolver());
+
+ replayControls();
+
+ final FormSupport fs = new FormSupportImpl(writer, cycle, form);
+
+ verifyControls();
+
+ delegate.clear();
+
+ trainGetParameter(cyclec, cycle, FormSupportImpl.SUBMIT_MODE, "cancel");
+
+ // Create a body, just to provie it doesn't get invoked.
+
+ IRender body = (IRender) newMock(IRender.class);
+
+ form.setBody(body);
+
+ replayControls();
+
+ assertEquals(FormConstants.SUBMIT_CANCEL, fs.rewind());
verifyControls();
}
@@ -1370,7 +1463,7 @@
form.setBody(body);
- fs.rewind();
+ assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
verifyControls();
}
@@ -1457,7 +1550,7 @@
trainHidden(writer, "formids", "");
trainHidden(writer, "service", "fred");
trainHidden(writer, "submitmode", "");
-
+
nested.close();
writer.end();
@@ -1476,11 +1569,22 @@
private void trainCycleForRewind(MockControl cyclec, IRequestCycle cycle, String allocatedIds,
String reservedIds)
{
- cycle.getParameter(FormSupportImpl.FORM_IDS);
- cyclec.setReturnValue(allocatedIds);
+ trainCycleForRewind(cyclec, cycle, "submit", allocatedIds, reservedIds);
+ }
+
+ private void trainCycleForRewind(MockControl cyclec, IRequestCycle cycle, String submitMode,
+ String allocatedIds, String reservedIds)
+ {
+ trainGetParameter(cyclec, cycle, FormSupportImpl.SUBMIT_MODE, submitMode);
+ trainGetParameter(cyclec, cycle, FormSupportImpl.FORM_IDS, allocatedIds);
+ trainGetParameter(cyclec, cycle, FormSupportImpl.RESERVED_FORM_IDS, reservedIds);
+ }
- cycle.getParameter(FormSupportImpl.RESERVED_FORM_IDS);
- cyclec.setReturnValue(reservedIds);
+ private void trainGetParameter(MockControl cyclec, IRequestCycle cycle, String parameterName,
+ String value)
+ {
+ cycle.getParameter(parameterName);
+ cyclec.setReturnValue(value);
}
private void trainForPageSupport(MockControl cyclec, IRequestCycle cycle, String initialization)
1.1 jakarta-tapestry/framework/src/test/org/apache/tapestry/form/TestForm.java
Index: TestForm.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.form;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.components.BaseComponentTestCase;
/**
* Tests for {@link org.apache.tapestry.form.Form}. Most of the testing is, still alas, done with
* mock objects.
*
* @author Howard Lewis Ship
* @since 4.0
*/
public class TestForm extends BaseComponentTestCase
{
private IActionListener newListener()
{
return (IActionListener) newMock(IActionListener.class);
}
public void testFindCancelListener()
{
IActionListener cancel = newListener();
IActionListener listener = newListener();
replayControls();
Form form = (Form) newInstance(Form.class, new Object[]
{ "listener", listener, "cancel", cancel });
assertSame(cancel, form.findListener(FormConstants.SUBMIT_CANCEL));
verifyControls();
}
public void testFindCancelDefaultListener()
{
IActionListener listener = newListener();
replayControls();
Form form = (Form) newInstance(Form.class, "listener", listener);
assertSame(listener, form.findListener(FormConstants.SUBMIT_CANCEL));
verifyControls();
}
public void testFindRefreshListener()
{
IActionListener refresh = newListener();
IActionListener listener = newListener();
replayControls();
Form form = (Form) newInstance(Form.class, new Object[]
{ "listener", listener, "refresh", refresh });
assertSame(refresh, form.findListener(FormConstants.SUBMIT_REFRESH));
verifyControls();
}
public void testFindRefreshListenerDefault()
{
IActionListener listener = newListener();
replayControls();
Form form = (Form) newInstance(Form.class, new Object[]
{ "listener", listener });
assertSame(listener, form.findListener(FormConstants.SUBMIT_REFRESH));
verifyControls();
}
public void testFindListenerNormal()
{
IActionListener cancel = newListener();
IActionListener refresh = newListener();
IActionListener listener = newListener();
replayControls();
Form form = (Form) newInstance(Form.class, new Object[]
{ "listener", listener, "cancel", cancel, "refresh", refresh });
assertSame(listener, form.findListener(FormConstants.SUBMIT_NORMAL));
verifyControls();
}
}
1.13 +16 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/wml/Go.jwc
Index: Go.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/wml/Go.jwc,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Go.jwc 15 May 2005 22:56:37 -0000 1.12
+++ Go.jwc 17 Jun 2005 16:52:19 -0000 1.13
@@ -39,6 +39,22 @@
to the submission.
</description>
</parameter>
+
+ <parameter name="cancel" default-binding="listener">
+ <description>
+ Object invoked when the form is cancelled (a special type of form submission).
+ The oncancel listener (if any) overrides the standard listener. Other properties
+ will not be affected by the rewind.
+ </description>
+ </parameter>
+
+ <parameter name="refresh" default-binding="listener">
+ <description>
+ Object invoked when the form is refreshed (a special type of form submission).
+ The onrefresh listener (if any) overrides the standard listener.
+ Other properties managed by enclosed components will be updated.
+ </description>
+ </parameter>
<parameter name="stateful" default-value="true">
<description>
1.6 +1 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/wml/Go.java
Index: Go.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/wml/Go.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Go.java 3 May 2005 17:41:26 -0000 1.5
+++ Go.java 17 Jun 2005 16:52:19 -0000 1.6
@@ -14,10 +14,10 @@
package org.apache.tapestry.wml;
-import org.apache.tapestry.FormSupport;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.form.Form;
+import org.apache.tapestry.form.FormSupport;
/**
* The go element declares a go task, indicating navigation to a URI. If the URI names a WML card or
1.11 +83 -10 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.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- index.xml 16 Jun 2005 22:01:07 -0000 1.10
+++ index.xml 17 Jun 2005 16:52:19 -0000 1.11
@@ -75,29 +75,102 @@
</p>
<p>
-Tapestry is distributed under the terms of the Apache Software License.
+Tapestry is distributed under the terms of the Apache Software License. It can be freely used, shared and modified with minimal
+constraints.
</p>
<section>
- <title>Status</title>
+ <title>Tapestry 4.0</title>
<p>
-Work has begun on Tapestry 4.0, which is currently in a late alpha stage. Documentation is being converted
-from the old DocBook format, to the new Forrest format, leaving many temporary gaps. Only the framework and the contrib
-library is being built, most example code is not.
+Tapestry 4.0 is just overflowing with new features aimed at further enhancing
+your productivity. Here's a few of our favorites:
+</p>
+
+<ul>
+ <li>
+ The new 4.0 specification DTDs have been simplified.
+ </li>
+ <li>
+ The syntax used for binding parameters inside an HTML template and inside
+ an XML specification is now consistent. Both make use of the binding prefixes.
+ </li>
+ <li>
+ "Friendly" URLs (that is, URLs that pack more information into the path and less into query
+ parameters) are built in. This makes it easy to divide your application across many folders (reducing
+ clutter),
+ and leverage J2EE declarative security along the way.
+ </li>
+ <li>
+ Component parameters now <em>just work</em>, without having to worry about
+ "direction".
+ </li>
+ <li>
+ Applications can now have a global message catalog, in addition to per-page and per-component
+ message catalogs. Messages not found in the component message catalog are searched for in the
+ application catalog.
+ </li>
+ <li>
+ Full, native support for <link href="tapestry-portlet/index.html">developing JSR-168 Portlets</link> has been added.
+ </li>
+ <li>
+ Tapestry 4.0 makes much less use of reflection and &OGNL; than Tapestry 3.0; partly
+ because there are many new <link href="UsersGuide/bindings.html">binding prefixes</link>.
+ </li>
+ <li>
+ HiveMind services and &Spring; beans to be directly injected
+ into page and component classes.
+ </li>
+ <li>
+ Tapestry 4.0 includes optional <link href="tapestry-annotations/index.html">JDK 1.5 annotation support</link>
+ (but Tapestry still works with <link href="dependencies.html">JDK 1.3</link>).
+ </li>
+ <li>
+ Tapestry 4.0 debuts a new and much more sophisticated user input validation subsystem. Thanks Paul!
+ </li>
+ <li>
+ Line precise error reporting can now display the contents of files containing errors.
+ </li>
+ <li>
+ Forms can now be canceled, bypassing client-side validation logic, and invoking an alternate
+ listener on the server-side.
+ </li>
+ <li>
+ You are no longer limited to just Global and Visit; you can have
+ <link href="UsersGuide/state.html#state.aso">application state objects</link> as you like.
+ </li>
+ <li>
+ The use of &HiveMind; under the covers means that Tapestry can be easily customized to fit your needs.
+ </li>
+ <li>
+ Page properties can now be persisted on the client, as well as in the session.
+ </li>
+</ul>
+
+<p>
+The complete list of changes is almost too numerous to list. Suffice to say, everything is about
+getting more bang for less work, and reducing the amount of Java code, reducing the complexity
+of templates, and simplifying (or eliminating) XML files.
</p>
+</section>
+
+<section>
+ <title>Status</title>
+
<p>
-If you are using Tapestry in a production environment, it is recommended that you stick with Tapestry <strong>3.0.3</strong>,
-the latest stable release.
+Work on Tapestry 4.0 is in full swing. Documentation is being converted
+from the old DocBook format, to the new Forrest format, leaving many temporary gaps. Only the
+main code base and the Workbench example is being built, all other example code is not (this unfortunately
+includes the Virtual Library).
</p>
<p>
-Tapestry 4.0 now supports <link href="tapestry-annotations/index.html">JDK 1.5 annotations</link>, which can be used
-as an alternative to the XML page and component specifcations (in some cases).
+Tapestry 4.0 should be production-ready soon. It needs more exposure and more documentation. For the
+momement, it is still recommended that you stick with Tapestry <strong>3.0.3</strong>,
+the latest stable release.
</p>
-
</section>
<section>
1.4 +1 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/FormBehavior.java
Index: FormBehavior.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/FormBehavior.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- FormBehavior.java 16 Jun 2005 18:27:11 -0000 1.3
+++ FormBehavior.java 17 Jun 2005 16:52:19 -0000 1.4
@@ -21,7 +21,7 @@
/**
* Common interface extended by {@link org.apache.tapestry.IForm} and
- * {@link org.apache.tapestry.FormSupport}.
+ * {@link org.apache.tapestry.form.FormSupport}.
*
* @author Howard M. Lewis Ship
* @since 4.0
1.8 +1 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/IValidationDelegate.java
Index: IValidationDelegate.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/IValidationDelegate.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- IValidationDelegate.java 21 May 2005 15:36:22 -0000 1.7
+++ IValidationDelegate.java 17 Jun 2005 16:52:19 -0000 1.8
@@ -54,7 +54,7 @@
* {@link org.apache.tapestry.form.ListEdit} inside your form? Some of your components will
* render multiple times. In this case you will have multiple <em>fields</em>. Each field will
* have a unique field name (the
- * {@link org.apache.tapestry.FormSupport#getElementId(IFormComponent) element id}, which you can
+ * {@link org.apache.tapestry.form.FormSupport#getElementId(IFormComponent) element id}, which you can
* see this in the generated HTML). It is this field name that the delegate keys off of, which means
* that some fields generated by a component may have errors and some may not, it all works fine
* (with one exception).
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org