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

svn commit: r574118 - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry/beaneditor/ tapestry-core/src/main/java/org/apache/tapestry/internal/ tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/ tapestry-core...

Author: hlship
Date: Sun Sep  9 19:44:27 2007
New Revision: 574118

URL: http://svn.apache.org/viewvc?rev=574118&view=rev
Log:
TAPESTRY-1471: Controlling the order of properties within a BeanModel is too complex and needs an improved API

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java
      - copied, changed from r573901, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/Order.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java
      - copied, changed from r573901, tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LogSource.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java
      - copied, changed from r573901, tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LogSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java
      - copied, changed from r573901, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LogSourceImplTest.java
Removed:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/Order.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LogSource.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LogSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LogSourceImplTest.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java Sun Sep  9 19:44:27 2007
@@ -23,7 +23,7 @@
  * Provides the information necessary to build a user interface to view, create or edit an instance
  * of a particular type.
  * <p>
- * BeanModels are not threadsafe, they are also not serializable.
+ * BeanModels are not thread-safe, they are also not serializable.
  * 
  * @see BeanModelSource
  */
@@ -49,17 +49,54 @@
     PropertyModel get(String propertyName);
 
     /**
-     * Adds a new property to the model, returning its mutable model for further refinement.
+     * Adds a new property to the model, returning its mutable model for further refinement. The
+     * property is added to the <em>end</em> of the list of properties.
      * 
      * @param propertyName
      *            name of property to add
-     * @return the model for the property
+     * @return the new property model (for further configuration)
      * @throws RuntimeException
      *             if the property already exists
      */
     PropertyModel add(String propertyName);
 
     /**
+     * Adds a new property to the model, ordered before or after an existing property.
+     * 
+     * @param position
+     *            controls whether the new property is ordered before or after the existing property
+     * @param existingPropertyName
+     *            the name of an existing property (this must exist)
+     * @param propertyName
+     *            the new property to add
+     * @throws RuntimeException
+     *             if the existing property does not exist, or if the new property already does
+     *             exist
+     * @return the new property model (for further configuration)
+     */
+    PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName);
+
+    /**
+     * Adds a new property to the model, ordered before or after an existing property.
+     * 
+     * @param position
+     *            controls whether the new property is ordered before or after the existing property
+     * @param existingPropertyName
+     *            the name of an existing property (this must exist)
+     * @param propertyName
+     *            the new property to add
+     * @param conduit
+     *            conduit used to read or update the property; this may be null for a synthetic or
+     *            placeholder property
+     * @throws RuntimeException
+     *             if the existing property does not exist, or if the new property already does
+     *             exist
+     * @return the new property model (for further configuration)
+     */
+    PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName,
+            PropertyConduit conduit);
+
+    /**
      * Adds a new property to the model, returning its mutable model for further refinement.
      * 
      * @param propertyName
@@ -79,7 +116,7 @@
      * 
      * @param propertyName
      *            the names of properties to be removed (case insensitive)
-     * @return the model for futher modifications
+     * @return the model for further modifications
      */
     BeanModel remove(String... propertyName);
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java?rev=574118&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java Sun Sep  9 19:44:27 2007
@@ -0,0 +1,23 @@
+package org.apache.tapestry.beaneditor;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Placed on either a property getter or a property setter method to control the order in which the
+ * properties are presented to the user.
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface OrderAfter
+{
+    /**
+     * The name of the other property. This property will be ordered before the other property.
+     */
+    String value();
+}

Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java (from r573901, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/Order.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/Order.java&r1=573901&r2=574118&rev=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/Order.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java Sun Sep  9 19:44:27 2007
@@ -23,14 +23,15 @@
 
 /**
  * Placed on either a property getter or a property setter method to control the order in which the
- * properties are presented to the user. The properties will be sorted in ascending order by the
- * value. Properties with no value will be treated as though they have the value 0. When multiple
- * properties have the same order value, they will be sorted alphabetically.
+ * properties are presented to the user.
  */
 @Target(METHOD)
 @Retention(RUNTIME)
 @Documented
-public @interface Order {
-    /** The sort order for this property. */
-    int value();
+public @interface OrderBefore
+{
+    /**
+     * The name of the other property. This property will be ordered before the other property.
+     */
+    String value();
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java Sun Sep  9 19:44:27 2007
@@ -26,16 +26,13 @@
 
     /**
      * Returns the id used to access other resources (this is based on the property name, but with
-     * any excess punctiuation stripped out).
+     * any excess punctuation stripped out).
      */
     String getId();
 
     /** Returns a user-presentable label for the property. */
     String getLabel();
 
-    /** Returns the order vlaue, used to sort the properties into presentation order. */
-    int getOrder();
-
     /** Returns the type of the property. */
     Class getPropertyType();
 
@@ -68,12 +65,6 @@
      * @return the property edit model, for further changes
      */
     PropertyModel label(String label);
-
-    /**
-     * Changes the order for the property. The properties are sorted by order (and then by name for
-     * identical orders) when building the user interface.
-     */
-    PropertyModel order(int order);
 
     /** Returns the containing model, often used for "fluent" construction of the model. */
     BeanModel model();

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java?rev=574118&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java Sun Sep  9 19:44:27 2007
@@ -0,0 +1,13 @@
+package org.apache.tapestry.beaneditor;
+
+/**
+ * Controls the position of newly added {@link PropertyModel}s inside a {@link BeanModel}.
+ */
+public enum RelativePosition
+{
+    /** The new {@link PropertyModel} goes before the existing model. */
+    BEFORE,
+
+    /** The new {@link PropertyModel} goes after the existing model. */
+    AFTER
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java Sun Sep  9 19:44:27 2007
@@ -25,4 +25,5 @@
     {
         return MESSAGES.format("bad-key-value", input);
     }
+
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java Sun Sep  9 19:44:27 2007
@@ -28,16 +28,18 @@
 import org.apache.commons.codec.EncoderException;
 import org.apache.commons.codec.net.URLCodec;
 import org.apache.tapestry.OptionModel;
-import org.apache.tapestry.PropertyConduit;
 import org.apache.tapestry.SelectModel;
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
 import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.Orderer;
 import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
 import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.slf4j.Logger;
 
 /** Shared utility methods used by various implementation classes. */
 public class TapestryInternalUtils
@@ -291,15 +293,6 @@
         return new KeyValue(key.trim(), value.trim());
     }
 
-    public static int defaultOrder(PropertyConduit conduit)
-    {
-        if (conduit == null) return 0;
-
-        Order order = conduit.getAnnotation(Order.class);
-
-        return order == null ? 0 : order.value();
-    }
-
     /**
      * Used to convert a property expression into a key that can be used to locate various resources
      * (Blocks, messages, etc.). Strips out any punctuation characters, leaving just words
@@ -366,9 +359,9 @@
 
     /**
      * Sorts the property names into presentation order. Filters out any properties that have an
-     * explicit {@link Order}, leaving the remainder. Estimates each propertie's position based on
-     * the relative position of the property's getter. The code assumes that all methods are
-     * readable (have a getter method).
+     * explicit {@link OrderBefore}, leaving the remainder. Estimates each propertie's position
+     * based on the relative position of the property's getter. The code assumes that all methods
+     * are readable (have a getter method).
      * 
      * @param classAdapter
      *            defines the bean that contains the properties
@@ -378,16 +371,32 @@
      *            the initial set of property names
      * @return propertyNames filtered and sorted
      */
-    public static List<String> orderProperties(ClassPropertyAdapter classAdapter,
+    public static List<String> orderProperties(Logger logger, ClassPropertyAdapter classAdapter,
             ClassFactory classFactory, List<String> propertyNames)
     {
+
+        // Property name to a list of constraints.
+        Map<String, List<String>> constraints = CollectionFactory.newMap();
+
         List<PropertyOrder> properties = newList();
 
         for (String name : propertyNames)
         {
+
             PropertyAdapter pa = classAdapter.getPropertyAdapter(name);
+            List<String> propertyConstraints = CollectionFactory.newList();
+
+            OrderBefore beforeAnnotation = pa.getAnnotation(OrderBefore.class);
+
+            if (beforeAnnotation != null)
+                propertyConstraints.add("before:" + beforeAnnotation.value());
+
+            OrderAfter afterAnnotation = pa.getAnnotation(OrderAfter.class);
 
-            if (pa.getAnnotation(Order.class) != null) continue;
+            if (afterAnnotation != null)
+                propertyConstraints.add("after:" + afterAnnotation.value());
+
+            if (!propertyConstraints.isEmpty()) constraints.put(name, propertyConstraints);
 
             Method readMethod = pa.getReadMethod();
 
@@ -398,12 +407,38 @@
 
         Collections.sort(properties);
 
-        List<String> result = newList();
+        Orderer<String> orderer = new Orderer<String>(logger);
+        String prev = null;
 
         for (PropertyOrder po : properties)
-            result.add(po._propertyName);
+        {
+            String name = po._propertyName;
+
+            List<String> propertyConstraints = constraints.get(name);
+
+            if (propertyConstraints != null)
+            {
+
+                String[] asArray = propertyConstraints.toArray(new String[propertyConstraints
+                        .size()]);
+
+                orderer.add(name, name, asArray);
+
+                prev = name;
+
+                continue;
+            }
+
+            if (prev == null)
+                orderer.add(name, name);
+            else
+                orderer.add(name, name, "after:" + prev);
+
+            prev = name;
+        }
+
+        return orderer.getOrdered();
 
-        return result;
     }
 
     private static int computeDepth(Method method)

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=574118&r1=574117&r2=574118&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  9 19:44:27 2007
@@ -15,23 +15,23 @@
 package org.apache.tapestry.internal.beaneditor;
 
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
-import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.tapestry.PropertyConduit;
 import org.apache.tapestry.beaneditor.BeanModel;
 import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.beaneditor.RelativePosition;
 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.TypeCoercer;
 import org.apache.tapestry.services.PropertyConduitSource;
 
-public class BeanModelImpl implements BeanModel, Comparator<PropertyModel>
+public class BeanModelImpl implements BeanModel
 {
     private final Class _beanType;
 
@@ -43,6 +43,10 @@
 
     private final Map<String, PropertyModel> _properties = newCaseInsensitiveMap();
 
+    // The list of property names, in desired order (generally not alphabetical order).
+
+    private final List<String> _propertyNames = CollectionFactory.newList();
+
     public BeanModelImpl(Class beanType, PropertyConduitSource propertyConduitSource,
             TypeCoercer typeCoercer, Messages messages)
     {
@@ -59,22 +63,67 @@
 
     public PropertyModel add(String propertyName)
     {
+        PropertyConduit conduit = createConduit(propertyName);
+
+        return add(propertyName, conduit);
+    }
+
+    private void validateNewPropertyName(String propertyName)
+    {
+        notBlank(propertyName, "propertyName");
+
         if (_properties.containsKey(propertyName))
             throw new RuntimeException(BeanEditorMessages.duplicatePropertyName(
                     _beanType,
                     propertyName));
+    }
+
+    public PropertyModel add(RelativePosition position, String existingPropertyName,
+            String propertyName, PropertyConduit conduit)
+    {
+        notNull(position, "position");
+
+        validateNewPropertyName(propertyName);
+
+        // Locate the existing one.
+
+        PropertyModel existing = get(existingPropertyName);
+
+        // Use the case normalized property name.
+
+        int pos = _propertyNames.indexOf(existing.getPropertyName());
+
+        PropertyModel newModel = new PropertyModelImpl(this, propertyName, conduit, _messages);
+
+        _properties.put(propertyName, newModel);
 
+        int offset = position == RelativePosition.AFTER ? 1 : 0;
+
+        _propertyNames.add(pos + offset, propertyName);
+
+        return newModel;
+    }
+
+    public PropertyModel add(RelativePosition position, String existingPropertyName,
+            String propertyName)
+    {
         PropertyConduit conduit = createConduit(propertyName);
 
-        return add(propertyName, conduit);
+        return add(position, existingPropertyName, propertyName, conduit);
     }
 
     public PropertyModel add(String propertyName, PropertyConduit conduit)
     {
+        validateNewPropertyName(propertyName);
+
         PropertyModel propertyModel = new PropertyModelImpl(this, propertyName, conduit, _messages);
 
         _properties.put(propertyName, propertyModel);
 
+        // Remember the order in which the properties were added.
+
+        _propertyNames.add(propertyName);
+
         return propertyModel;
     }
 
@@ -100,33 +149,25 @@
 
     public List<String> getPropertyNames()
     {
-        List<PropertyModel> propertyModels = newList(_properties.values());
-
-        // Sort the list of models by their order property.
-
-        Collections.sort(propertyModels, this);
-
-        List<String> result = newList();
-
-        for (PropertyModel propertyModel : propertyModels)
-            result.add(propertyModel.getPropertyName());
-
-        return result;
+        return CollectionFactory.newList(_propertyNames);
     }
 
-    public int compare(PropertyModel o1, PropertyModel o2)
+    public BeanModel remove(String... propertyNames)
     {
-        int result = o1.getOrder() - o2.getOrder();
+        for (String propertyName : propertyNames)
+        {
+            PropertyModel model = _properties.get(propertyName);
 
-        if (result == 0)
-            result = o1.getPropertyName().compareTo(o2.getPropertyName());
+            if (model == null) continue;
 
-        return result;
-    }
+            // De-referencing from the model is needed because the name provided may not be a
+            // case-exact match, so we get the normalized or canonical name from the model because
+            // that's the one in _propertyNames.
 
-    public BeanModel remove(String... propertyNames)
-    {
-        _properties.keySet().removeAll(Arrays.asList(propertyNames));
+            _propertyNames.remove(model.getPropertyName());
+
+            _properties.remove(propertyName);
+        }
 
         return this;
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java Sun Sep  9 19:44:27 2007
@@ -35,8 +35,6 @@
 
     private String _label;
 
-    private int _order;
-
     private String _dataType;
 
     private boolean _sortable;
@@ -49,7 +47,6 @@
         _conduit = conduit;
 
         _id = TapestryInternalUtils.extractIdFromPropertyExpression(name);
-        _order = TapestryInternalUtils.defaultOrder(conduit);
 
         _label = TapestryInternalUtils.defaultLabel(_id, messages, name);
 
@@ -93,18 +90,6 @@
     public String getPropertyName()
     {
         return _name;
-    }
-
-    public int getOrder()
-    {
-        return _order;
-    }
-
-    public PropertyModel order(int order)
-    {
-        _order = order;
-
-        return this;
     }
 
     public BeanModel model()

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java Sun Sep  9 19:44:27 2007
@@ -15,16 +15,20 @@
 package org.apache.tapestry.internal.services;
 
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
 
 import java.util.List;
+import java.util.Map;
 
 import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.beaneditor.BeanModel;
 import org.apache.tapestry.beaneditor.NonVisual;
 import org.apache.tapestry.internal.TapestryInternalUtils;
 import org.apache.tapestry.internal.beaneditor.BeanModelImpl;
+import org.apache.tapestry.ioc.LoggerSource;
 import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
 import org.apache.tapestry.ioc.services.PropertyAccess;
@@ -36,6 +40,8 @@
 
 public class BeanModelSourceImpl implements BeanModelSource
 {
+    private final LoggerSource _loggerSource;
+
     private final TypeCoercer _typeCoercer;
 
     private final PropertyAccess _propertyAccess;
@@ -46,10 +52,11 @@
 
     private final DataTypeAnalyzer _dataTypeAnalyzer;
 
-    public BeanModelSourceImpl(TypeCoercer typeCoercer, PropertyAccess propertyAccess,
-            PropertyConduitSource propertyConduitSource, ClassFactory classFactory,
-            DataTypeAnalyzer dataTypeAnalyzer)
+    public BeanModelSourceImpl(LoggerSource loggerSource, TypeCoercer typeCoercer,
+            PropertyAccess propertyAccess, PropertyConduitSource propertyConduitSource,
+            ClassFactory classFactory, DataTypeAnalyzer dataTypeAnalyzer)
     {
+        _loggerSource = loggerSource;
         _typeCoercer = typeCoercer;
         _propertyAccess = propertyAccess;
         _propertyConduitSource = propertyConduitSource;
@@ -67,48 +74,59 @@
 
         ClassPropertyAdapter adapter = _propertyAccess.getAdapter(beanClass);
 
-        BeanModel model = new BeanModelImpl(beanClass, _propertyConduitSource, _typeCoercer,
+        final BeanModel model = new BeanModelImpl(beanClass, _propertyConduitSource, _typeCoercer,
                 messages);
 
         List<String> propertyNames = newList();
 
-        for (String propertyName : adapter.getPropertyNames())
+        Map<String, Runnable> worksheet = newMap();
+
+        for (final String propertyName : adapter.getPropertyNames())
         {
             PropertyAdapter pa = adapter.getPropertyAdapter(propertyName);
 
-            if (!pa.isRead())
-                continue;
+            if (!pa.isRead()) continue;
 
-            if (pa.getAnnotation(NonVisual.class) != null)
-                continue;
+            if (pa.getAnnotation(NonVisual.class) != null) continue;
 
-            if (filterReadOnlyProperties && !pa.isUpdate())
-                continue;
+            if (filterReadOnlyProperties && !pa.isUpdate()) continue;
 
-            String dataType = _dataTypeAnalyzer.identifyDataType(pa);
+            final String dataType = _dataTypeAnalyzer.identifyDataType(pa);
 
             // If an unregistered type, then ignore the property.
 
-            if (dataType == null)
-                continue;
-
-            model.add(propertyName).dataType(dataType);
+            if (dataType == null) continue;
 
             propertyNames.add(propertyName);
+
+            // We need to defer execution of this; we want to add them in proper order, not
+            // alphabetical order.
+
+            Runnable worker = new Runnable()
+            {
+                public void run()
+                {
+                    model.add(propertyName).dataType(dataType);
+                }
+            };
+
+            worksheet.put(propertyName, worker);
         }
 
-        // Set default property order for properties that are not explicit.
+        // Determine the correct order to add the properties.
 
-        List<String> orderedNames = TapestryInternalUtils.orderProperties(
-                adapter,
-                _classFactory,
-                propertyNames);
+        List<String> orderedNames = TapestryInternalUtils.orderProperties(_loggerSource
+                .getLogger(beanClass), adapter, _classFactory, propertyNames);
 
-        for (int i = 0; i < orderedNames.size(); i++)
+        for (String propertyName : orderedNames)
         {
-            String propertyName = orderedNames.get(i);
+            Runnable r = worksheet.get(propertyName);
+
+            // This actually adds the property to the model, but we're doing it
+            // in orderedNames order, not propertyNames order (which is alphabetical).
+            // The default ordering comes from method ordering within the class.
 
-            model.get(propertyName).order(i);
+            r.run();
         }
 
         return model;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java Sun Sep  9 19:44:27 2007
@@ -25,7 +25,7 @@
 
 import org.apache.tapestry.internal.events.InvalidationListener;
 import org.apache.tapestry.internal.model.MutableComponentModelImpl;
-import org.apache.tapestry.ioc.LogSource;
+import org.apache.tapestry.ioc.LoggerSource;
 import org.apache.tapestry.ioc.Resource;
 import org.apache.tapestry.ioc.internal.util.ClasspathResource;
 import org.apache.tapestry.model.ComponentModel;
@@ -46,14 +46,14 @@
 
     private final ComponentClassTransformWorker _workerChain;
 
-    private final LogSource _logSource;
+    private final LoggerSource _logSource;
 
     /**
      * @param workerChain
      *            the ordered list of class transform works as a chain of command instance
      */
     public ComponentClassTransformerImpl(ComponentClassTransformWorker workerChain,
-            LogSource logSource)
+            LoggerSource logSource)
     {
         _workerChain = workerChain;
         _logSource = logSource;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java Sun Sep  9 19:44:27 2007
@@ -16,7 +16,7 @@
 
 import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.beaneditor.BeanModel;
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.beaneditor.OrderBefore;
 
 /**
  * Used by a component to create a default {@link BeanModel} for a particular bean class. Also
@@ -27,7 +27,7 @@
     /**
      * Creates a new model used for editting the indicated bean class. The model will represent all
      * read/write properties of the bean. The order of the properties is defined by the
-     * {@link Order} annotation on the getter or setter methods. The labels for the properties are
+     * {@link OrderBefore} annotation on the getter or setter methods. The labels for the properties are
      * derived from the property names, but if the component's message catalog has keys of the form
      * <code>propertyName-label</code>, then those will be used instead.
      * <p>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties Sun Sep  9 19:44:27 2007
@@ -12,5 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-bad-key-value=Key/value pair '%s' is not properly formatted (it does not contain a equals sign).
- 
\ No newline at end of file
+bad-key-value=Key/value pair '%s' is not properly formatted (it does not contain an equals sign).

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java Sun Sep  9 19:44:27 2007
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.integration.app1.data;
 
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
 import org.apache.tapestry.beaneditor.Validate;
 
 public class RegistrationData
@@ -28,26 +30,28 @@
 
     private boolean _citizen;
 
-    public String getFirstName()
+    @OrderAfter("lastName")
+    @Validate("min=1900,max=2007")
+    public int getBirthYear()
     {
-        return _firstName;
+        return _birthYear;
     }
 
-    @Validate("required,minlength=5")
-    public String getLastName()
+    @OrderBefore("citizen")
+    public Sex getSex()
     {
-        return _lastName;
+        return _sex;
     }
 
-    @Validate("min=1900,max=2007")
-    public int getBirthYear()
+    public String getFirstName()
     {
-        return _birthYear;
+        return _firstName;
     }
 
-    public Sex getSex()
+    @Validate("required,minlength=5")
+    public String getLastName()
     {
-        return _sex;
+        return _lastName;
     }
 
     public boolean isCitizen()

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java Sun Sep  9 19:44:27 2007
@@ -14,16 +14,15 @@
 
 package org.apache.tapestry.integration.app1.data;
 
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.beaneditor.OrderBefore;
 
 public interface SimpleTrack
 {
-    @Order(100)
+    @OrderBefore("album")
     String getTitle();
 
-    @Order(200)
+    @OrderBefore("rating")
     String getAlbum();
 
-    @Order(300)
     int getRating();
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java Sun Sep  9 19:44:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal;
 
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.beaneditor.OrderBefore;
 
 public class PropertyOrderBean
 {
@@ -34,7 +34,7 @@
         return _second;
     }
 
-    @Order(-1)
+    @OrderBefore("first")
     public String getThird()
     {
         return _third;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java Sun Sep  9 19:44:27 2007
@@ -29,7 +29,7 @@
 import org.apache.tapestry.OptionModel;
 import org.apache.tapestry.PropertyConduit;
 import org.apache.tapestry.SelectModel;
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.beaneditor.OrderBefore;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.ioc.services.ClassFactory;
@@ -308,37 +308,6 @@
     }
 
     @Test
-    public void default_order_no_annotation()
-    {
-        PropertyConduit conduit = mockPropertyConduit();
-
-        train_getAnnotation(conduit, Order.class, null);
-
-        replay();
-
-        assertEquals(TapestryInternalUtils.defaultOrder(conduit), 0);
-
-        verify();
-    }
-
-    @Test
-    public void default_order_with_annotation()
-    {
-        PropertyConduit conduit = mockPropertyConduit();
-        Order order = newMock(Order.class);
-
-        train_getAnnotation(conduit, Order.class, order);
-
-        expect(order.value()).andReturn(99);
-
-        replay();
-
-        assertEquals(TapestryInternalUtils.defaultOrder(conduit), 99);
-
-        verify();
-    }
-
-    @Test
     public void extract_id_from_property_expression()
     {
         assertEquals(
@@ -394,7 +363,7 @@
 
         names.remove("class");
 
-        List<String> sorted = TapestryInternalUtils.orderProperties(adapter, _classFactory, names);
+        List<String> sorted = TapestryInternalUtils.orderProperties(null, adapter, _classFactory, names);
 
         assertEquals(sorted, Arrays.asList("firstName", "lastName", "age"));
     }
@@ -408,7 +377,7 @@
 
         names.remove("class");
 
-        List<String> sorted = TapestryInternalUtils.orderProperties(adapter, _classFactory, names);
+        List<String> sorted = TapestryInternalUtils.orderProperties(null, adapter, _classFactory, names);
 
         // Subclass properties listed after superclass properties, as desired.
 
@@ -431,11 +400,11 @@
 
         names.remove("class");
 
-        List<String> sorted = TapestryInternalUtils.orderProperties(adapter, _classFactory, names);
+        List<String> sorted = TapestryInternalUtils.orderProperties(null, adapter, _classFactory, names);
 
-        // Property third has an explicit @Order
+        // Property third has an explicit @OrderBefore
 
-        assertEquals(sorted, Arrays.asList("first", "second"));
+        assertEquals(sorted, Arrays.asList("third", "first", "second"));
     }
 
     @Test

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java Sun Sep  9 19:44:27 2007
@@ -16,7 +16,9 @@
 
 import org.apache.tapestry.Binding;
 import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.annotations.BeforeRenderBody;
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.internal.util.IntegerRange;
 import org.apache.tapestry.ioc.Location;
@@ -93,7 +95,7 @@
 
         Binding binding = _factory.newBinding("test binding", resources, null, "readOnly", l);
 
-        assertEquals(binding.getAnnotation(Order.class).value(), 100);
+        assertEquals(binding.getAnnotation(OrderBefore.class).value(), "writeOnly");
 
         verify();
     }
@@ -109,7 +111,7 @@
 
         Binding binding = _factory.newBinding("test binding", resources, null, "writeOnly", l);
 
-        assertEquals(binding.getAnnotation(Order.class).value(), 200);
+        assertEquals(binding.getAnnotation(OrderAfter.class).value(), "foobar");
 
         verify();
     }
@@ -125,7 +127,7 @@
 
         Binding binding = _factory.newBinding("test binding", resources, null, "intValue", l);
 
-        assertNull(binding.getAnnotation(Order.class));
+        assertNull(binding.getAnnotation(OrderBefore.class));
 
         verify();
     }
@@ -146,7 +148,7 @@
                 "stringHolderMethod()",
                 l);
 
-        assertEquals(binding.getAnnotation(Order.class).value(), 300);
+        assertNotNull(binding.getAnnotation(BeforeRenderBody.class));
 
         verify();
     }
@@ -162,7 +164,7 @@
 
         Binding binding = _factory.newBinding("test binding", resources, null, "objectValue", l);
 
-        assertEquals(binding.getAnnotation(Order.class).value(), 1000);
+        assertEquals(binding.getAnnotation(OrderAfter.class).value(), "readOnly");
 
         verify();
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java Sun Sep  9 19:44:27 2007
@@ -14,7 +14,10 @@
 
 package org.apache.tapestry.internal.bindings;
 
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.annotations.BeforeRenderBody;
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
+import org.apache.tapestry.ioc.annotations.Symbol;
 
 public class TargetBean extends DefaultComponent
 {
@@ -31,7 +34,7 @@
         return _stringHolder;
     }
 
-    @Order(300)
+    @BeforeRenderBody
     public StringHolder stringHolderMethod()
     {
         return _stringHolder;
@@ -52,25 +55,25 @@
         _intValue = intValue;
     }
 
-    @Order(1000)
+    @OrderAfter("readOnly")
     public String getObjectValue()
     {
         return _objectValue;
     }
 
-    @Order(2000)
+    @OrderAfter("writeOnly")
     public void setObjectValue(String objectValue)
     {
         _objectValue = objectValue;
     }
 
-    @Order(200)
+    @OrderAfter("foobar")
     public void setWriteOnly(String value)
     {
         _writeOnly = value;
     }
 
-    @Order(100)
+    @OrderBefore("writeOnly")
     public String getReadOnly()
     {
         return "ReadOnly";

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=574118&r1=574117&r2=574118&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  9 19:44:27 2007
@@ -21,6 +21,7 @@
 import org.apache.tapestry.PropertyConduit;
 import org.apache.tapestry.beaneditor.BeanModel;
 import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.beaneditor.RelativePosition;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.services.BeanModelSource;
@@ -101,6 +102,117 @@
     }
 
     @Test
+    public void add_before()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+        PropertyConduit conduit = mockPropertyConduit();
+
+        Class propertyType = String.class;
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        expect(conduit.getPropertyType()).andReturn(propertyType).atLeastOnce();
+
+        replay();
+
+        BeanModel model = _source.create(SimpleBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        // Note the use of case insensitivity here.
+
+        PropertyModel property = model.add(
+                RelativePosition.BEFORE,
+                "lastname",
+                "middleInitial",
+                conduit);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList(
+                "firstName",
+                "middleInitial",
+                "lastName",
+                "age"));
+
+        assertEquals(property.getPropertyName(), "middleInitial");
+        assertSame(property.getConduit(), conduit);
+        assertSame(property.getPropertyType(), propertyType);
+
+        verify();
+    }
+
+    @Test
+    public void add_before_using_default_conduit()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        Class propertyType = String.class;
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = _source.create(SimpleBean.class, true, resources);
+
+        model.remove("firstname");
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("lastName", "age"));
+
+        // Note the use of case insensitivity here.
+
+        PropertyModel property = model.add(RelativePosition.BEFORE, "lastname", "firstName");
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        assertEquals(property.getPropertyName(), "firstName");
+        assertSame(property.getPropertyType(), String.class);
+
+        verify();
+    }
+
+    @Test
+    public void add_after()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+        PropertyConduit conduit = mockPropertyConduit();
+
+        Class propertyType = String.class;
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        expect(conduit.getPropertyType()).andReturn(propertyType).atLeastOnce();
+
+        replay();
+
+        BeanModel model = _source.create(SimpleBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        PropertyModel property = model.add(
+                RelativePosition.AFTER,
+                "firstname",
+                "middleInitial",
+                conduit);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList(
+                "firstName",
+                "middleInitial",
+                "lastName",
+                "age"));
+
+        assertEquals(property.getPropertyName(), "middleInitial");
+        assertSame(property.getConduit(), conduit);
+        assertSame(property.getPropertyType(), propertyType);
+
+        verify();
+    }
+
+    @Test
     public void filtering_out_read_only_properties()
     {
         ComponentResources resources = mockComponentResources();
@@ -372,7 +484,6 @@
         assertFalse(property.isSortable());
         assertSame(property.getPropertyType(), Object.class);
         assertEquals(property.getLabel(), "Placeholder");
-        assertEquals(property.getOrder(), 0);
 
         verify();
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java Sun Sep  9 19:44:27 2007
@@ -14,7 +14,8 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
 
 public class StoogeBean
 {
@@ -25,12 +26,13 @@
         return _moe;
     }
 
-    @Order(100)
+    @OrderAfter("shemp")
     public int getCurly()
     {
         return _curly;
     }
 
+    @OrderBefore("moe")
     public int getLarry()
     {
         return _larry;
@@ -46,7 +48,6 @@
         _curly = curly;
     }
 
-    @Order(-1)
     public void setLarry(int larry)
     {
         _larry = larry;

Copied: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java (from r573901, tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LogSource.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java?p2=tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java&p1=tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LogSource.java&r1=573901&r2=574118&rev=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LogSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java Sun Sep  9 19:44:27 2007
@@ -18,9 +18,9 @@
 
 /**
  * A wrapper around SLF4J's LoggerFactory that exists to allow particular projects to "hook" the
- * creation of Loggeer instances.
+ * creation of Logger instances.
  */
-public interface LogSource
+public interface LoggerSource
 {
     /** Creates or retrieves a log based on Class. This is rarely used in Tapestry IOC. */
     Logger getLogger(Class clazz);

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java Sun Sep  9 19:44:27 2007
@@ -23,7 +23,7 @@
 import org.apache.tapestry.ioc.annotations.SubModule;
 import org.apache.tapestry.ioc.def.ModuleDef;
 import org.apache.tapestry.ioc.internal.DefaultModuleDefImpl;
-import org.apache.tapestry.ioc.internal.LogSourceImpl;
+import org.apache.tapestry.ioc.internal.LoggerSourceImpl;
 import org.apache.tapestry.ioc.internal.RegistryImpl;
 import org.apache.tapestry.ioc.internal.RegistryWrapper;
 import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
@@ -34,7 +34,7 @@
 
 /**
  * Used to construct the IoC {@link org.apache.tapestry.ioc.Registry}. This class is <em>not</em>
- * threadsafe. The Registry, once created, <em>is</em> threadsafe.
+ * thread-safe. The Registry, once created, <em>is</em> thread-safe.
  */
 public final class RegistryBuilder
 {
@@ -47,7 +47,7 @@
 
     private final Logger _logger;
 
-    private final LogSource _logSource;
+    private final LoggerSource _loggerSource;
 
     private final ClassFactory _classFactory;
 
@@ -58,19 +58,19 @@
 
     public RegistryBuilder(ClassLoader classLoader)
     {
-        this(classLoader, new LogSourceImpl());
+        this(classLoader, new LoggerSourceImpl());
     }
 
-    public RegistryBuilder(ClassLoader classLoader, LogSource logSource)
+    public RegistryBuilder(ClassLoader classLoader, LoggerSource loggerSource)
     {
         _classLoader = classLoader;
-        _logSource = logSource;
-        _logger = logSource.getLogger(RegistryBuilder.class);
+        _loggerSource = loggerSource;
+        _logger = loggerSource.getLogger(RegistryBuilder.class);
 
         // Make the ClassFactory appear to be a service inside TapestryIOCModule, even before that
         // module exists.
 
-        Logger classFactoryLogger = logSource.getLogger(TapestryIOCModule.class.getName()
+        Logger classFactoryLogger = loggerSource.getLogger(TapestryIOCModule.class.getName()
                 + ".ClassFactory");
 
         _classFactory = new ClassFactoryImpl(_classLoader, classFactoryLogger);
@@ -129,7 +129,7 @@
     {
         _lock.lock();
 
-        RegistryImpl registry = new RegistryImpl(_modules, _classFactory, _logSource);
+        RegistryImpl registry = new RegistryImpl(_modules, _classFactory, _loggerSource);
 
         return new RegistryWrapper(registry);
     }

Copied: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java (from r573901, tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LogSourceImpl.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java?p2=tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java&p1=tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LogSourceImpl.java&r1=573901&r2=574118&rev=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LogSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java Sun Sep  9 19:44:27 2007
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.ioc.internal;
 
-import org.apache.tapestry.ioc.LogSource;
+import org.apache.tapestry.ioc.LoggerSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -23,7 +23,7 @@
  * be provided that promote warnings or errors upto thrown exceptions, for people who like their IOC
  * container extra finicky. In addition, the extra layer makes things a lot easier to mock.
  */
-public class LogSourceImpl implements LogSource
+public class LoggerSourceImpl implements LoggerSource
 {
     public Logger getLogger(Class clazz)
     {

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java Sun Sep  9 19:44:27 2007
@@ -30,7 +30,7 @@
 import org.apache.tapestry.ioc.AnnotationProvider;
 import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.IOCConstants;
-import org.apache.tapestry.ioc.LogSource;
+import org.apache.tapestry.ioc.LoggerSource;
 import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.ObjectLocator;
 import org.apache.tapestry.ioc.ObjectProvider;
@@ -84,7 +84,7 @@
 
     private final RegistryShutdownHubImpl _registryShutdownHub;
 
-    private final LogSource _logSource;
+    private final LoggerSource _loggerSource;
 
     /** Map from service id to the Module that contains the service. */
     private final Map<String, Module> _serviceIdToModule = newCaseInsensitiveMap();
@@ -122,17 +122,17 @@
      *            defines the modules (and builders, decorators, etc., within)
      * @param classFactory
      *            TODO
-     * @param logSource
-     *            used to obtain Log instances
+     * @param loggerSource
+     *            used to obtain Logger instances
      */
     public RegistryImpl(Collection<ModuleDef> moduleDefs, ClassFactory classFactory,
-            LogSource logSource)
+            LoggerSource loggerSource)
     {
-        _logSource = logSource;
+        _loggerSource = loggerSource;
 
         for (ModuleDef def : moduleDefs)
         {
-            Logger logger = _logSource.getLogger(def.getLoggerName());
+            Logger logger = _loggerSource.getLogger(def.getLoggerName());
 
             Module module = new ModuleImpl(this, def, classFactory, logger);
 
@@ -150,7 +150,7 @@
             }
         }
 
-        addBuiltin(LOG_SOURCE_SERVICE_ID, LogSource.class, _logSource);
+        addBuiltin(LOG_SOURCE_SERVICE_ID, LoggerSource.class, _loggerSource);
 
         _classFactory = classFactory;
 
@@ -198,12 +198,12 @@
 
         assert module != null;
 
-        return _logSource.getLogger(module.getLoggerName() + "." + serviceId);
+        return _loggerSource.getLogger(module.getLoggerName() + "." + serviceId);
     }
 
     private Logger loggerForBuiltinService(String serviceId)
     {
-        return _logSource.getLogger(TapestryIOCModule.class + "." + serviceId);
+        return _loggerSource.getLogger(TapestryIOCModule.class + "." + serviceId);
     }
 
     private <T> void addBuiltin(String serviceId, Class<T> serviceInterface, T service)

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java?rev=574118&r1=574117&r2=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java Sun Sep  9 19:44:27 2007
@@ -24,7 +24,7 @@
 import org.apache.tapestry.ioc.AnnotationProvider;
 import org.apache.tapestry.ioc.Configuration;
 import org.apache.tapestry.ioc.Location;
-import org.apache.tapestry.ioc.LogSource;
+import org.apache.tapestry.ioc.LoggerSource;
 import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.MessageFormatter;
 import org.apache.tapestry.ioc.Messages;
@@ -279,7 +279,7 @@
         expect(threadLocale.getLocale()).andReturn(locale);
     }
 
-    protected final void train_getLogger(LogSource source, String serviceId, Logger logger)
+    protected final void train_getLogger(LoggerSource source, String serviceId, Logger logger)
     {
         expect(source.getLogger(serviceId)).andReturn(logger).atLeastOnce();
     }

Copied: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java (from r573901, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LogSourceImplTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java?p2=tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java&p1=tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LogSourceImplTest.java&r1=573901&r2=574118&rev=574118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LogSourceImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java Sun Sep  9 19:44:27 2007
@@ -14,12 +14,12 @@
 
 package org.apache.tapestry.ioc.internal;
 
-import org.apache.tapestry.ioc.LogSource;
+import org.apache.tapestry.ioc.LoggerSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
-public class LogSourceImplTest extends IOCInternalTestCase
+public class LoggerSourceImplTest extends IOCInternalTestCase
 {
     @Test
     public void get_by_class()
@@ -27,7 +27,7 @@
         Class clazz = getClass();
 
         Logger expected = LoggerFactory.getLogger(clazz);
-        LogSource logSource = new LogSourceImpl();
+        LoggerSource logSource = new LoggerSourceImpl();
         Logger actual = logSource.getLogger(clazz);
 
         assertSame(actual, expected);
@@ -39,7 +39,7 @@
         String name = "foo.Bar";
 
         Logger expected = LoggerFactory.getLogger(name);
-        LogSource logSource = new LogSourceImpl();
+        LoggerSource logSource = new LoggerSourceImpl();
         Logger actual = logSource.getLogger(name);
 
         assertSame(actual, expected);