You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by si...@apache.org on 2006/04/30 19:04:39 UTC

svn commit: r398383 - in /cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms: event/ event/impl/ formmodel/

Author: simoneg
Date: Sun Apr 30 10:04:37 2006
New Revision: 398383

URL: http://svn.apache.org/viewcvs?rev=398383&view=rev
Log:
COCOON-1781 COCOON-1685 : ProcessingPhase listener fixes and configuration from definition
COCOON-1801 : repeater events.

Added:
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEvent.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEventAction.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterListener.java
Modified:
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/ProcessingPhase.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/WidgetEventMulticaster.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListener.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListenerBuilder.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Form.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinition.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinitionBuilder.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Repeater.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java
    cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/ProcessingPhase.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/ProcessingPhase.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/ProcessingPhase.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/ProcessingPhase.java Sun Apr 30 10:04:37 2006
@@ -31,6 +31,8 @@
     protected ProcessingPhase(String name, int value) {
         super(name, value);
     }
+    public static final int PROCESSING_INITIALIZE_VALUE = 4;
+    public static final ProcessingPhase PROCESSING_INITIALIZE = new ProcessingPhase("Processing initialize", PROCESSING_INITIALIZE_VALUE);
     
     public static final int LOAD_MODEL_VALUE = 0;
     public static final ProcessingPhase LOAD_MODEL = new ProcessingPhase("Load model", LOAD_MODEL_VALUE);

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEvent.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEvent.java?rev=398383&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEvent.java (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEvent.java Sun Apr 30 10:04:37 2006
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 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.cocoon.forms.event;
+
+import org.apache.cocoon.forms.formmodel.Widget;
+
+/**
+ * An event raised when a repeater widget row is added, removed or reordered.
+ * 
+ * @version $Id$
+ */
+public class RepeaterEvent extends WidgetEvent {
+
+    private int row = -1;
+    private RepeaterEventAction action = null;
+
+    /**
+     * @param sourceWidget The repeater widget dispatching the event.
+     * @param action The action for which this event is being triggered.
+     */
+    public RepeaterEvent(Widget sourceWidget, RepeaterEventAction action) {
+        super(sourceWidget);
+        this.action = action;
+    }
+    
+    /**
+     * @param sourceWidget The repeater widget dispatching the event.
+     * @param action The action for which this event is being triggered.
+     * @param row The row index for which the event is being generated. 
+     */
+    public RepeaterEvent(Widget sourceWidget, RepeaterEventAction action, int row) {
+        super(sourceWidget);
+        this.action = action;        
+        this.row = row;
+    }
+
+    /**
+     * @return Returns the row index for which the event has been generated.
+     */
+    public int getRow() {
+        return row;
+    }
+    /**
+     * @return Returns the action.
+     */
+    public RepeaterEventAction getAction() {
+        return action;
+    }
+}

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEventAction.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEventAction.java?rev=398383&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEventAction.java (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterEventAction.java Sun Apr 30 10:04:37 2006
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1999-2004 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.cocoon.forms.event;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.enums.ValuedEnum;
+
+/**
+ * Type-safe enumeration of the various repeater actions that triggers events.
+ * 
+ * @version $Id$
+ */
+public class RepeaterEventAction extends ValuedEnum {
+
+    protected RepeaterEventAction(String name, int value) {
+        super(name, value);
+    }
+    
+    public static final int ROW_ADDED_VALUE = 0;
+    /**
+     * This event type is triggered after a row has been added.
+     */
+    public static final RepeaterEventAction ROW_ADDED = new RepeaterEventAction("Row added", ROW_ADDED_VALUE);
+
+    public static final int ROW_DELETING_VALUE = 1;
+    /**
+     * This event type is triggered before a row get's removed. 
+     */
+    public static final RepeaterEventAction ROW_DELETING = new RepeaterEventAction("Row deleting", ROW_DELETING_VALUE);
+    
+    public static final int ROW_DELETED_VALUE = 2;
+    /**
+     * This event type is triggered after a row has been removed. 
+     */
+    public static final RepeaterEventAction ROW_DELETED = new RepeaterEventAction("Row deleted", ROW_DELETED_VALUE);
+    
+    public static final int ROWS_REARRANGED_VALUE = 3;
+    /**
+     * This event type is triggered after the order of one or more rows has been changed.
+     */
+    public static final RepeaterEventAction ROWS_REARRANGED = new RepeaterEventAction("Rows rearranged",ROWS_REARRANGED_VALUE);
+
+    public static final int ROWS_CLEARING_VALUE = 4;
+    /**
+     * This event type is triggered before the repeater is cleared (aka before all rows are removed). 
+     */
+    public static final RepeaterEventAction ROWS_CLEARING = new RepeaterEventAction("Rows clearing",ROWS_CLEARING_VALUE);
+    
+    public static final int ROWS_CLEARED_VALUE = 5;
+    /**
+     * This event type is triggered after the repeater has been cleared (aka after all rows have been removed)
+     */
+    public static final RepeaterEventAction ROWS_CLEARED = new RepeaterEventAction("Rows cleared",ROWS_CLEARED_VALUE);
+    
+    public static RepeaterEventAction getEnum(String name) {
+      return (RepeaterEventAction) getEnum(RepeaterEventAction.class, name);
+    }
+    
+    public static RepeaterEventAction getEnum(int value) {
+      return (RepeaterEventAction) getEnum(RepeaterEventAction.class, value);
+    }
+
+    public static Map getEnumMap() {
+      return getEnumMap(RepeaterEventAction.class);
+    }
+ 
+    public static List getEnumList() {
+      return getEnumList(RepeaterEventAction.class);
+    }
+ 
+    public static Iterator iterator() {
+      return iterator(RepeaterEventAction.class);
+    }
+}

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterListener.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterListener.java?rev=398383&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterListener.java (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/RepeaterListener.java Sun Apr 30 10:04:37 2006
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1999-2004 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.cocoon.forms.event;
+
+/**
+ * Listeners for {@link ListenerEvent}s
+ * 
+ * @version $Id$
+ */
+public interface RepeaterListener extends WidgetListener {
+    public void repeaterModified(RepeaterEvent event);
+}

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/WidgetEventMulticaster.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/WidgetEventMulticaster.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/WidgetEventMulticaster.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/WidgetEventMulticaster.java Sun Apr 30 10:04:37 2006
@@ -28,7 +28,7 @@
  * @version $Id$
  */
 public class WidgetEventMulticaster extends AWTEventMulticaster implements
-    ActionListener, ValueChangedListener, ProcessingPhaseListener {
+    ActionListener, ValueChangedListener, ProcessingPhaseListener, RepeaterListener {
 
     protected WidgetEventMulticaster(EventListener a, EventListener b) {
         super(a, b);
@@ -117,4 +117,20 @@
         if (b == null)  return a;
         return new WidgetEventMulticaster(a, b);
     }
+
+    // -- RepeaterListener -------------------------------------- 
+    
+    public void repeaterModified(RepeaterEvent e) {
+        ((RepeaterListener)a).repeaterModified(e);
+        ((RepeaterListener)b).repeaterModified(e);
+    }
+    
+    public static RepeaterListener add(RepeaterListener a, RepeaterListener b) {
+        return (RepeaterListener)addInternal(a, b);
+    }
+    
+    public static RepeaterListener remove(RepeaterListener l, RepeaterListener oldl) {
+        return (RepeaterListener)removeInternal(l, oldl);
+    }
+    
 }

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListener.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListener.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListener.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListener.java Sun Apr 30 10:04:37 2006
@@ -15,17 +15,19 @@
  */
 package org.apache.cocoon.forms.event.impl;
 
-import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.avalon.framework.CascadingRuntimeException;
 import org.apache.avalon.framework.context.Context;
 import org.apache.cocoon.components.ContextHelper;
-import org.apache.cocoon.components.flow.FlowHelper;
 import org.apache.cocoon.forms.event.ActionEvent;
 import org.apache.cocoon.forms.event.ActionListener;
 import org.apache.cocoon.forms.event.CreateEvent;
 import org.apache.cocoon.forms.event.CreateListener;
+import org.apache.cocoon.forms.event.ProcessingPhaseEvent;
+import org.apache.cocoon.forms.event.ProcessingPhaseListener;
+import org.apache.cocoon.forms.event.RepeaterEvent;
+import org.apache.cocoon.forms.event.RepeaterListener;
 import org.apache.cocoon.forms.event.ValueChangedEvent;
 import org.apache.cocoon.forms.event.ValueChangedListener;
 import org.apache.cocoon.forms.event.WidgetEvent;
@@ -55,24 +57,11 @@
      */
     protected void callScript(WidgetEvent event) {
         try {
-            
-            HashMap values = new HashMap(2);
-            values.put("event", event);
             //FIXME(SW) it would be nice to have "this" be the widget, but I don't know how to define
             //the "this" object for a script (this is easy for a function)
-            
             Map objectModel = ContextHelper.getObjectModel(context);
-
-            // Add the view data that was passed to showForm()
-            Object viewData = FlowHelper.getContextObject(objectModel);
-            if (viewData != null) {
-                values.put("viewData", viewData);
-            }
-            
             Widget w = event.getSourceWidget();
-            
             JavaScriptHelper.callFunction(this.func, w, new Object[]{w, event}, objectModel);
-            
         } catch(RuntimeException re) {
             // rethrow
             throw re;
@@ -124,4 +113,29 @@
             super.callScript(event);
         }
     }
+
+    public static class JSProcessingPhaseListener extends JavaScriptWidgetListener implements ProcessingPhaseListener {
+
+        public JSProcessingPhaseListener(Function func, Context context) {
+            super(func, context);
+        }
+
+        public void phaseEnded(ProcessingPhaseEvent event) {
+            super.callScript(event);
+        }
+    }
+
+    
+    public static class JSRepeaterListener extends JavaScriptWidgetListener implements RepeaterListener {
+
+        public JSRepeaterListener(Function func, Context context) {
+            super(func, context);
+        }
+
+        public void repeaterModified(RepeaterEvent event) {
+            super.callScript(event);
+        }
+    }
+    
 }
+

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListenerBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListenerBuilder.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListenerBuilder.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/event/impl/JavaScriptWidgetListenerBuilder.java Sun Apr 30 10:04:37 2006
@@ -21,6 +21,8 @@
 import org.apache.avalon.framework.thread.ThreadSafe;
 import org.apache.cocoon.forms.event.ActionListener;
 import org.apache.cocoon.forms.event.CreateListener;
+import org.apache.cocoon.forms.event.ProcessingPhaseListener;
+import org.apache.cocoon.forms.event.RepeaterListener;
 import org.apache.cocoon.forms.event.ValueChangedListener;
 import org.apache.cocoon.forms.event.WidgetListener;
 import org.apache.cocoon.forms.event.WidgetListenerBuilder;
@@ -64,6 +66,10 @@
             return new JavaScriptWidgetListener.JSValueChangedListener(func, context);
         } else if (listenerClass == TreeSelectionListener.class) {
             return new JavaScriptWidgetListener.JSTreeSelectionListener(func, context);
+        } else if (listenerClass == ProcessingPhaseListener.class) {
+            return new JavaScriptWidgetListener.JSProcessingPhaseListener(func, context);
+        } else if (listenerClass == RepeaterListener.class) {
+            return new JavaScriptWidgetListener.JSRepeaterListener(func, context);
         } else {
             throw new Exception("Unkonwn event class: " + listenerClass);
         }

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Form.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Form.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Form.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Form.java Sun Apr 30 10:04:37 2006
@@ -78,6 +78,7 @@
     public Form(FormDefinition definition) {
         super(definition);
         this.definition = definition;
+        this.listener = definition.getProcessingPhaseListener();
     }
 
     /**
@@ -292,6 +293,8 @@
         // Fire the binding phase events
         fireEvents();
 
+        this.phase = ProcessingPhase.PROCESSING_INITIALIZE;
+        
         // setup processing
         this.submitWidget = null;
         this.locale = formContext.getLocale();

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinition.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinition.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinition.java Sun Apr 30 10:04:37 2006
@@ -83,4 +83,10 @@
 
         super.addWidgetDefinition(definition);
     }
+    /**
+     * @return Returns the listener.
+     */
+    public ProcessingPhaseListener getProcessingPhaseListener() {
+        return listener;
+    }
 }

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinitionBuilder.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinitionBuilder.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/FormDefinitionBuilder.java Sun Apr 30 10:04:37 2006
@@ -15,8 +15,12 @@
  */
 package org.apache.cocoon.forms.formmodel;
 
+import java.util.Iterator;
+
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.forms.event.ProcessingPhaseListener;
+import org.apache.cocoon.forms.event.ValueChangedListener;
 import org.apache.cocoon.forms.formmodel.library.LibraryManager;
 import org.apache.cocoon.util.location.LocationAttributes;
 import org.w3c.dom.Element;
@@ -47,6 +51,11 @@
         
         // set local URI
         formDefinition.getLocalLibrary().setSourceURI(LocationAttributes.getURI(formElement));
+    
+        Iterator iter = buildEventListeners(formElement, "on-processing-phase", ProcessingPhaseListener.class).iterator();
+        while (iter.hasNext()) {
+            formDefinition.addProcessingPhaseListener((ProcessingPhaseListener)iter.next());
+        }
         
         super.setupDefinition(formElement, formDefinition);
         setDisplayData(formElement, formDefinition);

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Repeater.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Repeater.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Repeater.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/Repeater.java Sun Apr 30 10:04:37 2006
@@ -24,7 +24,11 @@
 import org.apache.cocoon.forms.FormContext;
 import org.apache.cocoon.forms.FormsConstants;
 import org.apache.cocoon.forms.FormsRuntimeException;
+import org.apache.cocoon.forms.event.RepeaterEvent;
+import org.apache.cocoon.forms.event.RepeaterEventAction;
+import org.apache.cocoon.forms.event.RepeaterListener;
 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;
@@ -59,6 +63,7 @@
     protected final List rows = new ArrayList();
     protected ValidationError validationError;
     private boolean orderable = false;
+    private RepeaterListener listener;
 
     public Repeater(RepeaterDefinition repeaterDefinition) {
         super(repeaterDefinition);
@@ -70,6 +75,7 @@
         }
         
         this.orderable = this.definition.getOrderable();
+        this.listener = this.definition.getRepeaterListener();
     }
 
     public WidgetDefinition getDefinition() {
@@ -79,6 +85,8 @@
     public void initialize() {
         for (int i = 0; i < this.rows.size(); i++) {
             ((RepeaterRow)rows.get(i)).initialize();
+            // TODO(SG) Is this safe !?
+            broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROW_ADDED, i));
         }
         super.initialize();
     }
@@ -100,6 +108,7 @@
         rows.add(repeaterRow);
         repeaterRow.initialize();
         getForm().addWidgetUpdate(this);
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROW_ADDED, rows.size() - 1));
         return repeaterRow;
     }
 
@@ -107,11 +116,13 @@
         RepeaterRow repeaterRow = new RepeaterRow(definition);
         if (index >= this.rows.size()) {
             rows.add(repeaterRow);
+            index = rows.size() - 1;
         } else {
             rows.add(index, repeaterRow);
         }
         repeaterRow.initialize();
         getForm().addWidgetUpdate(this);
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROW_ADDED, index));
         return repeaterRow;
     }
 
@@ -174,8 +185,10 @@
      * @throws IndexOutOfBoundsException if the the index is outside the range of existing rows.
      */
     public void removeRow(int index) {
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROW_DELETING, index));
         rows.remove(index);
         getForm().addWidgetUpdate(this);
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROW_DELETED, index));
     }
 
     /**
@@ -209,6 +222,7 @@
         }
 
         getForm().addWidgetUpdate(this);
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROWS_REARRANGED));        
     }
 
     public void moveRowLeft(int index) {
@@ -220,6 +234,7 @@
             this.rows.set(index, temp);
         }
         getForm().addWidgetUpdate(this);
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROWS_REARRANGED));                
     }
 
     public void moveRowRight(int index) {
@@ -231,6 +246,7 @@
             this.rows.set(index, temp);
         }
         getForm().addWidgetUpdate(this);
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROWS_REARRANGED));                
     }
 
     /**
@@ -245,7 +261,9 @@
      * Clears all rows from the repeater and go back to the initial size
      */
     public void clear() {
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROWS_CLEARING));        
         rows.clear();
+        broadcastEvent(new RepeaterEvent(this, RepeaterEventAction.ROWS_CLEARED));        
 
         // and reset to initial size
         for (int i = 0; i < this.definition.getInitialSize(); i++) {
@@ -253,6 +271,30 @@
         }
         getForm().addWidgetUpdate(this);
     }
+    
+    public void addRepeaterListener(RepeaterListener listener) {
+        this.listener = WidgetEventMulticaster.add(this.listener, listener);
+    }
+
+    public void removeRepeaterListener(RepeaterListener listener) {
+        this.listener = WidgetEventMulticaster.remove(this.listener, listener);
+    }
+
+    public boolean hasRepeaterListeners() {
+        return this.listener != null;
+    }
+
+    public void broadcastEvent(WidgetEvent event) {
+        if (event instanceof RepeaterEvent) {
+            if (this.listener != null) {
+                this.listener.repeaterModified((RepeaterEvent)event);
+            }
+        } else {
+            // Other kinds of events
+            super.broadcastEvent(event);
+        }
+    }
+    
 
     /**
      * Gets a widget on a certain row.
@@ -511,7 +553,6 @@
         public void initialize() {
             // Initialize children but don't call super.initialize() that would call the repeater's
             // on-create handlers for each row.
-            // FIXME(SW): add an 'on-create-row' handler?
             Iterator it = this.getChildren();
             while(it.hasNext()) {
               ((Widget)it.next()).initialize();

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java Sun Apr 30 10:04:37 2006
@@ -15,6 +15,11 @@
  */
 package org.apache.cocoon.forms.formmodel;
 
+import org.apache.cocoon.forms.event.RepeaterEvent;
+import org.apache.cocoon.forms.event.RepeaterListener;
+import org.apache.cocoon.forms.event.ValueChangedListener;
+import org.apache.cocoon.forms.event.WidgetEventMulticaster;
+
 /**
  * The {@link WidgetDefinition} part of a Repeater widget, see {@link Repeater} for more information.
  * 
@@ -25,6 +30,7 @@
     private int minSize;
     private int maxSize;
     private boolean orderable;
+    private RepeaterListener listener;
 
     public RepeaterDefinition(int initialSize, int minSize, int maxSize, boolean selectable, boolean orderable) {
         super();
@@ -69,4 +75,24 @@
     public boolean getOrderable() {
         return this.orderable;
     }
+    
+    public void addRepeaterListener(RepeaterListener listener) {
+        checkMutable();
+        this.listener = WidgetEventMulticaster.add(this.listener, listener);
+    }
+    
+    public void fireRepeaterEvent(RepeaterEvent event) {
+        if (this.listener != null) {
+            this.listener.repeaterModified(event);
+        }
+    }
+    
+    public boolean hasRepeaterListeners() {
+        return this.listener != null;
+    }
+
+    public RepeaterListener getRepeaterListener() {
+        return this.listener;
+    }
+    
 }

Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java?rev=398383&r1=398382&r2=398383&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java Sun Apr 30 10:04:37 2006
@@ -15,7 +15,11 @@
  */
 package org.apache.cocoon.forms.formmodel;
 
+import java.util.Iterator;
+
 import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.forms.event.RepeaterListener;
+import org.apache.cocoon.forms.event.ValueChangedListener;
 import org.apache.cocoon.forms.util.DomHelper;
 import org.w3c.dom.Element;
 
@@ -55,6 +59,12 @@
         super.setupDefinition(repeaterElement, repeaterDefinition);
         setDisplayData(repeaterElement, repeaterDefinition);
 
+        // parse "on-repeater-modified"
+        Iterator iter = buildEventListeners(repeaterElement, "on-repeater-modified", RepeaterListener.class).iterator();
+        while (iter.hasNext()) {
+            repeaterDefinition.addRepeaterListener((RepeaterListener)iter.next());
+        }        
+        
         setupContainer(repeaterElement,"widgets",repeaterDefinition);
 
         repeaterDefinition.makeImmutable();