cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jheym...@apache.org
Subject svn commit: r330548 [98/132] - in /cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/ cocoon-ajax-block/api/ cocoon-ajax-block/api/src/ cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/ cocoon-ajax-block/api/src/main/...
Date Thu, 03 Nov 2005 14:00:48 GMT
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterActionDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterActionDefinitionBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterActionDefinitionBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterActionDefinitionBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,114 @@
+/*
+ * 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.formmodel;
+
+import java.util.Iterator;
+
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.forms.event.ActionListener;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.apache.cocoon.util.Deprecation;
+import org.w3c.dom.Element;
+
+/**
+ * Builds a <code>&lt;fd:repeater-action/&gt;</code>
+ *
+ * <p>Three actions are defined:
+ * <ul>
+ * <li>
+ *   <code>&lt;fd:repeater-action id="add" command="add-row"
+ *   repeater="repeater-id"/&gt;</code>: when activated, adds a row to the
+ *   sibling repeater named "repeater-id".
+ * </li>
+ * <li>
+ *   <code>&lt;fd:repeater-action id="rm" command="delete-rows"
+ *   repeater="repeater-id" select="select-id"/&gt;</code>: removes the
+ *   selected rows from the sibling repeater named "repeater-id". The
+ *   selected rows are identified by the boolean field "select-id" present
+ *   in each row.
+ * </li>
+ * <li>
+ *   <code>&lt;fd:repeater-action id="insert" command="insert-rows"
+ *   repeater="repeater-id" select="select-id"/&gt;</code>: inserts rows before
+ *   the selected rows from the sibling repeater named "repeater-id". The
+ *   selected rows are identified by the boolean field "select-id" present
+ *   in each row.
+ * </li>
+ * </ul>
+ *
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: RepeaterActionDefinitionBuilder.java 326838 2005-10-20 06:26:53Z sylvain $
+ */
+public class RepeaterActionDefinitionBuilder extends AbstractWidgetDefinitionBuilder {
+
+    public WidgetDefinition buildWidgetDefinition(Element widgetElement) throws Exception {
+        // Get the "command" attribute
+        String actionCommand = DomHelper.getAttribute(widgetElement, "command", null);
+        
+        // If unspecified, check the deprecated "action-command" deprecated attribute
+        if (actionCommand == null) {
+            actionCommand = DomHelper.getAttribute(widgetElement, "action-command", null);
+            if (actionCommand != null) {
+                Deprecation.logger.info("The 'action-command' attribute is deprecated and replaced by 'command', at " +
+                    DomHelper.getLocation(widgetElement));
+            }
+        }
+        if (actionCommand == null) {
+            throw new Exception("Missing attribute 'command' at " + DomHelper.getLocation(widgetElement));
+        }
+
+
+        RepeaterActionDefinition definition = createDefinition(widgetElement, actionCommand);
+        super.setupDefinition(widgetElement, definition);
+        setDisplayData(widgetElement, definition);
+
+        definition.setActionCommand(actionCommand);
+
+        // Warn of the mis-named 'on-action' that existed initially
+        Element buggyOnActivate = DomHelper.getChildElement(widgetElement, FormsConstants.DEFINITION_NS, "on-activate", false);
+        if (buggyOnActivate != null) {
+            throw new Exception("Use 'on-action' instead of 'on-activate' on row-action at " +
+                DomHelper.getLocation(buggyOnActivate));
+        }
+
+        Iterator iter = buildEventListeners(widgetElement, "on-action", ActionListener.class).iterator();
+        while (iter.hasNext()) {
+            definition.addActionListener((ActionListener)iter.next());
+        }
+
+        definition.makeImmutable();
+        return definition;
+    }
+
+    protected RepeaterActionDefinition createDefinition(Element element, String actionCommand) throws Exception {
+
+        String repeater = DomHelper.getAttribute(element, "repeater");
+        if ("delete-rows".equals(actionCommand)) {
+            String select = DomHelper.getAttribute(element, "select");
+            return new RepeaterActionDefinition.DeleteRowsActionDefinition(repeater, select);
+
+        } else if ("add-row".equals(actionCommand)) {
+            return new RepeaterActionDefinition.AddRowActionDefinition(repeater);
+
+        } else if ("insert-rows".equals(actionCommand)) {
+            String select = DomHelper.getAttribute(element, "select");
+            return new RepeaterActionDefinition.InsertRowsActionDefinition(repeater, select);
+
+        } else {
+            throw new Exception("Unknown repeater action '" + actionCommand + "' at " + DomHelper.getLineLocation(element));
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterActionDefinitionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,66 @@
+/*
+ * 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.formmodel;
+
+/**
+ * The {@link WidgetDefinition} part of a Repeater widget, see {@link Repeater} for more information.
+ * 
+ * @version $Id: RepeaterDefinition.java 307119 2005-10-07 13:28:45Z sylvain $
+ */
+public class RepeaterDefinition extends AbstractContainerDefinition {
+    private int initialSize = 0;
+    private int minSize;
+    private int maxSize;
+
+    public RepeaterDefinition(int initialSize, int minSize, int maxSize) {
+        super();
+        this.initialSize = initialSize;
+        this.minSize = minSize;
+        this.maxSize = maxSize;
+    }
+    
+    /**
+     * 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 RepeaterDefinition) {
+            RepeaterDefinition other = (RepeaterDefinition)definition;
+            this.initialSize = other.initialSize;
+            this.maxSize = other.maxSize;
+            this.minSize = other.minSize;
+        } else {
+            throw new Exception("Definition to inherit from is not of the right type! (at "+getLocation()+")");
+        }
+    }
+
+    public Widget createInstance() {
+        return new Repeater(this);
+    }
+    
+    public int getInitialSize() {
+        return this.initialSize;
+    }
+
+    public int getMaxSize() {
+        return this.maxSize;
+    }
+
+    public int getMinSize() {
+        return this.minSize;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,60 @@
+/*
+ * 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.formmodel;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * Builds {@link RepeaterDefinition}s.
+ * 
+ * @version $Id: RepeaterDefinitionBuilder.java 307119 2005-10-07 13:28:45Z sylvain $
+ */
+public final class RepeaterDefinitionBuilder extends AbstractContainerDefinitionBuilder {
+
+    public WidgetDefinition buildWidgetDefinition(Element repeaterElement) throws Exception {
+        
+        int initialSize = DomHelper.getAttributeAsInteger(repeaterElement, "initial-size", 0);
+        int minSize = DomHelper.getAttributeAsInteger(repeaterElement, "min-size", 0);
+        int maxSize = DomHelper.getAttributeAsInteger(repeaterElement, "max-size", Integer.MAX_VALUE);
+
+        // should throw error on negative values ? Just correct them for now. 
+        if (minSize < 0) {
+            throw new ConfigurationException("min-size should be positive, at " + DomHelper.getLocationObject(repeaterElement));
+        }
+        
+        if (maxSize < 0) {
+            throw new ConfigurationException("max-size should be positive, at " + DomHelper.getLocationObject(repeaterElement));
+        }
+        
+        if (maxSize < minSize) {
+            throw new ConfigurationException("max-size should be greater that or equal to min-size, at " + DomHelper.getLocationObject(repeaterElement));
+        }
+
+        // initial size is at least the min size
+        initialSize = minSize > initialSize ? minSize : initialSize;
+                
+        RepeaterDefinition repeaterDefinition = new RepeaterDefinition(initialSize, minSize, maxSize);
+        super.setupDefinition(repeaterElement, repeaterDefinition);
+        setDisplayData(repeaterElement, repeaterDefinition);
+
+        setupContainer(repeaterElement,"widgets",repeaterDefinition);
+
+        repeaterDefinition.makeImmutable();
+        return repeaterDefinition;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RepeaterDefinitionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowAction.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowAction.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowAction.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowAction.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,65 @@
+/*
+ * 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.formmodel;
+
+import java.util.Locale;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * 
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: RowAction.java 151179 2005-02-03 16:55:16Z tim $
+ */
+public class RowAction extends Action {
+    public RowAction(RowActionDefinition definition) {
+        super(definition);
+    }
+    
+    public static class MoveUpAction extends RowAction {
+        public MoveUpAction(RowActionDefinition.MoveUpDefinition definition) {
+            super(definition);
+        }
+
+        public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException {
+            
+            // Only generate if we're not at the top
+            Repeater.RepeaterRow row = Repeater.getParentRow(this);
+            if (((Repeater)row.getParent()).indexOf(row) > 0) {
+                super.generateSaxFragment(contentHandler, locale);
+            }
+        }
+    }
+
+    public static class MoveDownAction extends RowAction {
+        public MoveDownAction(RowActionDefinition.MoveDownDefinition definition) {
+            super(definition);
+        }
+
+        public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException {
+            
+            // Only generate if we're not at the bottom
+            Repeater.RepeaterRow row = Repeater.getParentRow(this);
+            Repeater repeater = (Repeater)row.getParent();
+            
+            if (repeater.indexOf(row) < repeater.getSize() - 1) {
+                super.generateSaxFragment(contentHandler, locale);
+            }
+        }
+    }
+}
+

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowAction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinition.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinition.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinition.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,106 @@
+/*
+ * 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.formmodel;
+
+import org.apache.cocoon.forms.event.ActionEvent;
+import org.apache.cocoon.forms.event.ActionListener;
+
+/**
+ * 
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: RowActionDefinition.java 151179 2005-02-03 16:55:16Z tim $
+ */
+public class RowActionDefinition extends ActionDefinition {
+    
+    public Widget createInstance() {
+        return new RowAction(this);
+    }
+    
+    /**
+     * Deletes the row containing this action. Action listeners, if any, are called <em>before</em>
+     * the row is deleted.
+     */
+    public static class DeleteRowDefinition extends RowActionDefinition {
+        
+        public boolean hasActionListeners() {
+            // We always want to be notified
+            return true;
+        }
+        
+        public void fireActionEvent(ActionEvent event) {
+            // Call event listeners, if any (the row still exists)
+            super.fireActionEvent(event);
+
+            // and delete the row
+            Repeater.RepeaterRow row = Repeater.getParentRow(event.getSourceWidget());
+            Repeater repeater = (Repeater)row.getParent();
+            repeater.removeRow(repeater.indexOf(row));
+        }
+    }
+    
+    /**
+     * Moves up the row containing this action. Action listeners, if any, are called <em>after</em>
+     * the row has been moved.
+     */
+    public static class MoveUpDefinition extends RowActionDefinition {
+        public MoveUpDefinition() {
+            super.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent event) {
+                    Repeater.RepeaterRow row = Repeater.getParentRow(event.getSourceWidget());
+                    Repeater repeater = (Repeater)row.getParent();
+                    // Rotation: up in a table is left in a list!
+                    repeater.moveRowLeft(repeater.indexOf(row));
+                }
+            });
+        }
+    }
+    
+    /**
+     * Moves up the row containing this action. Action listeners, if any, are called <em>after</em>
+     * the row has been moved.
+     */
+    public static class MoveDownDefinition extends RowActionDefinition {
+        public MoveDownDefinition() {
+            super.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent event) {
+                    Repeater.RepeaterRow row = Repeater.getParentRow(event.getSourceWidget());
+                    Repeater repeater = (Repeater)row.getParent();
+                    // Rotation : down in a table is right in a list!
+                    repeater.moveRowRight(repeater.indexOf(row));
+                }
+            });
+        }
+    }
+    
+    /**
+     * Adds a row after the one containing this action. Action listeners, if any, are called <em>after</em>
+     * the new row has been created.
+     */
+    public static class AddAfterDefinition extends RowActionDefinition {
+        public AddAfterDefinition() {
+            super.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent event) {
+                    Repeater.RepeaterRow row = Repeater.getParentRow(event.getSourceWidget());
+                    Repeater repeater = (Repeater)row.getParent();
+                    repeater.addRow(repeater.indexOf(row)+1);
+                }
+            });
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinitionBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinitionBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinitionBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,91 @@
+/*
+ * 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.formmodel;
+
+import java.util.Iterator;
+
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.forms.event.ActionListener;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.apache.cocoon.util.Deprecation;
+import org.w3c.dom.Element;
+
+/**
+ * 
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: RowActionDefinitionBuilder.java 326838 2005-10-20 06:26:53Z sylvain $
+ */
+public class RowActionDefinitionBuilder extends AbstractWidgetDefinitionBuilder {
+    
+    
+    public WidgetDefinition buildWidgetDefinition(Element widgetElement) throws Exception {
+        // Get the "command" attribute
+        String actionCommand = DomHelper.getAttribute(widgetElement, "command", null);
+        
+        // If unspecified, check the deprecated "action-command" deprecated attribute
+        if (actionCommand == null) {
+            actionCommand = DomHelper.getAttribute(widgetElement, "action-command", null);
+            if (actionCommand != null) {
+                Deprecation.logger.info("The 'action-command' attribute is deprecated and replaced by 'command', at " +
+                    DomHelper.getLocation(widgetElement));
+            }
+        }
+        if (actionCommand == null) {
+            throw new Exception("Missing attribute 'command' at " + DomHelper.getLocation(widgetElement));
+        }
+
+        RowActionDefinition definition = createDefinition(widgetElement, actionCommand);
+        super.setupDefinition(widgetElement, definition);
+        setDisplayData(widgetElement, definition);
+
+        definition.setActionCommand(actionCommand);
+
+        // Warn of the mis-named 'on-action' that existed initially
+        Element buggyOnActivate = DomHelper.getChildElement(widgetElement, FormsConstants.DEFINITION_NS, "on-activate", false);
+        if (buggyOnActivate != null) {
+            throw new Exception("Use 'on-action' instead of 'on-activate' on row-action at " +
+                DomHelper.getLocation(buggyOnActivate));
+        }
+
+        Iterator iter = buildEventListeners(widgetElement, "on-action", ActionListener.class).iterator();
+        while (iter.hasNext()) {
+            definition.addActionListener((ActionListener)iter.next());
+        }
+
+        definition.makeImmutable();
+        return definition;
+    }
+    
+    protected RowActionDefinition createDefinition(Element element, String actionCommand) throws Exception {
+
+        if ("delete".equals(actionCommand)) {
+            return new RowActionDefinition.DeleteRowDefinition();
+
+        } else if ("add-after".equals(actionCommand)) {
+            return new RowActionDefinition.AddAfterDefinition();
+
+        } else if ("move-up".equals(actionCommand)) {
+            return new RowActionDefinition.MoveUpDefinition();
+
+        } else if ("move-down".equals(actionCommand)) {
+            return new RowActionDefinition.MoveDownDefinition();
+
+        } else {
+            throw new Exception("Unknown repeater row action '" + actionCommand + "' at " + DomHelper.getLineLocation(element));
+        }
+    }
+}
+

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/RowActionDefinitionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SelectableWidget.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SelectableWidget.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SelectableWidget.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SelectableWidget.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,53 @@
+/*
+ * 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.formmodel;
+
+import org.apache.cocoon.forms.datatype.SelectionList;
+
+/**
+ * A {@link Widget} that can have a selection list. The initial selection list is set by the
+ * widget's {@link WidgetDefinition}, and can be changed afterwards. The selection list can
+ * be removed by setting the list to <code>null</code>.
+ * 
+ * @version $Id: SelectableWidget.java 155211 2005-02-24 17:05:51Z sylvain $
+ */
+public interface SelectableWidget extends Widget {
+
+    /**
+     * Set the widget's selection list given a {@link SelectionList}.
+     * 
+     * @param selectionList the selection list or <code>null</code> to have no selection list.
+     */
+    public void setSelectionList(SelectionList selectionList);
+
+    /**
+     * Set the widget's selection list given a source URI where the list will be read from.
+     * 
+     * @param uri the selection list's URI
+     */
+    public void setSelectionList(String uri);
+
+    /**
+     * Set the widgdet's selection given an object and XPath expressions.
+     * 
+     * @param model the selection list model. This is typically a collection or an array of objects
+     *        in which <code>valuePath</code> and <code>labelPath</code> will extract some data.
+     * @param valuePath the XPath expression to extract values
+     * @param labelPath the XPath expression to extract labels (can be absent in which case the value is
+     *        used as label).
+     */
+    public void setSelectionList(Object model, String valuePath, String labelPath);
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SelectableWidget.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Struct.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Struct.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Struct.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Struct.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,39 @@
+/*
+ * 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.formmodel;
+
+
+/**
+ * A container {@link Widget} which can hold zero or more child widgets.
+ * 
+ * @deprecated replaced by {@link Group}
+ * @version $Id: Struct.java 155211 2005-02-24 17:05:51Z sylvain $
+ */
+public class Struct extends Group {
+    private static final String STRUCT_EL = "struct";
+    
+    public Struct(GroupDefinition definition) {
+        super(definition);
+    }
+
+    /**
+     * @return "struct"
+     */
+    public String getXMLElementName() {
+        return STRUCT_EL;
+    }
+    
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Struct.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinition.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinition.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinition.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,31 @@
+/*
+ * 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.formmodel;
+
+/**
+ * The {@link WidgetDefinition} corresponding to a {@link Struct} widget.
+ *
+ * @deprecated replaced by {@link GroupDefinition}
+ * @version $Id: StructDefinition.java 155211 2005-02-24 17:05:51Z sylvain $
+ */
+public class StructDefinition extends GroupDefinition {
+
+    public Widget createInstance() {
+        Struct structWidget = new Struct(this);
+        createWidgets(structWidget);
+        return structWidget;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinitionBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinitionBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinitionBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,40 @@
+/*
+ * 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.formmodel;
+
+import org.apache.cocoon.util.Deprecation;
+import org.w3c.dom.Element;
+
+/**
+ * Builds {StructDefinition}s.
+ *
+ * @deprecated replaced by {@link GroupDefinitionBuilder}
+ * @version $Id: StructDefinitionBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class StructDefinitionBuilder extends AbstractContainerDefinitionBuilder {
+
+    public WidgetDefinition buildWidgetDefinition(Element element) throws Exception {
+        StructDefinition definition = new StructDefinition();
+        super.setupDefinition(element, definition);
+        setDisplayData(element, definition);
+
+        setupContainer(element,"widgets",definition);
+
+        definition.makeImmutable();
+        Deprecation.logger.info("Use of 'fd:struct' is deprecated. Use 'fd:group' instead, at " + definition.getLocation());
+        return definition;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/StructDefinitionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Submit.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Submit.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Submit.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Submit.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,41 @@
+/*
+ * 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.formmodel;
+
+/**
+ * A submit is an action that exits of the current form.
+ * 
+ * @see SubmitDefinitionBuilder
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: Submit.java 151179 2005-02-03 16:55:16Z tim $
+ */
+public class Submit extends Action {
+
+    private boolean validateForm;
+    
+    public Submit(ActionDefinition definition, boolean validateForm) {
+        super(definition);
+        this.validateForm = validateForm;
+    }
+    
+    protected void handleActivate() {
+        if (!validateForm) {
+            // End the form processing now and don't redisplay the form.
+            getForm().endProcessing(false);
+        }
+        // Otherwise let the normal processing flow continue.
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Submit.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinition.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinition.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinition.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,53 @@
+/*
+ * 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.formmodel;
+
+/**
+ * Definition for a {@link Submit}.
+ * 
+ * @see SubmitDefinitionBuilder
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: SubmitDefinition.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class SubmitDefinition extends ActionDefinition {
+    
+    private boolean validateForm;
+    
+    /**
+     * 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 SubmitDefinition) {
+    		SubmitDefinition other = (SubmitDefinition)definition;
+    		
+    		this.validateForm = other.validateForm;
+    		
+    	} else {
+    		throw new Exception("Definition to inherit from is not of the right type! (at "+getLocation()+")");
+    	}
+    }
+    
+    public void setValidateForm(boolean validateForm) {
+        checkMutable();
+        this.validateForm = validateForm;
+    }
+    
+    public Widget createInstance() {
+        return new Submit(this, validateForm);
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinitionBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinitionBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinitionBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,47 @@
+/*
+ * 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.formmodel;
+
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * Builds a <code>&lt;fd:submit&gt;</code> widget. A submit is an action that
+ * terminates the current form. It can either require the form to be valid
+ * (in which case it will be redisplayed if not valid) or terminate it without
+ * validation (e.g. a "cancel" button).
+ *
+ * <p>The syntax is as follows:
+ * <pre>
+ *   &lt;wd:submit id="sub-id" command="cmd" validate="false"&gt;
+ * </pre>
+ * The "validate" attribute can have the value <code>true</code> or
+ * <code>false</code> and determines if the form is to be validated
+ * (defaults to true).</p>
+ *
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: SubmitDefinitionBuilder.java 155211 2005-02-24 17:05:51Z sylvain $
+ */
+public final class SubmitDefinitionBuilder extends ActionDefinitionBuilder {
+
+    public WidgetDefinition buildWidgetDefinition(Element widgetElement) throws Exception {
+        SubmitDefinition definition = new SubmitDefinition();
+        super.setupDefinition(widgetElement, definition);
+        definition.setValidateForm(DomHelper.getAttributeAsBoolean(widgetElement, "validate", true));
+        definition.makeImmutable();
+        return definition;
+    }    
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/SubmitDefinitionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Union.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Union.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Union.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Union.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,158 @@
+/*
+ * 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.formmodel;
+
+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.commons.lang.ObjectUtils;
+
+/**
+ * A discriminated union that references a discriminant value in another
+ * widget and contains one of several cases (widgets).  To have a case
+ * hold more than one widget or to use a different id for the case than
+ * for the widget id, just wrap the widget(s) in a container widget named
+ * with the desired case id.
+ *
+ * @version $Id: Union.java 210082 2005-07-11 08:06:48Z cziegeler $
+ */
+public class Union extends AbstractContainerWidget {
+
+    //Note: union instances behave like simple "field" instance with respect to 
+    //      XSLT post-processing, the choice of element-name reflects this.
+    private static final String UNION_EL = "field";
+
+    private Widget caseWidget;
+    private String caseValue;
+
+    private final UnionDefinition definition;
+
+    public Union(UnionDefinition definition) {
+        super(definition);
+        this.definition = definition;
+        // TODO: Remove after moving logic to Field.
+        //item.enteredValue = (String)definition.getDefaultValue();
+    }
+
+    public WidgetDefinition getDefinition() {
+        return definition;
+    }
+
+    /**
+     * Called after widget's environment has been setup,
+     * to allow for any contextual initalization such as
+     * looking up case widgets for union widgets.
+     */
+    public void initialize() {
+        String caseWidgetId = definition.getCaseWidgetId();
+        this.caseWidget = getParent().lookupWidget(caseWidgetId);
+        if(this.caseWidget == null) {
+            throw new RuntimeException("Could not find case widget \""
+                + caseWidgetId + "\" for union \"" + getId() + "\" at " + getLocation());
+        }
+        ((ValueChangedListenerEnabled)caseWidget).addValueChangedListener(
+            new ValueChangedListener() {
+                public void valueChanged(ValueChangedEvent event) {
+                    String newValue = (String)event.getNewValue();
+                    if (!ObjectUtils.equals(Union.this.caseValue, newValue)) {
+                        Union.this.caseValue = newValue;
+                        getForm().addWidgetUpdate(Union.this);
+                    }
+                }
+            }
+        );
+    }
+
+    /**
+     * @return "field"
+     */
+    public String getXMLElementName() {
+        return UNION_EL;
+    }
+
+    public Object getValue() {
+        return this.caseWidget.getValue();
+    }
+
+    public void readFromRequest(FormContext formContext) {
+        // Ensure the case widget has read its value
+        this.caseWidget.readFromRequest(formContext);
+
+        Widget widget;
+        // Read current case from request
+        String newValue = (String)getValue();
+        if (newValue != null && !newValue.equals("")) {
+
+            if (getForm().getSubmitWidget() == this.caseWidget && !newValue.equals(this.caseValue)) {
+                // If submitted by the case widget and its value has changed, read the values
+                // for the previous case value. This allows to keep any already entered values
+                // despite the case change.
+                widget = getChild(this.caseValue);
+            } else {
+                // Get the corresponding widget (will create it if needed)
+                widget = getChild(newValue);
+            }
+
+            if (widget != null && getCombinedState().isAcceptingInputs()) {
+                widget.readFromRequest(formContext);
+            }
+        }
+        
+        if (!ObjectUtils.equals(this.caseValue, newValue)) {
+            this.caseValue = newValue;
+            getForm().addWidgetUpdate(this);
+        }
+    }
+
+    // TODO: Simplify this logic.
+    public boolean validate() {
+        if (!getCombinedState().isValidatingValues()) {
+            this.wasValid = true;
+            return true;
+        }
+        Widget widget;
+        boolean valid = true;
+        // Read current case from request
+        String value = (String)getValue();
+        if (value != null && !value.equals("")) {
+            if ((widget = getChild(value)) != null) {
+                valid = valid & widget.validate();
+            }
+        }
+        this.wasValid = valid;
+        return valid;
+    }
+
+    public Widget getChild(String id) {
+        if (!widgets.hasWidget(id) && ((ContainerDefinition)definition).hasWidget(id)) {
+            ((ContainerDefinition)definition).createWidget(this, id);
+            Widget child = super.getChild(id);
+            child.initialize();
+            return child;
+        }
+        return super.getChild(id);
+    }
+
+    //TODO: check further: cause the claim in the accompanied comment doesn't seem
+    // to be completely correct
+    
+    // This method is overridden to suppress output of sub-widget sax fragments.
+//    public void generateItemsSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException {
+//        // Do nothing
+//    }
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Union.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinition.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinition.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinition.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,81 @@
+/*
+ * 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.formmodel;
+
+
+/**
+ * The {@link WidgetDefinition} corresponding to a {@link Union} widget.
+ *
+ * @version $Id: UnionDefinition.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class UnionDefinition extends AbstractContainerDefinition {
+    private String caseWidgetId;
+
+    /*
+    public void setDatatype(Datatype datatype) {
+        if (!String.class.isAssignableFrom(datatype.getTypeClass()))
+            throw new RuntimeException("Only datatype string is allowed for this widget at " + getLocation() + ".");
+        super.setDatatype(datatype);
+    }
+
+    public void setDefault(Object value) throws Exception {
+        if (!(value == null || String.class.isAssignableFrom(value.getClass())))
+            throw new Exception("UnionDefinition: Default case must be supplied as a string (" + getLocation() + ")");
+        if (value == null || value.equals("")) {
+            if (isRequired())
+                throw new Exception("UnionWidget: Union is marked required, but no default case was supplied (" + getLocation() + ")");
+            this.defaultValue = "";
+        } else {
+            if (!hasWidget((String)value))
+                throw new Exception("UnionWidget: The default value \"" + value + "\" does not match a union case (" + getLocation() + ")");
+            this.defaultValue = (String)value;
+        }
+    }
+
+    public Object getDefaultValue() {
+        return defaultValue;
+    }
+    */
+    
+    /**
+     * 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 UnionDefinition) {
+    		UnionDefinition other = (UnionDefinition)definition;
+    		this.caseWidgetId = other.caseWidgetId;
+    		
+    	} else {
+    		throw new Exception("Definition to inherit from is not of the right type! (at "+getLocation()+")");
+    	}
+    }
+
+    public void setCaseWidgetId(String id) {
+        checkMutable();
+        caseWidgetId = id;
+    }
+
+    public String getCaseWidgetId() {
+        return caseWidgetId;
+    }
+
+    public Widget createInstance() {
+        Union unionWidget = new Union(this);
+        return unionWidget;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinitionBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinitionBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinitionBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,41 @@
+/*
+ * 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.formmodel;
+
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * Builds {UnionDefinition}s.
+ *
+ * @version $Id: UnionDefinitionBuilder.java 307119 2005-10-07 13:28:45Z sylvain $
+ */
+public final class UnionDefinitionBuilder extends AbstractContainerDefinitionBuilder {
+
+    public WidgetDefinition buildWidgetDefinition(Element element) throws Exception {
+        UnionDefinition definition = new UnionDefinition();
+        super.setupDefinition(element, definition);
+        definition.setCaseWidgetId(DomHelper.getAttribute(element, "case"));
+        setDisplayData(element, definition);
+
+        setupContainer(element,"widgets",definition);
+
+        definition.makeImmutable();
+        return definition;
+    }
+    // TODO: Need to add code somewhere to build a selection list for the case widget.
+}
+

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UnionDefinitionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Upload.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Upload.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Upload.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Upload.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,287 @@
+/*
+ * Copyright 1999-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.cocoon.forms.formmodel;
+
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+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;
+
+import org.apache.cocoon.servlet.multipart.Part;
+import org.apache.cocoon.servlet.multipart.RejectedPart;
+
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.apache.commons.lang.ObjectUtils;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * 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: Upload.java 327208 2005-10-21 15:30:51Z sylvain $
+ */
+public class Upload extends AbstractWidget
+                    implements ValidationErrorAware, ValueChangedListenerEnabled {
+
+    private static final String UPLOAD_EL = "upload";
+    private static final String VALUE_EL = "value";
+    private static final String VALIDATION_MSG_EL = "validation-message";
+
+    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() {
+        return this.uploadDefinition;
+    }
+
+    public WidgetDefinition getDefinition() {
+        return this.uploadDefinition;
+    }
+
+    public Object getValue() {
+        return this.isValid() ? this.part : null;
+    }
+
+    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 + ".");
+        }
+        changed();
+    }
+
+    public void readFromRequest(FormContext formContext) {
+        if (!getCombinedState().isAcceptingInputs()) {
+            return;
+        }
+
+        Object obj = formContext.getRequest().get(getRequestParameterName());
+
+        // If the request object is a Part, keep it
+        if (obj instanceof Part) {
+            Part requestPart = (Part)obj;
+            if (this.part != null) {
+                // Replace the current part
+                this.part.dispose();
+            }
+
+            // Keep the request part
+            requestPart.setDisposeWithRequest(false);
+            this.part = requestPart;
+            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
+        } else if (obj != null || getForm().getSubmitWidget() == this){
+            // Clear the part, if any
+            if (this.part != null) {
+                this.part.dispose();
+                this.part = null;
+            }
+            setValidationError(null);
+            // Ensure we redisplay it
+            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();
+        if (mimeTypes != null) {
+            StringTokenizer tok = new StringTokenizer(mimeTypes, ", ");
+            String contentType = this.part.getMimeType();
+            while(tok.hasMoreTokens()) {
+                if (tok.nextToken().equals(contentType)) {
+                    return true;
+                }
+            }
+            I18nMessage message = new I18nMessage("upload.invalid-type",
+                                                  new String[] {contentType},
+                                                  FormsConstants.I18N_CATALOGUE);
+            setValidationError(new ValidationError(message));
+            return false;
+        }
+
+        // No mime type restriction
+        return true;
+    }
+
+    /**
+     * Check if the part is oversized, and if yes sets the validation error accordingly
+     */
+    private boolean validateOversize() {
+        if (!this.part.isRejected()) {
+            return true; 
+        }
+
+        // Set a validation error indicating the sizes in kbytes (rounded)
+        RejectedPart rjp = (RejectedPart)this.part;
+        int size = (rjp.getContentLength() + 512) / 1024;
+        int maxSize = (rjp.getMaxContentLength() + 512) / 1024;
+        String[] i18nParams = new String[] { String.valueOf(size), String.valueOf(maxSize) };
+        I18nMessage i18nMessage = new I18nMessage("upload.rejected", i18nParams, FormsConstants.I18N_CATALOGUE);
+        setValidationError(new ValidationError(i18nMessage));
+        return false;
+    }
+
+    public boolean validate() {
+        if (!getCombinedState().isValidatingValues()) {
+            this.wasValid = true;
+            return true;
+        }
+
+        if (this.part == null) {
+            if (this.uploadDefinition.isRequired()) {
+                I18nMessage i18nMessage = new I18nMessage("general.field-required", FormsConstants.I18N_CATALOGUE);
+                setValidationError(new ValidationError(i18nMessage));
+            }
+        } else if (validateOversize() && validateMimeType()) {
+            super.validate();
+        }
+
+        this.wasValid = this.validationError == null;
+        return this.wasValid;
+    }
+
+    /**
+     * Returns the validation error, if any. There will always be a validation error in case the
+     * {@link #validate()} method returned false.
+     */
+    public ValidationError getValidationError() {
+        return this.validationError;
+    }
+
+    /**
+     * Set a validation error on this field. This allows fields to be externally marked as invalid by
+     * application logic.
+     *
+     * @param error the validation error
+     */
+    public void setValidationError(ValidationError error) {
+        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);
+        }
+    }
+
+    /**
+     * @return "upload"
+     */
+    public String getXMLElementName() {
+        return UPLOAD_EL;
+    }
+
+    /**
+     * Adds attributes @required, @mime-types
+     */
+    public AttributesImpl getXMLElementAttributes() {
+        AttributesImpl attrs = super.getXMLElementAttributes();
+        attrs.addCDATAAttribute("id", getRequestParameterName());
+        attrs.addCDATAAttribute("required", String.valueOf(this.uploadDefinition.isRequired()));
+        if (this.uploadDefinition.getMimeTypes() != null) {
+            attrs.addCDATAAttribute("mime-types", this.uploadDefinition.getMimeTypes());
+        }
+        return attrs;
+    }
+
+    public void generateItemSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException {
+        if (this.part != null) {
+            String name = (String)this.part.getHeaders().get("filename");
+            contentHandler.startElement(FormsConstants.INSTANCE_NS, VALUE_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUE_EL, XMLUtils.EMPTY_ATTRIBUTES);
+            contentHandler.characters(name.toCharArray(), 0, name.length());
+            contentHandler.endElement(FormsConstants.INSTANCE_NS, VALUE_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUE_EL);
+        }
+
+        // validation message element: only present if the value is not valid
+        if (this.validationError != null) {
+            contentHandler.startElement(FormsConstants.INSTANCE_NS, VALIDATION_MSG_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALIDATION_MSG_EL, XMLUtils.EMPTY_ATTRIBUTES);
+            this.validationError.generateSaxFragment(contentHandler);
+            contentHandler.endElement(FormsConstants.INSTANCE_NS, VALIDATION_MSG_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALIDATION_MSG_EL);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Upload.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,103 @@
+/*
+ * 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.formmodel;
+
+import org.apache.cocoon.forms.event.ValueChangedListener;
+import org.apache.cocoon.forms.event.WidgetEventMulticaster;
+
+/**
+ * The definition of an upload widget.
+ * 
+ * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: UploadDefinition.java 327208 2005-10-21 15:30:51Z sylvain $
+ */
+public class UploadDefinition extends AbstractWidgetDefinition {
+    private ValueChangedListener listener;
+    private boolean required;
+    private String mimeTypes;
+    
+    public UploadDefinition() {
+    	this.mimeTypes = null;
+    	this.required = false;
+    }
+    
+    public UploadDefinition(boolean required, String mimeTypes) {
+        this.required = required;
+        this.mimeTypes = mimeTypes;
+    }
+    
+    /**
+     * 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
+            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;
+            }
+        }
+    }
+    
+    public void setRequired(boolean required) {
+        checkMutable();
+        this.required = required;
+    }
+
+    public Widget createInstance() {
+        Upload upload = new Upload(this);
+        return upload;
+    }
+
+    public boolean isRequired() {
+        return required;
+    }
+    
+    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;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,54 @@
+/*
+ * 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.formmodel;
+
+import java.util.Iterator;
+
+import org.apache.cocoon.forms.event.ValueChangedListener;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * Builds {@link org.apache.cocoon.forms.formmodel.UploadDefinition}s.
+ * 
+ * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: UploadDefinitionBuilder.java 327208 2005-10-21 15:30:51Z sylvain $
+ */
+public final class UploadDefinitionBuilder extends AbstractWidgetDefinitionBuilder {
+
+    public WidgetDefinition buildWidgetDefinition(Element widgetElement) throws Exception {
+        String mimeTypes = DomHelper.getAttribute(widgetElement, "mime-types", null);
+        
+        UploadDefinition uploadDefinition = new UploadDefinition();
+        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));
+        
+        uploadDefinition.addMimeTypes(mimeTypes);
+
+        uploadDefinition.makeImmutable();
+        return uploadDefinition;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/UploadDefinitionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Widget.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Widget.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Widget.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Widget.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,266 @@
+/*
+ * Copyright 1999-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.cocoon.forms.formmodel;
+
+import org.apache.cocoon.forms.FormContext;
+import org.apache.cocoon.forms.validation.WidgetValidator;
+import org.apache.cocoon.forms.event.WidgetEvent;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import java.util.Locale;
+
+/**
+ * Interface to be implemented by Widgets. In CForms, a form consists of a number
+ * of widgets. Each widget:
+ *
+ * <ul>
+ *  <li>has an id, unique within its parent context widget. See {@link #getId()}.</li>
+ *  <li>can have a parent (see {@link #getParent()}.</li>
+ *  <li>can hold a value (which can be any kind of object). See {@link #getValue()}.</li>
+ *  <li>can read its value from a request object (and convert it from a string to its native type).
+ *  See {@link #readFromRequest(FormContext)}.</li>
+ *  <li>can validate itself. See {@link #validate()}.</li>
+ *  <li>can generate an XML representation of itself.</li>
+ * </ul>
+ *
+ * <p>When a request is submitted, first the {@link #readFromRequest(FormContext)} method of all widgets
+ * will be called so that they can read their value(s). Next, the {@link #validate()} method will
+ * be called. Doing this in two steps allows the validation to compare values between widgets.
+ * See also the method {@link Form#process(FormContext)}.</p>
+ *
+ * <p>A Widget is created by calling the createInstance method on the a
+ * {@link WidgetDefinition}. A Widget holds all the data that is specific for
+ * a certain use of the widget (its value, validationerrors, ...), while the
+ * WidgetDefinition holds the data that is static accross all widgets. This
+ * keeps the Widgets small and light to create. This mechanism is similar to
+ * classes and objects in Java.
+ *
+ * @version $Id: Widget.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public interface Widget extends Locatable {
+
+    /**
+     * Widget-Separator used in path-like notations
+     * @see #lookupWidget(String)
+     */
+    char PATH_SEPARATOR = '/';
+
+    /**
+     * Called after widget's environment has been setup,
+     * to allow for any contextual initalization such as
+     * looking up case widgets for union widgets.
+     */
+    void initialize();
+
+    /**
+     * @return  the source location of this widget.
+     */
+    Location getLocation();
+
+    /**
+     * @return the name of this widget.  This should never be <code>null</code>
+     * Top-level container widgets (like 'form') should return <code>""</code>
+     */
+    String getName();
+
+    /**
+     * @return the id of this widget.  This should never be <code>null</code>
+     * Top-level container widgets (like 'form') should return <code>""</code>
+     */
+    String getId();
+
+    /**
+     * @return the parent of this widget. If this widget is the root widget,
+     * this method returns null.
+     */
+    Widget getParent();
+
+    /**
+     * This method is called on a widget when it is added to a container.
+     * You shouldn't call this method unless youre implementing a widget yourself (in
+     * which case it should be called when a widget is added as child of your widget).
+     */
+    void setParent(Widget widget);
+
+    /**
+     * @return the {@link Form} to which this widget belongs. The form is the top-most ancestor
+     * of the widget.
+     */
+    Form getForm();
+
+    /**
+     * Get this widget's definition.
+     *
+     * @return the widget's definition
+     */
+    WidgetDefinition getDefinition();
+    
+    /**
+     * Get the widget's own state. Note that this state is <em>not</em> the one actually considered
+     * for handling requests and producing output. For these matters, the combined state is used.
+     *
+     * @see #getCombinedState()
+     * @return the widget's own state
+     */
+    WidgetState getState();
+
+    /**
+     * Set the widget's own state. This may change its combined state, and those of its
+     * children, if any.
+     *
+     * @param state the new wiget state
+     */
+    void setState(WidgetState state);
+
+    /**
+     * Get the widget's combined state, which is the strictest of its own state and parent state.
+     * This combined state is the one that will be used by the widget to know if request
+     * parameters should be considered and if some output must be produced.
+     *
+     * @see WidgetState#strictest(WidgetState, WidgetState)
+     * @return the combined state
+     */
+    WidgetState getCombinedState();
+
+    /**
+     * @return the name prefixed with the namespace, this name should be unique
+     * accross all widgets on the form.
+     */
+    String getFullName();
+
+    /**
+     * @return the id prefixed with the namespace, this name should be unique
+     * accross all widgets on the form.
+     */
+    String getRequestParameterName();
+
+    /**
+     * @deprecated getWidget got removed, use lookupWidget or getChild instead.
+     * @throws UnsupportedOperationException indicating this method has been
+     * deprecated from the API, and will be removed from future releases.
+     */
+    Widget getWidget(String id);
+
+    /**
+     * Finds a widget relative to this one based on a path-like
+     * string (/-delimted) into the widget-tree structure.
+     * This supports '../' and '/' to point to
+     * @return the found widget or <code>null</code> if allong the traversal
+     *   of the path an invalid section was encountered.
+     */
+    Widget lookupWidget(String path);
+
+    /**
+     * Lets this widget read its data from a request. At this point the Widget
+     * may try to convert the request parameter to its native datatype (if it
+     * is not a string), but it should not yet generate any validation errors.
+     */
+    void readFromRequest(FormContext formContext);
+
+    /**
+     * Validates this widget and returns the outcome. Possible error messages are
+     * remembered by the widget itself and will be part of the XML produced by
+     * this widget in its {@link #generateSaxFragment(ContentHandler, Locale)} method.
+     *
+     * @return <code>true</code> to indicate all validations were ok,
+     *         <code>false</code> otherwise
+     */
+    boolean validate();
+
+    void addValidator(WidgetValidator validator);
+
+    boolean removeValidator(WidgetValidator validator);
+
+    /**
+     * Return the current validation state.
+     * This method delivers the same result as the last call to {@link #validate()}.
+     * The validation process is not started again. If the value of this widget has
+     * changed since the latest call to {@link #validate()}, the result of this method
+     * is out of date.
+     * @return The result of the last call to {@link #validate()}.
+     */
+    boolean isValid();
+
+    /**
+     * Generates an XML representation of this widget. The startDocument and endDocument
+     * SAX events will not be called. It is assumed that the prefix for the CForms namespace
+     * mentioned in Constants.FI_PREFIX is already declared (by the caller or otherwise).
+     */
+    void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException;
+
+    /**
+     * Generates SAX events for the label of this widget. The label will not be wrapped
+     * inside another element.
+     */
+    void generateLabel(ContentHandler contentHandler) throws SAXException;
+
+    /**
+     * Get the value of a widget.
+     * <p>
+     * Not all widgets do have a value (notably {@link ContainerWidget}s,
+     * but this method is provided here as a convenience to ease writing and avoiding casts.
+     *
+     * @return the value of the widget.
+     * @throws UnsupportedOperationException if this widget doesn't have a value.
+     */
+    Object getValue() throws UnsupportedOperationException;
+
+    /**
+     * Sets the value of this widget.
+     * <p>
+     * Not all widgets do have a value (notably {@link ContainerWidget}s,
+     * but this method is provided here as a convenience to ease writing and avoiding casts.
+     *
+     * @param value the new widget's value.
+     * @throws UnsupportedOperationException if this widget doesn't have a value.
+     */
+    void setValue(Object value) throws UnsupportedOperationException;
+
+    /**
+     * @return whether this widget is required to be filled in. As with {@link #getValue()},
+     * for some widgets this may not make sense, those should return false here.
+     */
+    boolean isRequired();
+
+    /**
+     * Broadcast an event previously queued by this widget to its event listeners.
+     */
+    void broadcastEvent(WidgetEvent event);
+
+    /**
+     * Retrieves an attribute on this widget.
+     *
+     * @param name of the attribute to lookup
+     * @return the found attribute or <code>null</code> if none was found with that name.
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Sets an attribute on this widget. This can be used to store custom
+     * data with each widget.
+     */
+    void setAttribute(String name, Object value);
+
+    /**
+     * Removes the named attribute from this widget.
+     *
+     * @param name of the attribute
+     */
+    void removeAttribute(String name);
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/formmodel/Widget.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message