You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/09/17 04:16:19 UTC

svn commit: r576236 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry/corelib/components/ main/java/org/apache/tapestry/internal/beaneditor/ site/apt/guide/ test/app1/WEB-INF/ test/java/org/apache/tapestry/integration/ tes...

Author: hlship
Date: Sun Sep 16 19:16:18 2007
New Revision: 576236

URL: http://svn.apache.org/viewvc?rev=576236&view=rev
Log:
TAPESTRY-1742: Support removal and reordering of BeanModel properties inside Grid and BeanEditForm components

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/BeanEditRemoveReorder.html
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/beaneditform.apt
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java?rev=576236&r1=576235&r2=576236&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java Sun Sep 16 19:16:18 2007
@@ -24,6 +24,7 @@
 import org.apache.tapestry.annotations.Parameter;
 import org.apache.tapestry.annotations.SupportsInformalParameters;
 import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.internal.beaneditor.BeanModelUtils;
 import org.apache.tapestry.ioc.internal.util.TapestryException;
 import org.apache.tapestry.services.BeanModelSource;
 import org.apache.tapestry.services.ComponentDefaultProvider;
@@ -32,9 +33,9 @@
  * A component that creates an entire form editing the properties of a particular bean. Inspired by
  * <a href="http://www.trailsframework.org/">Trails</a> and <a
  * href="http://beanform.sourceforge.net/">BeanForm</a> (both for Tapestry 4). Generates a simple
- * UI for editing the properties of a JavaBean, with the flavor of UI for each property (text
- * field, checkbox, drop down list) determined from the property type, and the order and validation
- * for the properties determined from annotations on the property's getter and setter methods.
+ * UI for editing the properties of a JavaBean, with the flavor of UI for each property (text field,
+ * checkbox, drop down list) determined from the property type, and the order and validation for the
+ * properties determined from annotations on the property's getter and setter methods.
  * <p>
  * You may add &lt;t:parameter&gt;s to the component; when the name matches (case insensitive) the
  * name of a property, then the corresponding Block is renderered, rather than any of the built in
@@ -64,6 +65,21 @@
     @Parameter(required = true)
     private Object _object;
 
+    /**
+     * A comma-separated list of property names to be removed from the {@link BeanModel}. The names
+     * are case-insensitive.
+     */
+    @Parameter(defaultPrefix="literal")
+    private String _remove;
+
+    /**
+     * A comma-separated list of property names indicating the order in which the properties should
+     * be presented. The names are case insensitive. Any properties not indicated in the list will
+     * be appended to the end of the display order.
+     */
+    @Parameter(defaultPrefix="literal")
+    private String _reorder;
+
     /** If true, the default, then the embedded Form component will use client-side validation. */
     @SuppressWarnings("unused")
     @Parameter
@@ -140,6 +156,12 @@
 
             _model = _modelSource.create(beanType, true, _resources.getContainerResources());
         }
+        
+        if (_remove != null)
+            BeanModelUtils.remove(_model, _remove);
+        
+        if (_reorder != null)
+            BeanModelUtils.reorder(_model, _reorder);
 
         // Abort the form's prepare event, as we've already sent a prepare on its behalf.
         return true;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java?rev=576236&r1=576235&r2=576236&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java Sun Sep 16 19:16:18 2007
@@ -29,6 +29,7 @@
 import org.apache.tapestry.internal.services.CoercingPropertyConduitWrapper;
 import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
 import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.services.PropertyConduitSource;
 
@@ -199,4 +200,25 @@
         return this;
     }
 
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder("BeanModel[");
+        builder.append(ClassFabUtils.toJavaClassName(_beanType));
+
+        builder.append(" properties:");
+        String sep = "";
+
+        for (String name : _propertyNames)
+        {
+            builder.append(sep);
+            builder.append(name);
+
+            sep = ", ";
+        }
+
+        builder.append("]");
+
+        return builder.toString();
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java?rev=576236&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java Sun Sep 16 19:16:18 2007
@@ -0,0 +1,58 @@
+// Copyright 2007 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.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.beaneditor.BeanModel;
+
+/**
+ * Utilities used in a few places to modify an existing {@link BeanModel}.
+ */
+public final class BeanModelUtils
+{
+    /**
+     * Removes properties from the bean model.
+     * 
+     * @param model
+     * @param propertyNames
+     *            comma-separated list of property names
+     * @see BeanModel#remove(String...)
+     */
+    public static void remove(BeanModel model, String propertyNames)
+    {
+        model.remove(split(propertyNames));
+    }
+
+    /**
+     * Reorders properties within the bean model.
+     * 
+     * @param model
+     * @param propertyNames
+     *            comma-separated list of property names
+     * @see BeanModel#reorder(String...)
+     */
+    public static void reorder(BeanModel model, String propertyNames)
+    {
+        model.reorder(split(propertyNames));
+    }
+
+    static String[] split(String propertyNames)
+    {
+        String trimmed = propertyNames.trim();
+
+        if (trimmed.length() == 0) return new String[0];
+
+        return trimmed.split("\\s*,\\s*");
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/beaneditform.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/beaneditform.apt?rev=576236&r1=576235&r2=576236&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/beaneditform.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/beaneditform.apt Sun Sep 16 19:16:18 2007
@@ -94,6 +94,23 @@
 
   The other fields will render normally (using the built-in editors).
   
+Customizing the BeanModel
+
+  You may want to customize the BeanModel further, to remove from the form properties that should not be editable by the user,
+  and to change the order in which properties are presented within the form.
+  
+  The BeanEditForm component has two parameters for this purpose:
+  
+  * remove: A comma separated list of property names to remove from the model.
+  
+  * reorder: A comma separated list of property names indicating the desired order.
+  
+  []
+  
+  If a model has more properties that are listed in the reorder parameter, then the additional properties will be ordered at the end of the form.
+  
+  Note that these parameters <modify> the BeanModel.
+    
 Providing the BeanModel
 
   The BeanEditForm component operates in terms of a {{{../../apidocs/org/apache/tapestry/beaneditor/BeanModel.html}BeanModel}}, which describes
@@ -101,8 +118,11 @@
   
   Normally, the BeanEditForm automatically creates the BeanModel as needed, based on the type of object bound to its object parameter.
   
-  Alternately, the BeanModel can be supplied as the model parameter. This can be useful if certain properties should be omitted, or the order
-  of the properties needs to be changed.  The model can be created when the page is first loaded:
+  Alternately, the BeanModel can be supplied as the model parameter. This can be useful in situations where the remove and reorder parameters
+  are insufficient.  For example, if the the type of the property being edited is an interface type, it may be useful to provide
+  an explicit BeanModel around an underlying implementation class.
+  
+  The model can be created when the page is first loaded:
   
 +---+
 public class MyPage

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/BeanEditRemoveReorder.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/BeanEditRemoveReorder.html?rev=576236&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/BeanEditRemoveReorder.html (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/BeanEditRemoveReorder.html Sun Sep 16 19:16:18 2007
@@ -0,0 +1,14 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <h1>${pageTitle}</h1>
+
+  <form t:id="registrationData" submitlabel="Register" remove="birthYear" reorder="lastname,firstname">
+
+    <t:parameter name="firstName">
+      <t:label for="firstName"/>
+      <input t:type="TextField" t:id="firstName" value="registrationData.firstName" size="40"/>
+      (First Name is Required) </t:parameter>
+
+  </form>
+
+  <p>[<a t:type="ActionLink" t:id="clear">Clear Data</a>]</p>
+</t:border>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html?rev=576236&r1=576235&r2=576236&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html Sun Sep 16 19:16:18 2007
@@ -1,4 +1,5 @@
-<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<html t:type="Border"
+  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
 
   <h1>Tapestry 5 Integration Application 1</h1>
 
@@ -16,127 +17,226 @@
             <a t:type="PageLink" page="Countdown">Countdown Page</a>
           </li>
           <li>
-            <a t:type="PageLink" page="ParameterConflict">Template Overriden by Class Page</a>
+            <a t:type="PageLink" page="ParameterConflict">
+              Template Overriden by Class Page
+            </a>
           </li>
           <li>
-            <a t:type="PageLink" page="EnvironmentalDemo">Environmental Annotation Useage</a>
+            <a t:type="PageLink" page="EnvironmentalDemo">
+              Environmental Annotation Useage
+            </a>
           </li>
           <li>
             <a t:type="PageLink" page="expansion">Expansion Page</a>
           </li>
           <li>
-            <a href="BadTemplate">BadTemplate Page</a> -- More exception reporting </li>
+            <a href="BadTemplate">BadTemplate Page</a>
+            -- More exception reporting
+          </li>
           <li>
-            <a t:type="PageLink" page="ActionPage">Action Page</a> -- tests fixture for ActionLink
-            component </li>
+            <a t:type="PageLink" page="ActionPage">Action Page</a>
+            -- tests fixture for ActionLink component
+          </li>
           <li>
-            <a t:type="PageLink" page="InstanceMixin">InstanceMixin</a> -- Mixin added to particular
-            component instance </li>
+            <a t:type="PageLink" page="InstanceMixin">InstanceMixin</a>
+            -- Mixin added to particular component instance
+          </li>
           <li>
-            <a t:type="PageLink" page="RenderPhaseOrder">RenderPhaseOrder</a> -- Order of operations
-            when invoking render phase methods </li>
-          <li><a t:type="PageLink" page="SimpleForm">SimpleForm</a> -- first pass at writing Form
-            and TextField components </li>
+            <a t:type="PageLink" page="RenderPhaseOrder">
+              RenderPhaseOrder
+            </a>
+            -- Order of operations when invoking render phase methods
+          </li>
           <li>
-            <a t:type="PageLink" page="NumberSelect">NumberSelect</a> -- passivate/activate page
-            context demo </li>
+            <a t:type="PageLink" page="SimpleForm">SimpleForm</a>
+            -- first pass at writing Form and TextField components
+          </li>
           <li>
-            <a t:type="PageLink" page="Localization">Localization</a> -- accessing localized
-            messages from the component catalog </li>
+            <a t:type="PageLink" page="NumberSelect">NumberSelect</a>
+            -- passivate/activate page context demo
+          </li>
           <li>
-            <a t:type="PageLink" page="AssetDemo">AssetDemo</a> -- declaring an using Assets </li>
+            <a t:type="PageLink" page="Localization">Localization</a>
+            -- accessing localized messages from the component catalog
+          </li>
           <li>
-            <a t:type="PageLink" page="ExpansionSubclass">ExpansionSubclass</a> -- components can
-            inherit templates from base classes </li>
+            <a t:type="PageLink" page="AssetDemo">AssetDemo</a>
+            -- declaring an using Assets
+          </li>
           <li>
-            <a href="InjectComponentMismatch">InjectComponentMismatch</a> -- check error reporting
-            when @InjectComponent doesn't match the actual field type </li>
+            <a t:type="PageLink" page="ExpansionSubclass">
+              ExpansionSubclass
+            </a>
+            -- components can inherit templates from base classes
+          </li>
+          <li>
+            <a href="InjectComponentMismatch">
+              InjectComponentMismatch
+            </a>
+            -- check error reporting when @InjectComponent doesn't match
+            the actual field type
+          </li>
 
           <li>
-            <a t:type="PageLink" page="ParameterDefault">ParameterDefault</a> -- defaulter methods
-            for component parameters </li>
+            <a t:type="PageLink" page="ParameterDefault">
+              ParameterDefault
+            </a>
+            -- defaulter methods for component parameters
+          </li>
           <li>
-            <a t:type="PageLink" page="ValidForm">ValidForm</a> -- server-side input validation</li>
+            <a t:type="PageLink" page="ValidForm">ValidForm</a>
+            -- server-side input validation
+          </li>
           <li>
-            <a t:type="PageLink" page="PasswordFieldDemo">PasswordFieldDemo</a> -- test for the
-            PasswordField component </li>
+            <a t:type="PageLink" page="PasswordFieldDemo">
+              PasswordFieldDemo
+            </a>
+            -- test for the PasswordField component
+          </li>
           <li>
-            <a t:type="PageLink" page="RenderComponentDemo">RenderComponentDemo</a> -- components
-            that "nominate" other components to render </li>
+            <a t:type="PageLink" page="RenderComponentDemo">
+              RenderComponentDemo
+            </a>
+            -- components that "nominate" other components to render
+          </li>
           <li>
-            <a t:type="PageLink" page="BlockDemo">BlockDemo</a> -- use of blocks to control
-            rendering </li>
+            <a t:type="PageLink" page="BlockDemo">BlockDemo</a>
+            -- use of blocks to control rendering
+          </li>
           <li>
-            <a t:type="PageLink" page="ToDoListVolatile">ToDo List (Volatile)</a> -- Loops and
-            Submit inside Form, volatile mode </li>
+            <a t:type="PageLink" page="ToDoListVolatile">
+              ToDo List (Volatile)
+            </a>
+            -- Loops and Submit inside Form, volatile mode
+          </li>
         </ul>
       </td>
       <td>
         <ul>
 
           <li>
-            <a t:type="PageLink" page="ToDoList">ToDo List</a> -- Loops and Submit inside Form using
-            a primary key encoder </li>
+            <a t:type="PageLink" page="ToDoList">ToDo List</a>
+            -- Loops and Submit inside Form using a primary key encoder
+          </li>
           <li>
-            <a t:type="PageLink" page="FlashDemo">FlashDemo</a> -- demonstrate "flash" persistence </li>
+            <a t:type="PageLink" page="FlashDemo">FlashDemo</a>
+            -- demonstrate "flash" persistence
+          </li>
           <li>
-            <a t:type="PageLink" page="beaneditordemo">BeanEditor Demo</a> -- demonstrate the
-            BeanEditor mega-component </li>
+            <a t:type="PageLink" page="beaneditordemo">
+              BeanEditor Demo
+            </a>
+            -- demonstrate the BeanEditor mega-component
+          </li>
           <li>
-            <a t:type="PageLink" page="pageloadeddemo">PageLoaded Demo</a> -- shows that page
-            lifecycle methods are invoked </li>
+            <a t:type="PageLink" page="pageloadeddemo">
+              PageLoaded Demo
+            </a>
+            -- shows that page lifecycle methods are invoked
+          </li>
           <li>
-            <a t:type="PageLink" page="griddemo">Grid Demo</a> -- default Grid component </li>
+            <a t:type="PageLink" page="griddemo">Grid Demo</a>
+            -- default Grid component
+          </li>
           <li>
-            <a t:type="PageLink" page="nullgrid">Null Grid</a> -- handling of null source for Grid </li>
+            <a t:type="PageLink" page="nullgrid">Null Grid</a>
+            -- handling of null source for Grid
+          </li>
           <li>
-            <a t:type="PageLink" page="gridenumdemo">Grid Enum Demo</a> -- handling of enum types in
-            the Grid </li>
+            <a t:type="PageLink" page="gridenumdemo">Grid Enum Demo</a>
+            -- handling of enum types in the Grid
+          </li>
+          <li>
+            <a t:type="PageLink" page="protected">Protected Page</a>
+            -- Demonstrate result of non-void return from a page's
+            activate method.
+          </li>
           <li>
-            <a t:type="PageLink" page="protected">Protected Page</a> -- Demonstrate result of
-            non-void return from a page's activate method. </li>
+            <a t:type="PageLink" page="kicker">Kicker</a>
+            -- demos complex page and component context in links
+          </li>
           <li>
-            <a t:type="PageLink" page="kicker">Kicker</a> -- demos complex page and component
-            context in links </li>
+            <a t:type="PageLink" page="simpletrackgriddemo">
+              SimpleTrack Grid Demo
+            </a>
+            -- customizing the model for a Grid around an interface
+          </li>
           <li>
-            <a t:type="PageLink" page="simpletrackgriddemo">SimpleTrack Grid Demo</a> -- customizing
-            the model for a Grid around an interface </li>
+            <a t:type="PageLink" page="pagelinkcontext">
+              PageLink Context Demo
+            </a>
+            -- passing explicit context in a page render link
+          </li>
           <li>
-            <a t:type="PageLink" page="pagelinkcontext">PageLink Context Demo</a> -- passing
-            explicit context in a page render link </li>
+            <a t:type="pagelink" page="ValidBeanEditorDemo">
+              Client Validation Demo
+            </a>
+            --BeanEditor with validation enabled
+          </li>
           <li>
-            <a t:type="pagelink" page="ValidBeanEditorDemo">Client Validation Demo</a> --BeanEditor
-            with validation enabled </li>
+            <a href="recursivedemo">Recursive Demo</a>
+            -- check for handling of recursive components
+          </li>
           <li>
-            <a href="recursivedemo">Recursive Demo</a> -- check for handling of recursive components </li>
+            <t:pagelink page="renderabledemo">
+              Renderable Demo
+            </t:pagelink>
+            -- Shows that render phase methods can return a Renderable
+            object
+          </li>
           <li>
-            <t:pagelink page="renderabledemo">Renderable Demo</t:pagelink> -- Shows that render
-            phase methods can return a Renderable object </li>
+            <t:pagelink page="eventhandlerdemo" context="'clear'">
+              EventHandler Demo
+            </t:pagelink>
+            -- Tests for event handling method order and matching
+          </li>
           <li>
-            <t:pagelink page="eventhandlerdemo" context="'clear'">EventHandler Demo</t:pagelink> --
-            Tests for event handling method order and matching </li>
+            <t:pagelink page="inheritedbindingsdemo">
+              Inherited Bindings Demo
+            </t:pagelink>
+            -- Tests for components that inherit bindings from
+            containing components
+          </li>
           <li>
-            <t:pagelink page="inheritedbindingsdemo">Inherited Bindings Demo</t:pagelink> -- Tests
-            for components that inherit bindings from containing components </li>
+            <t:pagelink page="ClientPersistenceDemo">
+              Client Persistence Demo
+            </t:pagelink>
+            -- component field values persisted on the client side
+          </li>
           <li>
-            <t:pagelink page="ClientPersistenceDemo">Client Persistence Demo</t:pagelink> --
-            component field values persisted on the client side </li>
+            <t:pagelink page="attributeExpansionsDemo">
+              Attribute Expansions Demo
+            </t:pagelink>
+            -- use expansions inside attributes of ordinary elements
+          </li>
           <li>
-            <t:pagelink page="attributeExpansionsDemo">Attribute Expansions Demo</t:pagelink> -- use
-            expansions inside attributes of ordinary elements </li>
+            <t:pagelink page="PaletteDemo">Palette Demo</t:pagelink>
+            -- multiple selection component
+          </li>
           <li>
-            <t:pagelink page="PaletteDemo">Palette Demo</t:pagelink> -- multiple selection component </li>
+            <t:pagelink page="ReturnTypes">Return Types</t:pagelink>
+            -- Tests various event handler return types
+          </li>
           <li>
-            <t:pagelink page="ReturnTypes">Return Types</t:pagelink> -- Tests various event handler
-            return types </li>
+            <t:pagelink page="FormEncodingType">
+              Form Encoding Type
+            </t:pagelink>
+            -- Test ability to set an encoding type for a Form
+          </li>
           <li>
-            <t:pagelink page="FormEncodingType">Form Encoding Type</t:pagelink> -- Test ability to
-            set an encoding type for a Form </li>
+            <t:pagelink page="RadioDemo">RadioDemo</t:pagelink>
+            -- Use of the RadioGroup and Radio components.
+          </li>
           <li>
-            <t:pagelink page="RadioDemo">RadioDemo</t:pagelink> -- Use of the RadioGroup and Radio
-            components. </li>
+            <t:pagelink page="RegexpDemo">Regexp Demo</t:pagelink>
+            -- Use of the Regexp validator
+          </li>
           <li>
-            <t:pagelink page="RegexpDemo">Regexp Demo</t:pagelink> -- Use of the Regexp validator
+            <t:pagelink page="BeanEditRemoveReorder">
+              BeanEdit Remove/Reorder
+            </t:pagelink>
+            -- Use of the remove and reorder parameters with
+            BeanEditForm
           </li>
         </ul>
       </td>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=576236&r1=576235&r2=576236&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Sun Sep 16 19:16:18 2007
@@ -599,6 +599,24 @@
     }
 
     @Test
+    public void bean_editor_property_reorder_remove()
+    {
+        open(BASE_URL);
+        clickAndWait("link=BeanEdit Remove/Reorder");
+        clickAndWait("link=Clear Data");
+
+        // Looks like a bug in Selenium; we can see //label[1] but not //label[2].
+        // assertTextSeries("//label[%d]", 1, "Last Name", "First Name", "Sex", "U.S. Citizen");
+
+        type("firstName", "Howard");
+        type("lastName", "Lewis Ship");
+
+        clickAndWait("//input[@type=\'submit\']");
+
+        assertTextPresent("[Howard]", "[Lewis Ship]", "[0]", "[MAIL]", "[false]");
+    }
+
+    @Test
     public void pageloaded_lifecycle_method_invoked()
     {
         open(BASE_URL);

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java?rev=576236&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java Sun Sep 16 19:16:18 2007
@@ -0,0 +1,32 @@
+// Copyright 2007 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.tapestry.integration.app1.pages;
+
+public class BeanEditRemoveReorder extends BeanEditorDemo
+{
+
+    @Override
+    public boolean getClientValidation()
+    {
+        return true;
+    }
+
+    @Override
+    public String getPageTitle()
+    {
+        return "BeanEditForm: Remove and Reorder";
+    }
+
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java?rev=576236&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java Sun Sep 16 19:16:18 2007
@@ -0,0 +1,69 @@
+// Copyright 2007 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.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class BeanModelUtilsTest extends InternalBaseTestCase
+{
+    @Test(dataProvider = "split_inputs")
+    public void split(String propertyNames, String[] expected)
+    {
+        assertEquals(BeanModelUtils.split(propertyNames), expected);
+    }
+
+    private Object[] build(String propertyNames, String... expected)
+    {
+        return new Object[]
+        { propertyNames, expected };
+    }
+
+    @DataProvider(name = "split_inputs")
+    public Object[][] split_inputs()
+    {
+        return new Object[][]
+        { build("fred", "fred"), build("fred,barney", "fred", "barney"),
+                build(" fred, barney, wilma, betty ", "fred", "barney", "wilma", "betty"),
+                new Object[]
+                { "   ", new String[0] } };
+    }
+
+    @Test
+    public void remove()
+    {
+        BeanModel model = mockBeanModel();
+
+        expect(model.remove("fred", "barney")).andReturn(model);
+
+        replay();
+
+        BeanModelUtils.remove(model, "fred,barney");
+    }
+
+    @Test
+    public void reorder()
+    {
+        BeanModel model = mockBeanModel();
+
+        expect(model.reorder("fred", "barney")).andReturn(model);
+
+        replay();
+
+        BeanModelUtils.reorder(model, "fred,barney");
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java?rev=576236&r1=576235&r2=576236&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java Sun Sep 16 19:16:18 2007
@@ -66,6 +66,10 @@
 
         assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
 
+        assertEquals(
+                model.toString(),
+                "BeanModel[org.apache.tapestry.internal.services.SimpleBean properties:firstName, lastName, age]");
+
         PropertyModel age = model.get("age");
 
         assertEquals(age.getLabel(), "Age");
@@ -566,7 +570,7 @@
         // Testing a couple of things here:
         // 1) case insensitive
         // 2) unreferenced property names added to the end.
-        
+
         model.reorder("lastname", "AGE");
 
         assertEquals(model.getPropertyNames(), Arrays.asList("lastName", "age", "firstName"));