You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2005/10/21 17:31:00 UTC
svn commit: r327208 - in /cocoon/blocks/forms/trunk:
java/org/apache/cocoon/forms/formmodel/ samples/forms/
Author: sylvain
Date: Fri Oct 21 08:30:51 2005
New Revision: 327208
URL: http://svn.apache.org/viewcvs?rev=327208&view=rev
Log:
Add value-changed-listeners on uploads and outputs
Modified:
cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Output.java
cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java
cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java
cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java
cocoon/blocks/forms/trunk/samples/forms/carselector_form.xml
cocoon/blocks/forms/trunk/samples/forms/upload_model.xml
cocoon/blocks/forms/trunk/samples/forms/upload_template.xml
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Output.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Output.java?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Output.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Output.java Fri Oct 21 08:30:51 2005
@@ -20,7 +20,13 @@
import org.apache.cocoon.forms.FormsConstants;
import org.apache.cocoon.forms.FormContext;
import org.apache.cocoon.forms.datatype.Datatype;
+import org.apache.cocoon.forms.event.ValueChangedEvent;
+import org.apache.cocoon.forms.event.ValueChangedListener;
+import org.apache.cocoon.forms.event.ValueChangedListenerEnabled;
+import org.apache.cocoon.forms.event.WidgetEvent;
+import org.apache.cocoon.forms.event.WidgetEventMulticaster;
import org.apache.cocoon.xml.XMLUtils;
+import org.apache.commons.lang.ObjectUtils;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@@ -33,10 +39,11 @@
*
* @version $Id$
*/
-public class Output extends AbstractWidget implements DataWidget {
+public class Output extends AbstractWidget implements DataWidget, ValueChangedListenerEnabled {
private final OutputDefinition definition;
private Object value;
+ private ValueChangedListener listener;
public OutputDefinition getOutputDefinition() {
return definition;
@@ -49,6 +56,7 @@
protected Output(OutputDefinition definition) {
super(definition);
this.definition = definition;
+ this.listener = definition.getValueChangedListener();
}
public WidgetDefinition getDefinition() {
@@ -107,7 +115,36 @@
+ "expected " + definition.getDatatype().getTypeClass()
+ ", received " + object.getClass() + ".");
}
- value = object;
- getForm().addWidgetUpdate(this);
+ if (!ObjectUtils.equals(value, object)) {
+ Object oldValue = value;
+ value = object;
+ if (this.hasValueChangedListeners()) {
+ getForm().addWidgetEvent(new ValueChangedEvent(this, oldValue, value));
+ }
+ getForm().addWidgetUpdate(this);
+ }
+ }
+
+ public void addValueChangedListener(ValueChangedListener listener) {
+ this.listener = WidgetEventMulticaster.add(this.listener, listener);
+ }
+
+ public void removeValueChangedListener(ValueChangedListener listener) {
+ this.listener = WidgetEventMulticaster.remove(this.listener, listener);
+ }
+
+ public boolean hasValueChangedListeners() {
+ return this.listener != null || this.getForm().hasFormHandler();
+ }
+
+ public void broadcastEvent(WidgetEvent event) {
+ if (event instanceof ValueChangedEvent) {
+ if (this.listener != null) {
+ this.listener.valueChanged((ValueChangedEvent)event);
+ }
+ } else {
+ // Other kinds of events
+ super.broadcastEvent(event);
+ }
}
}
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java Fri Oct 21 08:30:51 2005
@@ -20,6 +20,11 @@
import org.apache.cocoon.forms.FormsConstants;
import org.apache.cocoon.forms.FormContext;
+import org.apache.cocoon.forms.event.ValueChangedEvent;
+import org.apache.cocoon.forms.event.ValueChangedListener;
+import org.apache.cocoon.forms.event.ValueChangedListenerEnabled;
+import org.apache.cocoon.forms.event.WidgetEvent;
+import org.apache.cocoon.forms.event.WidgetEventMulticaster;
import org.apache.cocoon.forms.util.I18nMessage;
import org.apache.cocoon.forms.validation.ValidationError;
import org.apache.cocoon.forms.validation.ValidationErrorAware;
@@ -38,13 +43,17 @@
/**
* A file-uploading Widget. This widget gives access via Cocoon Forms, to Cocoon's
* file upload functionality.
+ * <p>
+ * This widget accepts value-changed listeners, but the event raised does not hold
+ * the previous value, as uploads are heavyweight resources that must be released
+ * as soon as possible.
*
* @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
* @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
* @version $Id$
*/
public class Upload extends AbstractWidget
- implements ValidationErrorAware {
+ implements ValidationErrorAware, ValueChangedListenerEnabled {
private static final String UPLOAD_EL = "upload";
private static final String VALUE_EL = "value";
@@ -53,10 +62,12 @@
private final UploadDefinition uploadDefinition;
private Part part;
private ValidationError validationError;
+ private ValueChangedListener listener;
public Upload(UploadDefinition uploadDefinition) {
super(uploadDefinition);
this.uploadDefinition = uploadDefinition;
+ this.listener = uploadDefinition.getValueChangedListener();
}
public UploadDefinition getUploadDefinition() {
@@ -72,12 +83,16 @@
}
public void setValue(Object object) {
+ if (object == this.part) {
+ return;
+ }
+
if ((object == null) || (object instanceof Part)) {
this.part = (Part)object;
} else {
throw new RuntimeException("The value of an upload widget must be of type " + Part.class + ".");
}
- getForm().addWidgetUpdate(this);
+ changed();
}
public void readFromRequest(FormContext formContext) {
@@ -98,11 +113,11 @@
// Keep the request part
requestPart.setDisposeWithRequest(false);
this.part = requestPart;
- getForm().addWidgetUpdate(this);
if (validateOversize()) {
// Clear any validation error
setValidationError(null);
}
+ changed();
// If it's not a part and not null, clear any existing value
// We also check if we're the submit widget, as a result of clicking the "..." button
@@ -114,11 +129,18 @@
}
setValidationError(null);
// Ensure we redisplay it
- getForm().addWidgetUpdate(this);
+ changed();
}
// And keep the current state if the parameter doesn't exist or is null
}
+
+ private void changed() {
+ if (this.hasValueChangedListeners()) {
+ this.getForm().addWidgetEvent(new ValueChangedEvent(this, null, this.part));
+ }
+ getForm().addWidgetUpdate(this);
+ }
private boolean validateMimeType() {
String mimeTypes = this.uploadDefinition.getMimeTypes();
@@ -196,6 +218,34 @@
if(!ObjectUtils.equals(this.validationError, error)) {
this.validationError = error;
getForm().addWidgetUpdate(this);
+ }
+ }
+
+ /**
+ * Adds a ValueChangedListener to this widget instance. Listeners defined
+ * on the widget instance will be executed in addtion to any listeners
+ * that might have been defined in the widget definition.
+ */
+ public void addValueChangedListener(ValueChangedListener listener) {
+ this.listener = WidgetEventMulticaster.add(this.listener, listener);
+ }
+
+ public void removeValueChangedListener(ValueChangedListener listener) {
+ this.listener = WidgetEventMulticaster.remove(this.listener, listener);
+ }
+
+ public boolean hasValueChangedListeners() {
+ return this.listener != null || this.getForm().hasFormHandler();
+ }
+
+ public void broadcastEvent(WidgetEvent event) {
+ if (event instanceof ValueChangedEvent) {
+ if (this.listener != null) {
+ this.listener.valueChanged((ValueChangedEvent)event);
+ }
+ } else {
+ // Other kinds of events
+ super.broadcastEvent(event);
}
}
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java Fri Oct 21 08:30:51 2005
@@ -15,6 +15,9 @@
*/
package org.apache.cocoon.forms.formmodel;
+import org.apache.cocoon.forms.event.ValueChangedListener;
+import org.apache.cocoon.forms.event.WidgetEventMulticaster;
+
/**
* The definition of an upload widget.
*
@@ -23,6 +26,7 @@
* @version $Id$
*/
public class UploadDefinition extends AbstractWidgetDefinition {
+ private ValueChangedListener listener;
private boolean required;
private String mimeTypes;
@@ -40,33 +44,35 @@
* initialize this definition with the other, sort of like a copy constructor
*/
public void initializeFrom(WidgetDefinition definition) throws Exception {
- super.initializeFrom(definition);
-
- if(definition instanceof UploadDefinition) {
- UploadDefinition other = (UploadDefinition)definition;
-
- this.required = other.required;
- this.mimeTypes = other.mimeTypes.substring(0); // deep copy
-
- } else {
- throw new Exception("Definition to inherit from is not of the right type! (at "+getLocation()+")");
- }
+ super.initializeFrom(definition);
+
+ if(definition instanceof UploadDefinition) {
+ UploadDefinition other = (UploadDefinition)definition;
+
+ this.required = other.required;
+ this.mimeTypes = other.mimeTypes.substring(0); // deep copy
+ this.listener = WidgetEventMulticaster.add(this.listener, other.listener);
+
+ } else {
+ throw new Exception("Definition to inherit from is not of the right type! (at "+getLocation()+")");
+ }
}
public void addMimeTypes(String types) {
- if(types != null) {
- if(mimeTypes == null)
- mimeTypes = types;
- else {
- if(mimeTypes.length()>0)
- mimeTypes += ", ";
- mimeTypes += types;
- }
- }
+ if(types != null) {
+ if(mimeTypes == null)
+ mimeTypes = types;
+ else {
+ if(mimeTypes.length()>0)
+ mimeTypes += ", ";
+ mimeTypes += types;
+ }
+ }
}
public void setRequired(boolean required) {
- this.required = required;
+ checkMutable();
+ this.required = required;
}
public Widget createInstance() {
@@ -80,5 +86,18 @@
public String getMimeTypes() {
return this.mimeTypes;
+ }
+
+ public void addValueChangedListener(ValueChangedListener listener) {
+ checkMutable();
+ this.listener = WidgetEventMulticaster.add(this.listener, listener);
+ }
+
+ public ValueChangedListener getValueChangedListener() {
+ return this.listener;
+ }
+
+ public boolean hasValueChangedListeners() {
+ return listener != null;
}
}
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java Fri Oct 21 08:30:51 2005
@@ -15,6 +15,9 @@
*/
package org.apache.cocoon.forms.formmodel;
+import java.util.Iterator;
+
+import org.apache.cocoon.forms.event.ValueChangedListener;
import org.apache.cocoon.forms.util.DomHelper;
import org.w3c.dom.Element;
@@ -34,6 +37,11 @@
super.setupDefinition(widgetElement, uploadDefinition);
setDisplayData(widgetElement, uploadDefinition);
+ Iterator iter = buildEventListeners(widgetElement, "on-value-changed", ValueChangedListener.class).iterator();
+ while (iter.hasNext()) {
+ uploadDefinition.addValueChangedListener((ValueChangedListener)iter.next());
+ }
+
if(widgetElement.hasAttribute("required"))
uploadDefinition.setRequired(DomHelper.getAttributeAsBoolean(widgetElement, "required", false));
Modified: cocoon/blocks/forms/trunk/samples/forms/carselector_form.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/carselector_form.xml?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/carselector_form.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/carselector_form.xml Fri Oct 21 08:30:51 2005
@@ -24,12 +24,12 @@
<fd:field id="make" required="true">
<fd:label>Make:</fd:label>
<fd:datatype base="string"/>
- <fd:selection-list src="cocoon:/cars" dynamic="true"/>
+ <fd:selection-list src="cocoon:/cars"/>
<fd:on-value-changed>
- <javascript>
- // The following variables are available in event listeners:
- // - "widget" and "this" are set to the current widget
- // - "event" is the event that was raised
+ <fd:javascript>
+ // The following variables are available in event listeners:
+ // - "widget" and "this" are set to the current widget
+ // - "event" is the event that was raised
java.lang.System.err.println("maker changed from " + event.oldValue + " to " + event.newValue);
var value = this.value;
var typewidget = widget.lookupWidget("../type");
@@ -57,7 +57,7 @@
msg.value = "Why not? " + value + " also makes good cars!";
}
}
- </javascript>
+ </fd:javascript>
</fd:on-value-changed>
</fd:field>
@@ -70,7 +70,7 @@
</fd:item>
</fd:selection-list>
<fd:on-value-changed>
- <javascript>
+ <fd:javascript>
java.lang.System.err.println("type changed to " + event.newValue);
var value = event.newValue;
var modelwidget = this.lookupWidget("../model");
@@ -97,9 +97,9 @@
msg.value = "So you prefer a " + value + " ?";
}
} else {
- msg.value = "I see that you're undecided...";
- }
- </javascript>
+ msg.value = "I see that you're undecided...";
+ }
+ </fd:javascript>
</fd:on-value-changed>
</fd:field>
@@ -116,18 +116,23 @@
var value = this.value;
if (value != null) {
this.lookupWidget("../message").value = "Model " + value + " is a great car!";
- this.lookupWidget("../buy").state = Packages.org.apache.cocoon.forms.formmodel.WidgetState.ACTIVE;
+ this.lookupWidget("../buy").state = Packages.org.apache.cocoon.forms.formmodel.WidgetState.ACTIVE;
} else {
// Reset value
this.value = null;
- this.lookupWidget("../buy").state = Packages.org.apache.cocoon.forms.formmodel.WidgetState.DISABLED;
+ this.lookupWidget("../buy").state = Packages.org.apache.cocoon.forms.formmodel.WidgetState.DISABLED;
}
</javascript>
</fd:on-value-changed>
</fd:field>
- <fd:output id="message">
+ <fd:output id="message" initial-value="Please choose a car above">
<fd:datatype base="string"/>
+ <fd:on-value-changed>
+ <fd:javascript>
+ java.lang.System.err.println("Message changed to '" + event.newValue + "'");
+ </fd:javascript>
+ </fd:on-value-changed>
</fd:output>
<!-- submit button, initially disabled as no model has been chosen -->
Modified: cocoon/blocks/forms/trunk/samples/forms/upload_model.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/upload_model.xml?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/upload_model.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/upload_model.xml Fri Oct 21 08:30:51 2005
@@ -25,7 +25,21 @@
<fd:upload id="upload" mime-types="text/plain" required="true">
<fd:label>Upload a text file</fd:label>
<fd:hint>You must choose a text file</fd:hint>
+ <fd:on-value-changed>
+ <fd:javascript>
+ var msg = this.lookupWidget("../message");
+ if (this.value) {
+ msg.value = "Uploaded " + this.value.fileName + ", " + this.value.size + " bytes";
+ } else {
+ msg.value = "No file uploaded currently";
+ }
+ </fd:javascript>
+ </fd:on-value-changed>
</fd:upload>
+
+ <fd:output id="message">
+ <fd:datatype base="string"/>
+ </fd:output>
</fd:widgets>
</fd:form>
Modified: cocoon/blocks/forms/trunk/samples/forms/upload_template.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/upload_template.xml?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/upload_template.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/upload_template.xml Fri Oct 21 08:30:51 2005
@@ -28,6 +28,7 @@
<fi:items>
<ft:widget id="user"/>
<ft:widget id="upload"/>
+ <ft:widget id="message"/>
<input type="submit"/>
</fi:items>
</fi:group>