click-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sa...@apache.org
Subject svn commit: r1023477 - in /click/trunk/click/framework/src/org/apache/click/control: Field.java FieldSet.java Form.java
Date Sun, 17 Oct 2010 12:30:11 GMT
Author: sabob
Date: Sun Oct 17 12:30:11 2010
New Revision: 1023477

URL: http://svn.apache.org/viewvc?rev=1023477&view=rev
Log:
added stateful support for Form, FieldSet and Field. CLK-715

Modified:
    click/trunk/click/framework/src/org/apache/click/control/Field.java
    click/trunk/click/framework/src/org/apache/click/control/FieldSet.java
    click/trunk/click/framework/src/org/apache/click/control/Form.java

Modified: click/trunk/click/framework/src/org/apache/click/control/Field.java
URL: http://svn.apache.org/viewvc/click/trunk/click/framework/src/org/apache/click/control/Field.java?rev=1023477&r1=1023476&r2=1023477&view=diff
==============================================================================
--- click/trunk/click/framework/src/org/apache/click/control/Field.java (original)
+++ click/trunk/click/framework/src/org/apache/click/control/Field.java Sun Oct 17 12:30:11
2010
@@ -21,6 +21,7 @@ package org.apache.click.control;
 import org.apache.click.Context;
 import org.apache.click.Control;
 import org.apache.click.Page;
+import org.apache.click.Stateful;
 import org.apache.commons.lang.StringUtils;
 
 import org.apache.click.util.ClickUtils;
@@ -179,7 +180,7 @@ import org.apache.click.util.HtmlStringB
  * </dd>
  * </dl>
  */
-public abstract class Field extends AbstractControl {
+public abstract class Field extends AbstractControl implements Stateful {
 
     // Constants --------------------------------------------------------------
 
@@ -1033,6 +1034,36 @@ public abstract class Field extends Abst
     }
 
     /**
+     * Return the Field state. The following state is returned:
+     * <ul>
+     * <li>{@link #getValue() field value}</li>
+     * </ul>
+     *
+     * @return the Field state
+     */
+    public Object getState() {
+        String state = getValue();
+        if (StringUtils.isEmpty(state)) {
+            return null;
+        }
+        return state;
+    }
+
+    /**
+     * Set the Field state.
+     *
+     * @param state the Field state to set
+     */
+    public void setState(Object state) {
+        if (state == null) {
+            return;
+        }
+
+        String fieldState = (String) state;
+        setValue(fieldState);
+    }
+
+    /**
      * This method processes the page request returning true to continue
      * processing or false otherwise. The Field <tt>onProcess()</tt> method is
      * typically invoked by the Form <tt>onProcess()</tt> method when
@@ -1085,6 +1116,48 @@ public abstract class Field extends Abst
     }
 
     /**
+     * Remove the Field state from the session for the given request context.
+     *
+     * @see #saveState(org.apache.click.Context)
+     * @see #restoreState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    public void removeState(Context context) {
+        ClickUtils.removeState(this, getName(), context);
+    }
+
+    /**
+     * Restore the Field state from the session for the given request context.
+     * <p/>
+     * This method delegates to {@link #setState(java.lang.Object)} to set the
+     * field restored state.
+     *
+     * @see #saveState(org.apache.click.Context)
+     * @see #removeState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    public void restoreState(Context context) {
+        ClickUtils.restoreState(this, getName(), context);
+    }
+
+    /**
+     * Save the Field state to the session for the given request context.
+     * <p/>
+     * * This method delegates to {@link #getState()} to retrieve the field state
+     * to save.
+     *
+     * @see #restoreState(org.apache.click.Context)
+     * @see #removeState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    public void saveState(Context context) {
+        ClickUtils.saveState(this, getName(), context);
+    }
+
+    /**
      * The validate method is invoked by <tt>onProcess()</tt> to validate
      * the request submission. Field subclasses should override this method
      * to implement request validation logic.

Modified: click/trunk/click/framework/src/org/apache/click/control/FieldSet.java
URL: http://svn.apache.org/viewvc/click/trunk/click/framework/src/org/apache/click/control/FieldSet.java?rev=1023477&r1=1023476&r2=1023477&view=diff
==============================================================================
--- click/trunk/click/framework/src/org/apache/click/control/FieldSet.java (original)
+++ click/trunk/click/framework/src/org/apache/click/control/FieldSet.java Sun Oct 17 12:30:11
2010
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.click.Context;
 import org.apache.click.Control;
 import org.apache.click.util.ClickUtils;
 import org.apache.click.util.ContainerUtils;
@@ -879,6 +880,55 @@ public class FieldSet extends Field impl
     }
 
     /**
+     * Return the FieldSet state. The state will include all the input Field
+     * values and other FieldSets contained in this FieldSet or child containers.
+     *
+     * @return the state of input Fields and FieldSets contained in this FieldSet
+     */
+    @Override
+    public Object getState() {
+        List<Field> fields = new ArrayList<Field>();
+        addStatefulFields(this, fields);
+        Map<String, Object> stateMap = new HashMap<String, Object>();
+        for(Field field : fields) {
+            Object state = field.getState();
+            if(state != null) {
+                stateMap.put(field.getName(), state);
+            }
+        }
+
+        if (stateMap.isEmpty()) {
+            return null;
+        }
+        return stateMap;
+    }
+
+    /**
+     * Set the FieldSet state. The state will be applied to all the input Fields
+     * and FieldSets contained in the FieldSet or child containers.
+     *
+     * @param state the FieldSet state to set
+     */
+    @Override
+    public void setState(Object state) {
+        if (state == null) {
+            return;
+        }
+
+        Map stateMap = (Map) state;
+        List<Field> fields = new ArrayList<Field>();
+        addStatefulFields(this, fields);
+
+        for(Field field : fields) {
+            String fieldName = field.getName();
+            if (stateMap.containsKey(fieldName)) {
+                Object fieldState = stateMap.get(fieldName);
+                field.setState(fieldState);
+            }
+        }
+    }
+
+    /**
      * Render the HTML representation of the FieldSet.
      * <p/>
      * The size of buffer is determined by {@link #getControlSizeEst()}.
@@ -936,6 +986,50 @@ public class FieldSet extends Field impl
     }
 
     /**
+     * Remove the FieldSet state from the session for the given request context.
+     *
+     * @see #saveState(org.apache.click.Context)
+     * @see #restoreState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    @Override
+    public void removeState(Context context) {
+        ClickUtils.removeState(this, getName(), context);
+    }
+
+    /**
+     * Restore the FieldSet state from the session for the given request context.
+     * <p/>
+     * This method delegates to {@link #setState(java.lang.Object)} to set the
+     * field restored state.
+     *
+     * @see #saveState(org.apache.click.Context)
+     * @see #removeState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    @Override
+    public void restoreState(Context context) {
+        ClickUtils.restoreState(this, getName(), context);
+    }
+
+    /**
+     * Save the FieldSet state to the session for the given request context.
+     * <p/>
+     * * This method delegates to {@link #getState()} to retrieve the field state
+     * to save.
+     *
+     * @see #restoreState(org.apache.click.Context)
+     * @see #removeState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    public void saveState(Context context) {
+        ClickUtils.saveState(this, getName(), context);
+    }
+
+    /**
      * Returns the HTML representation of the FieldSet.
      * <p/>
      * The rendering of the FieldSet is delegated to
@@ -1253,4 +1347,27 @@ public class FieldSet extends Field impl
             return ((Field) control).isHidden();
         }
     }
+
+    /**
+     * Add fields for the given Container to the specified field list,
+     * recursively including any Fields contained in child containers.
+     *
+     * @param container the container to obtain the fields from
+     * @param fields the list of contained fields
+     */
+    private void addStatefulFields(final Container container, final List<Field> fields)
{
+        for (Control control : container.getControls()) {
+            if (control instanceof Label || control instanceof Button) {
+                // Skip buttons and labels
+                continue;
+            }
+
+            if (control instanceof Field) {
+                fields.add((Field) control);
+            } else if (control instanceof Container) {
+                Container childContainer = (Container) control;
+                addStatefulFields(childContainer, fields);
+            }
+        }
+    }
 }

Modified: click/trunk/click/framework/src/org/apache/click/control/Form.java
URL: http://svn.apache.org/viewvc/click/trunk/click/framework/src/org/apache/click/control/Form.java?rev=1023477&r1=1023476&r2=1023477&view=diff
==============================================================================
--- click/trunk/click/framework/src/org/apache/click/control/Form.java (original)
+++ click/trunk/click/framework/src/org/apache/click/control/Form.java Sun Oct 17 12:30:11
2010
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRes
 import org.apache.click.Context;
 import org.apache.click.Control;
 import org.apache.click.Page;
+import org.apache.click.Stateful;
 import org.apache.click.element.CssImport;
 import org.apache.click.element.Element;
 import org.apache.click.element.JsImport;
@@ -504,7 +505,7 @@ import org.apache.commons.lang.StringUti
  * @see Field
  * @see Submit
  */
-public class Form extends AbstractContainer {
+public class Form extends AbstractContainer implements Stateful {
 
     // Constants --------------------------------------------------------------
 
@@ -926,6 +927,8 @@ public class Form extends AbstractContai
      * the form
      * @return the new control that replaced the current control
      *
+     * @deprecated this method was used for stateful pages, which have been deprecated
+     *
      * @throws IllegalArgumentException if the currentControl or newControl is
      * null
      * @throws IllegalStateException if the currentControl is not contained in
@@ -1330,6 +1333,7 @@ public class Form extends AbstractContai
         }
         this.name = name;
 
+        // TODO: Remove with stateful pages
         HiddenField bypassValidationField = (HiddenField) getField(BYPASS_VALIDATION);
         if (bypassValidationField == null) {
             // Create a hidden field which name and value cannot be change
@@ -1338,10 +1342,11 @@ public class Form extends AbstractContai
             insertIndexOffset++;
         }
 
+        // TODO: Remove with stateful pages
         HiddenField nameField = (HiddenField) getField(FORM_NAME);
         if (nameField == null) {
-            // Create a hidden field which name cannot be changed
-            nameField = new NonbindableHiddenField(FORM_NAME, String.class);
+            // Create a hidden field that won't be processed and name cannot change
+            nameField = new NonProcessedHiddenField(FORM_NAME, String.class);
             add(nameField);
             insertIndexOffset++;
         }
@@ -1902,6 +1907,53 @@ public class Form extends AbstractContai
     }
 
     /**
+     * Return the form state. The state will include all the input Field values
+     * and FieldSets contained in the Form or child containers.
+     *
+     * @return the state of input Fields and FieldSets contained in the form
+     */
+    public Object getState() {
+        List<Field> fields = new ArrayList<Field>();
+        addStatefulFields(this, fields);
+        Map<String, Object> stateMap = new HashMap<String, Object>();
+        for(Field field : fields) {
+            Object state = field.getState();
+            if(state != null) {
+                stateMap.put(field.getName(), state);
+            }
+        }
+
+        if (stateMap.isEmpty()) {
+            return null;
+        }
+        return stateMap;
+    }
+
+    /**
+     * Set the Form state. The state will be applied to all the input Fields
+     * and FieldSets contained in the Form or child containers.
+     *
+     * @param state the Form state to set
+     */
+    public void setState(Object state) {
+        if (state == null) {
+            return;
+        }
+
+        Map stateMap = (Map) state;
+        List<Field> fields = new ArrayList<Field>();
+        addStatefulFields(this, fields);
+
+        for(Field field : fields) {
+            String fieldName = field.getName();
+            if (stateMap.containsKey(fieldName)) {
+                Object fieldState = stateMap.get(fieldName);
+                field.setState(fieldState);
+            }
+        }
+    }
+
+    /**
      * Process the Form and its child controls only if the Form was submitted
      * by the user.
      * <p/>
@@ -2170,6 +2222,48 @@ public class Form extends AbstractContai
     }
 
     /**
+     * Remove the Form state from the session for the given request context.
+     *
+     * @see #saveState(org.apache.click.Context)
+     * @see #restoreState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    public void removeState(Context context) {
+        ClickUtils.removeState(this, getName(), context);
+    }
+
+    /**
+     * Restore the Form state from the session for the given request context.
+     * <p/>
+     * This method delegates to {@link #setState(java.lang.Object)} to set the
+     * form restored state.
+     *
+     * @see #saveState(org.apache.click.Context)
+     * @see #removeState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    public void restoreState(Context context) {
+        ClickUtils.restoreState(this, getName(), context);
+    }
+
+    /**
+     * Save the Form state to the session for the given request context.
+     * <p/>
+     * * This method delegates to {@link #getState()} to retrieve the form state
+     * to save.
+     *
+     * @see #restoreState(org.apache.click.Context)
+     * @see #removeState(org.apache.click.Context)
+     *
+     * @param context the request context
+     */
+    public void saveState(Context context) {
+        ClickUtils.saveState(this, getName(), context);
+    }
+
+    /**
      * Return the rendered opening form tag and all the forms hidden fields.
      *
      * @return the rendered form start tag and the forms hidden fields
@@ -2325,7 +2419,7 @@ public class Form extends AbstractContai
         // CLK-267: check against adding a duplicate field
         HiddenField field = (HiddenField) getField(submitTokenName);
         if (field == null) {
-            field = new NonbindableHiddenField(submitTokenName, Long.class);
+            field = new NonProcessedHiddenField(submitTokenName, Long.class);
             add(field);
             insertIndexOffset++;
         }
@@ -2983,6 +3077,32 @@ public class Form extends AbstractContai
 
     // Private Methods --------------------------------------------------------
 
+         /**
+     * Add fields for the given Container to the specified field list,
+     * recursively including any Fields contained in child containers.
+     *
+     * @param container the container to obtain the fields from
+     * @param fields the list of contained fields
+     */
+    private void addStatefulFields(final Container container, final List<Field> fields)
{
+        for (Control control : container.getControls()) {
+            if (control instanceof Label
+                || control instanceof Button
+                || control instanceof NonProcessedHiddenField
+                ) {
+                // Skip buttons and labels and NonProcessedHiddenFields
+                continue;
+            }
+
+            if (control instanceof Field) {
+                fields.add((Field) control);
+            } else if (control instanceof Container) {
+                Container childContainer = (Container) control;
+                addStatefulFields(childContainer, fields);
+            }
+        }
+    }
+
     /**
      * Return true if the control is hidden, false otherwise.
      *
@@ -3001,9 +3121,10 @@ public class Form extends AbstractContai
     // Inner Classes ----------------------------------------------------------
 
     /**
-     * Provides a HiddenField which does not bind to incoming values.
+     * Provides a HiddenField which does not get processed or bind to its
+     * incoming value. In addition the field name cannot be changed once set.
      */
-    private static class NonbindableHiddenField extends HiddenField {
+    private static class NonProcessedHiddenField extends HiddenField {
 
         private static final long serialVersionUID = 1L;
 
@@ -3013,11 +3134,21 @@ public class Form extends AbstractContai
          * @param name the field name
          * @param valueClass the Class of the value Object
          */
-        public NonbindableHiddenField(String name, Class<?> valueClass) {
+        public NonProcessedHiddenField(String name, Class<?> valueClass) {
             super(name, valueClass);
         }
 
         /**
+         * Create a field with the given name and value.
+         *
+         * @param name the field name
+         * @param value the value of the field
+         */
+        public NonProcessedHiddenField(String name, Object value) {
+            super(name, value);
+        }
+
+        /**
          * This method is overridden to not change the field name once it is set.
          *
          * @param name the name of the field
@@ -3031,10 +3162,11 @@ public class Form extends AbstractContai
         }
 
         /**
-         * Overridden to not bind to request value.
+         * Overridden to not process the field or bind to its request value.
          */
         @Override
-        public void bindRequestValue() {
+        public boolean onProcess() {
+            return true;
         }
     }
 
@@ -3042,7 +3174,7 @@ public class Form extends AbstractContai
      * Provides a HiddenField which name and value cannot be changed, once it
      * is set.
      */
-    private static class ImmutableHiddenField extends HiddenField {
+    private static class ImmutableHiddenField extends NonProcessedHiddenField {
 
         private static final long serialVersionUID = 1L;
 
@@ -3057,19 +3189,6 @@ public class Form extends AbstractContai
         }
 
         /**
-         * This method is overridden to not change the field name once it is set.
-         *
-         * @param name the name of the field
-         */
-        @Override
-        public void setName(String name) {
-            if (this.name != null) {
-                return;
-            }
-            super.setName(name);
-        }
-
-        /**
          * This method is overridden to not change the field value once it is set.
          *
          * @param value the field value



Mime
View raw message