stephan 2004/06/23 03:53:41
Modified: src/blocks/javaflow/java/org/apache/cocoon/forms/flow/java
FormInstance.java
src/blocks/javaflow/samples/forms form1.xml
Log:
Fixing CForms sample because of recent changes of CForms.
Revision Changes Path
1.11 +286 -261
cocoon-2.1/src/blocks/javaflow/java/org/apache/cocoon/forms/flow/java/FormInstance.java
Index: FormInstance.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/javaflow/java/org/apache/cocoon/forms/flow/java/FormInstance.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- FormInstance.java 7 May 2004 17:47:55 -0000 1.10
+++ FormInstance.java 23 Jun 2004 10:53:41 -0000 1.11
@@ -16,12 +16,22 @@
package org.apache.cocoon.forms.flow.java;
+import java.io.OutputStream;
import java.util.Locale;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.flow.FlowHelper;
import org.apache.cocoon.components.flow.java.AbstractContinuable;
import org.apache.cocoon.components.flow.java.VarMap;
+import org.apache.cocoon.components.source.SourceUtil;
import org.apache.cocoon.forms.FormContext;
import org.apache.cocoon.forms.FormManager;
import org.apache.cocoon.forms.binding.Binding;
@@ -29,275 +39,290 @@
import org.apache.cocoon.forms.formmodel.Form;
import org.apache.cocoon.forms.formmodel.Widget;
import org.apache.cocoon.forms.transformation.FormsPipelineConfig;
+import org.apache.cocoon.forms.util.XMLAdapter;
+import org.apache.excalibur.source.ModifiableSource;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.w3c.dom.Element;
/**
* Implementation of the Cocoon Forms/Java Flow integration.
- *
- * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
- * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
+ *
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez </a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels </a>
* @version CVS $Id$
*/
public class FormInstance extends AbstractContinuable {
- private Form form;
- private Binding binding;
- private Locale locale;
- private boolean isValid;
- private Object validator; // Used?
-
- /**
- * Create a form, given the URI of its definition file
- */
- public FormInstance(String uri) {
- FormManager formMgr = null;
- SourceResolver resolver = null;
- Source src = null;
- try {
- formMgr = (FormManager)getComponent(FormManager.ROLE);
- resolver = (SourceResolver)getComponent(SourceResolver.ROLE);
- src = resolver.resolveURI(uri);
- this.form = formMgr.createForm(src);
- this.binding = null;
- // this.validator = null;
- // TODO : do we keep this ?
- // this.formWidget = new Widget(this.form); could not create
instance
- } catch (Exception e) {
- throw new CascadingRuntimeException("Could not create form
instance", e);
- } finally {
- releaseComponent(formMgr);
- if (src != null) resolver.release(src);
- releaseComponent(resolver);
- }
- }
-
- /**
- * Create a form, given the URI of its definition file, the
- * binding file.
- */
- public FormInstance(String definitionFile, String bindingFile) {
- this(definitionFile);
- createBinding(bindingFile);
- }
-
- /**
- * Create a form of an fd:form element in the form of a
org.w3c.dom.Element
- */
- public FormInstance(Element formDefinition) {
- FormManager formMgr = null;
- SourceResolver resolver = null;
- Source src = null;
- try {
- formMgr = (FormManager)getComponent(FormManager.ROLE);
- resolver = (SourceResolver)getComponent(SourceResolver.ROLE);
- this.form = formMgr.createForm(formDefinition);
- this.binding = null;
- } catch (Exception e) {
- throw new CascadingRuntimeException("Could not create form
instance", e);
- } finally {
- releaseComponent(formMgr);
- if (src != null) resolver.release(src);
- releaseComponent(resolver);
- }
- }
-
- public Widget getModel() {
- return this.form;
- }
-
- /**
- * Get a Widget (the java object) from the form.
- * If <code>name</code> is undefined, the form widget itself is returned.
- * Otherwise, the form's child widget of name <code>name</code> is
returned.
- */
- public Widget getChild(String name) {
- if (name == null) {
- return this.form;
- } else {
- return this.form.getChild(name);
- }
- }
-
- public String getSubmitId() {
-
- Widget widget = this.form.getSubmitWidget();
- // Can be null on "normal" submit
- return widget == null ? null : widget.getId();
+ private Form form;
+ private Binding binding;
+ private Locale locale;
+ private boolean isValid;
+ private XMLAdapter xmlAdapter;
+
+ /**
+ * Create a form, given the URI of its definition file
+ */
+ public FormInstance(String uri) {
+ FormManager formMgr = null;
+ SourceResolver resolver = null;
+ Source src = null;
+ try {
+ formMgr = (FormManager) getComponent(FormManager.ROLE);
+ resolver = (SourceResolver)
getComponent(SourceResolver.ROLE);
+ src = resolver.resolveURI(uri);
+ this.form = formMgr.createForm(src);
+ this.binding = null;
+ } catch (Exception e) {
+ throw new CascadingRuntimeException(
+ "Could not create form instance", e);
+ } finally {
+ releaseComponent(formMgr);
+ if (src != null)
+ resolver.release(src);
+ releaseComponent(resolver);
+ }
+ }
+
+ /**
+ * Create a form, given the URI of its definition file, the binding
file.
+ */
+ public FormInstance(String definitionFile, String bindingFile) {
+ this(definitionFile);
+ createBinding(bindingFile);
+ }
+
+ /**
+ * Create a form of an fd:form element in the form of a
org.w3c.dom.Element
+ */
+ public FormInstance(Element formDefinition) {
+ FormManager formMgr = null;
+ SourceResolver resolver = null;
+ Source src = null;
+ try {
+ formMgr = (FormManager) getComponent(FormManager.ROLE);
+ resolver = (SourceResolver)
getComponent(SourceResolver.ROLE);
+ this.form = formMgr.createForm(formDefinition);
+ this.binding = null;
+ } catch (Exception e) {
+ throw new CascadingRuntimeException(
+ "Could not create form instance", e);
+ } finally {
+ releaseComponent(formMgr);
+ if (src != null)
+ resolver.release(src);
+ releaseComponent(resolver);
+ }
+ }
+
+ public Widget getModel() {
+ return this.form;
+ }
+
+ /**
+ * Get a Widget (the java object) from the form. If <code>name</code> is
+ * undefined, the form widget itself is returned. Otherwise, the form's
+ * child widget of name <code>name</code> is returned.
+ */
+ public Widget getChild(String name) {
+ if (name == null) {
+ return this.form;
+ } else {
+ return this.form.getChild(name);
+ }
+ }
+
+ /**
+ * Get a Widget (the java object) from the form via its
<code>path</code>.
+ */
+ public Widget lookupWidget(String path) {
+ return this.form.lookupWidget(path);
+ }
+
+ public void show(String uri) {
+ show(uri, new VarMap());
+ }
+
+ /**
+ * Manages the display of a form and its validation.
+ *
+ * This uses some additionnal propertied on the form object :
+ * - "locale" : the form locale (default locale is used if not set)
+ *
+ * On return, the calling code can check some properties to know the
form result :
+ * - "isValid" : true if the form was sucessfully validated
+ * - "submitId" : the id of the widget that triggered the form submit
(can be null)
+ *
+ * @parameter uri the page uri (like in cocoon.sendPageAndWait())
+ * @parameter bizdata some business data for the view (like in
cocoon.sendPageAndWait()).
+ * The "{FormsPipelineConfig.CFORMSKEY}" and "locale"
properties are added to this object.
+ */
+ public String show(String uri, Object bizData) {
+
+ if (bizData == null)
+ bizData = new VarMap();
+ ((VarMap) bizData).add(FormsPipelineConfig.CFORMSKEY,
this.form);
+
+ if (this.locale == null)
+ this.locale = java.util.Locale.getDefault();
+ ((VarMap) bizData).add("locale", this.locale);
+
+ // Keep the first continuation that will be created as the
result of
+ // this function
+ //var result = null;
+
+ boolean finished = false;
+ this.isValid = false;
+
+ do {
+ sendPageAndWait(uri, bizData);
+
+ FormContext formContext = new FormContext(getRequest(),
locale);
+
+ // Prematurely add the bizData as a request attribute
so that event
+ // listeners can use it
+ // (the same is done by cocoon.sendPage())
+ FlowHelper.setContextObject(this.getObjectModel(),
bizData);
+
+ finished = this.form.process(formContext);
+
+ // Additional flow-level validation
+ if (finished) {
+ this.isValid = this.form.isValid();
+ }
+
+ // FIXME: Theoretically, we should clone the form
widget (this.form)
+ // to ensure it keeps its
+ // value with the continuation. We don't do it since
there should me
+ // not much pratical consequences
+ // except a sudden change of repeaters whose size
changed from a
+ // continuation to another.
+
+ } while (!finished);
+
+ Widget widget = this.form.getSubmitWidget();
+ // Can be null on "normal" submit
+ return widget == null ? null : widget.getId();
+ }
+
+ public void createBinding(String bindingURI) {
+ BindingManager bindingManager = null;
+ Source source = null;
+ SourceResolver resolver = null;
+ try {
+ bindingManager = (BindingManager)
getComponent(BindingManager.ROLE);
+ resolver = (SourceResolver)
getComponent(SourceResolver.ROLE);
+ source = resolver.resolveURI(bindingURI);
+ this.binding = bindingManager.createBinding(source);
+ } catch (Exception e) {
+ throw new CascadingRuntimeException("Could not create
bindinh", e);
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ releaseComponent(bindingManager);
+ releaseComponent(resolver);
}
+ }
- /**
- * Sets the point in your script that will be returned to when the form
is
- * redisplayed. If setBookmark() is not called, this is implicitly set to
- * the beginning of showForm().
- */
-/* public WebContinuation setBookmark() {
- return (this.local_.webContinuation =
cocoon.createWebContinuation());
- }*/
-
- /**
- * Returns the bookmark continuation associated with this form, or
undefined
- * if setBookmark() has not been called.
- *
- */
-/* public WebContinuation getBookmark() {
- return this.local_.webContinuation;
- } */
-
- public void show(String uri) {
- show(uri, new VarMap());
- }
-
- /**
- * Manages the display of a form and its validation.
- *
- * This uses some additionnal propertied on the form object :
- * - "locale" : the form locale (default locale is used if not set)
- * - "validator" : additional validation function. This function receives
- * the form object as parameter and should return a boolean indicating
- * if the form handling is finished (true) or if the form should be
- * redisplayed again (false)
- *
- * On return, the calling code can check some properties to know the
form result :
- * - "isValid" : true if the form was sucessfully validated
- * - "submitId" : the id of the widget that triggered the form submit
(can be null)
- *
- * @param uri the page uri (like in cocoon.sendPageAndWait())
- * @param bizData some business data for the view (like in
cocoon.sendPageAndWait()).
- * The "{FormsPipelineConfig.CFORMSKEY}" and "locale"
properties are added to this object.
- */
- public void show(String uri, Object bizData) {
-
- if (bizData==null) bizData = new VarMap();
- ((VarMap)bizData).add(FormsPipelineConfig.CFORMSKEY, this.form);
-
- if (this.locale == null)
- this.locale = java.util.Locale.getDefault();
- ((VarMap)bizData).add("locale", this.locale);
-
- // Keep the first continuation that will be created as the result of
this function
- //var result = null;
-
- boolean finished = false;
- this.isValid = false;
-
- do {
- sendPageAndWait(uri, bizData);
-
- FormContext formContext = new FormContext(getRequest(), locale);
-
- // Prematurely add the bizData as a request attribute so that
event listeners can use it
- // (the same is done by cocoon.sendPage())
- FlowHelper.setContextObject(this.getObjectModel(), bizData);
-
- finished = this.form.process(formContext);
-
- // Additional flow-level validation
- if (finished) {
- if (this.validator == null) {
- this.isValid = this.form.isValid();
- } else {
- this.isValid = this.form.isValid() /*&
this.validator(this.form, bizData)*/;
- }
- finished = this.isValid;
- }
-
- // FIXME: Theoretically, we should clone the form widget
(this.form) to ensure it keeps its
- // value with the continuation. We don't do it since there
should me not much pratical consequences
- // except a sudden change of repeaters whose size changed from a
continuation to another.
-
- } while(!finished);
- }
- /*
- /**
- * Manages the display of a form and its validation.
- * @param uri the page uri (like in cocoon.sendPageAndWait())
- * @param fun optional function which will be executed after pipeline
- * processing. Useful for releasing resources needed during pipeline
- * processing but which should not become part of the continuation
- * @param ttl Time to live (in milliseconds) for the continuation
- * created
- * @return The web continuation associated with submitting this form
- *
- public showForm(String uri, Object fun, ttl) {
- if (!this.getBookmark()) {
- this.setBookmark();
- }
- FormContext formContext = FormsFlowHelper.getFormContext(cocoon,
this.locale);
- // this is needed by the FormTemplateTransformer:
- //var javaWidget = this.formWidget_.unwrap();;
- //this.formWidget_["CocoonFormsInstance"] = javaWidget;
-
getRequest().setAttribute(Packages.org.apache.cocoon.forms.transformation.CFORMSKEY,
this.formWidget);
- WebContinuation wk = sendPageAndWait(uri, this.formWidget, fun, ttl);
- var formContext = new FormContext(cocoon.request,
javaWidget.getLocale());
- var userErrors = 0;
- this.formWidget_.validationErrorListener = function(widget, error) {
- if (error != null) {
- userErrors++;
- }
- }
- var finished = javaWidget.process(formContext);
- if (this.onValidate) {
- this.onValidate(this);
- }
- if (!finished || userErrors > 0) {
- cocoon.continuation = this.local_.webContinuation;
-
this.local_.webContinuation.continuation(this.local_.webContinuation);
- }
- return wk;
- }*/
-
- public void createBinding(String bindingURI) {
- BindingManager bindingManager = null;
- Source source = null;
- SourceResolver resolver = null;
- try {
- bindingManager =
(BindingManager)getComponent(BindingManager.ROLE);
- resolver = (SourceResolver)getComponent(SourceResolver.ROLE);
- source = resolver.resolveURI(bindingURI);
- this.binding = bindingManager.createBinding(source);
- } catch (Exception e) {
- throw new CascadingRuntimeException("Could not create bindinh",
e);
- } finally {
- if (source != null)
- resolver.release(source);
- releaseComponent(bindingManager);
- releaseComponent(resolver);
- }
- }
-
- public void load(Object object) {
- if (this.binding == null)
- throw new Error("Binding not configured for this form.");
-
- try {
- this.binding.loadFormFromModel(this.form, object);
- } catch (Exception e) {
- throw new CascadingRuntimeException("Could not load form from
model", e);
- }
- }
-
- public void save(Object object) {
- if (this.binding == null)
- throw new Error("Binding not configured for this form.");
-
- try {
- this.binding.saveFormToModel(this.form, object);
- } catch (Exception e) {
- throw new CascadingRuntimeException("Could not save form into
model", e);
- }
- }
-
- public void setAttribute(String name, Object value) {
- this.form.setAttribute(name, value);
- }
-
- public Object getAttribute(String name) {
- return this.form.getAttribute(name);
- }
-
- public void removeAttribute(String name) {
- this.form.removeAttribute(name);
- }
-}
+ public void load(Object object) {
+ if (this.binding == null)
+ throw new Error("Binding not configured for this
form.");
+
+ try {
+ this.binding.loadFormFromModel(this.form, object);
+ } catch (Exception e) {
+ throw new CascadingRuntimeException(
+ "Could not load form from model", e);
+ }
+ }
+
+ public void save(Object object) {
+ if (this.binding == null)
+ throw new Error("Binding not configured for this
form.");
+
+ try {
+ this.binding.saveFormToModel(this.form, object);
+ } catch (Exception e) {
+ throw new CascadingRuntimeException(
+ "Could not save form into model", e);
+ }
+ }
+
+ public void setAttribute(String name, Object value) {
+ this.form.setAttribute(name, value);
+ }
+
+ public Object getAttribute(String name) {
+ return this.form.getAttribute(name);
+ }
+
+ public void removeAttribute(String name) {
+ this.form.removeAttribute(name);
+ }
+
+ public XMLAdapter getXML() {
+ if (this.xmlAdapter == null)
+ this.xmlAdapter = new XMLAdapter(this.form);
+ return this.xmlAdapter;
+ }
+
+ public void loadXML(String uri) {
+ Source source = null;
+ SourceResolver resolver = null;
+ try {
+ resolver = (SourceResolver)
getComponent(SourceResolver.ROLE);
+ source = resolver.resolveURI(uri);
+ SourceUtil.toSAX(source, this.getXML());
+ } catch (Exception e) {
+ throw new CascadingRuntimeException("Could not load
XML", e);
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ releaseComponent(resolver);
+ }
+ }
+
+ public void saveXML(String uri) {
+ Source source = null;
+ SourceResolver resolver = null;
+ OutputStream outputStream = null;
+ try {
+ resolver = (SourceResolver)
getComponent(SourceResolver.ROLE);
+ source = resolver.resolveURI(uri);
+
+ TransformerFactory tf =
TransformerFactory.newInstance();
+
+ if (source instanceof ModifiableSource
+ &&
tf.getFeature(SAXTransformerFactory.FEATURE)) {
+
+ ModifiableSource msource = (ModifiableSource)
source;
+
+ outputStream = msource.getOutputStream();
+ TransformerHandler transformerHandler =
(TransformerHandler) tf
+ .newTransformer();
+ Transformer transformer =
transformerHandler.getTransformer();
+
transformer.setOutputProperty(OutputKeys.INDENT, "true");
+
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ transformerHandler.setResult(new
StreamResult(outputStream));
+ this.getXML().toSAX(transformerHandler);
+ } else {
+ throw new ProcessingException("Cannot write to
source " + uri);
+ }
+ } catch (Exception e) {
+ throw new CascadingRuntimeException("Could not save
XML", e);
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ releaseComponent(resolver);
+ if (outputStream != null) {
+ try {
+ outputStream.flush();
+ outputStream.close();
+ } catch (Exception e) {
+ throw new CascadingRuntimeException(
+ "Could not flush/close
outputstream", e);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
1.4 +57 -32 cocoon-2.1/src/blocks/javaflow/samples/forms/form1.xml
Index: form1.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/javaflow/samples/forms/form1.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- form1.xml 7 May 2004 21:32:32 -0000 1.3
+++ form1.xml 23 Jun 2004 10:53:41 -0000 1.4
@@ -21,7 +21,22 @@
<fd:form xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"
xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
-
+
+ <fd:validation>
+ <!-- This demonstrates form level validation -->
+ <fd:javascript>
+ var success = true;
+ var price = widget.lookupWidget("dieselprice");
+ if (price.value < 1) {
+ price.setValidationError(new
Packages.org.apache.cocoon.forms.validation.ValidationError("It can not be that
low!", false));
+ success = false;
+ }
+
+ // Must return true/false
+ return success;
+ </fd:javascript>
+ </fd:validation>
+
<fd:widgets>
<fd:field id="tab-state">
<fd:datatype base="string"/>
@@ -30,9 +45,9 @@
<fd:field id="email" required="true">
<fd:datatype base="string"/>
<!-- new-style validation, outside of the datatype -->
- <fd:validation>
- <fd:email/>
- </fd:validation>
+ <fd:validation>
+ <fd:email/>
+ </fd:validation>
<fd:label>Enter an <b>email</b> address:</fd:label>
<fd:help>
An email address must be in <i>[EMAIL PROTECTED]</i> format.
@@ -100,7 +115,7 @@
java.lang.System.err.println("Was here!");
var newValue = event.source.value;
if (newValue != null) {
- var number2 = event.source.lookupWidget("../number2");
+ var number2 = event.source.parent.lookupWidget("number2");
if (number2.value == null) {
number2.setValue(new java.lang.Long(newValue.intValue() + 1));
}
@@ -112,11 +127,11 @@
<fd:field id="number2" required="true">
<fd:label>Enter another number, larger than the other
number:</fd:label>
<fd:datatype base="long"/>
- <fd:validation>
- <fd:range min="number1 + 1">
- <fd:failmessage>This number should be larger than the first
number.</fd:failmessage>
- </fd:range>
- </fd:validation>
+ <fd:validation>
+ <fd:range min="number1 + 1">
+ <fd:failmessage>This number should be larger than the first
number.</fd:failmessage>
+ </fd:range>
+ </fd:validation>
</fd:field>
<fd:multivaluefield id="drinks">
@@ -235,31 +250,31 @@
<fd:repeater id="contacts">
<fd:validation>
- <!-- This demonstrates validating a repeater: we check here if
all contacts are distinct.
- A validator cannot itself display a validation error,
and therefore sets a validation
- error on a field in the offenting row. -->
+ <!-- This demonstrates validating a repeater: we check here if all
contacts are distinct.
+ A repeater cannot itself display a validation error, and
therefore sets a validation
+ error on a field in the offenting row. -->
<fd:javascript>
var list = new java.util.ArrayList();
var success = true;
// Iterate on all rows
- for (var i = 0; i < widget.size; i++) {
- // Get the row
- var row = widget.getRow(i);
- // Compute a key combining the first and last name
- var key = row.lookupWidget("firstname").value + "/" +
row.getWidget("lastname").value;
- if (list.contains(key)) {
- // already in the list
- row.lookupWidget("firstname").setValidationError(new
Packages.org.apache.cocoon.forms.validation.ValidationError("Duplicate contact
name", false));
- success = false;
- break; // no need to continue
- }
- // Add the current row's key to the list
- list.add(key);
- }
-
- // Must return true/false
- return success;
-
+ for (var i = 0; i < widget.size; i++) {
+ // Get the row
+ var row = widget.getRow(i);
+ // Compute a key combining the first and last name
+ var key = row.lookupWidget("firstname").value + "/" +
row.lookupWidget("lastname").value;
+ if (list.contains(key)) {
+ // already in the list
+ row.lookupWidget("firstname").setValidationError(new
Packages.org.apache.cocoon.forms.validation.ValidationError("Duplicate contact
name", false));
+ success = false;
+ break; // no need to continue
+ }
+ // Add the current row's key to the list
+ list.add(key);
+ }
+
+ // Must return true/false
+ return success;
+
</fd:javascript>
</fd:validation>
<fd:widgets>
@@ -281,6 +296,16 @@
<fd:validation>
<fd:email/>
</fd:validation>
+ </fd:field>
+ <fd:field id="birthdate">
+ <fd:label>Birthdate (dd/MM/yyyy):</fd:label>
+ <fd:datatype base="date">
+ <fd:convertor>
+ <fd:patterns>
+ <fd:pattern>dd/MM/yyyy</fd:pattern>
+ </fd:patterns>
+ </fd:convertor>
+ </fd:datatype>
</fd:field>
<fd:booleanfield id="select">
<fd:label>Select</fd:label>