cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sylv...@apache.org
Subject svn commit: r327208 - in /cocoon/blocks/forms/trunk: java/org/apache/cocoon/forms/formmodel/ samples/forms/
Date Fri, 21 Oct 2005 15:31:00 GMT
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>



Mime
View raw message