Author: hlship
Date: Mon Sep  3 16:38:47 2007
New Revision: 572450

URL: http://svn.apache.org/viewvc?rev=572450&view=rev
Log:
TAPESTRY-1676: Add component for editing a single bean property

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java
Modified:
    tapestry/tapestry5/trunk/pom.xml
    tapestry/tapestry5/trunk/support/tapestry-core.launch
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Mixin.java
    
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/services/PropertyEditContext.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.html
    
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/beaneditform.apt
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditFormTest.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java

Modified: tapestry/tapestry5/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/pom.xml?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/pom.xml (original)
+++ tapestry/tapestry5/trunk/pom.xml Mon Sep  3 16:38:47 2007
@@ -235,6 +235,32 @@
         </plugins>
       </build>
     </profile>
+    <!--  Only enable Javadoc as part of the output site when the release 
profile is active. -->
+    <profile>
+      <id>release</id>
+      <reporting>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <configuration>
+              <linksource>true</linksource>
+              <links>
+                <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
+                <link>http://java.sun.com/j2ee/1.4/docs/api/</link>
+                <link>
+                  http://jakarta.apache.org/commons/logging/apidocs/
+                </link>
+              </links>
+              <stylesheetfile>
+                ${basedir}/src/site/resources/css/jdstyle.css
+              </stylesheetfile>
+              <aggregate>true</aggregate>
+            </configuration>
+          </plugin>
+        </plugins>
+      </reporting>
+    </profile>
   </profiles>
   <reporting>
     <plugins>
@@ -254,22 +280,6 @@
           </reportSet>
         </reportSets>
       </plugin>
-
-      <!--       
-        <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <configuration>
-        <linksource>true</linksource>
-        <links>
-        <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
-        <link>http://java.sun.com/j2ee/1.4/docs/api/</link>
-        <link>http://jakarta.apache.org/commons/logging/apidocs/</link>
-        </links>
-        
<stylesheetfile>${basedir}/src/site/resources/css/jdstyle.css</stylesheetfile>
-        <aggregate>true</aggregate>
-        </configuration>
-        </plugin> -->
     </plugins>
   </reporting>
   <repositories>

Modified: tapestry/tapestry5/trunk/support/tapestry-core.launch
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/support/tapestry-core.launch?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/support/tapestry-core.launch (original)
+++ tapestry/tapestry5/trunk/support/tapestry-core.launch Mon Sep  3 16:38:47 
2007
@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <launchConfiguration type="org.testng.eclipse.launchconfig">
+<booleanAttribute key="com.mountainminds.eclemma.core.INPLACE_INSTRUMENTATION" 
value="false"/>
+<listAttribute key="com.mountainminds.eclemma.core.INSTRUMENTATION_PATHS">
+<listEntry value="/tapestry5/bin"/>
+</listAttribute>
 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" 
value="true"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Mixin.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Mixin.java?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Mixin.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Mixin.java
 Mon Sep  3 16:38:47 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 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.
@@ -22,7 +22,7 @@
 import java.lang.annotation.Target;
 
 /**
- * Defines an <em>implementation</em> mixin for a comopnent.
+ * Defines an <em>implementation</em> mixin for a component.
  */
 @Target(FIELD)
 @Documented
@@ -30,7 +30,7 @@
 public @interface Mixin {
 
     /**
-     * Defines the type of mixin, using a logical mixin name. This value takes 
precendence over the
+     * Defines the type of mixin, using a logical mixin name. This value takes 
precedence over the
      * type of field (to which the annotation is attached). In such cases, it 
is presumed that the
      * field's type is an interface implemented by the actual mixin. The 
default value (the empty
      * string) directs Tapestry to use the field type as the mixin class to 
instantiate and attach

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=572450&r1=572449&r2=572450&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
 Mon Sep  3 16:38:47 2007
@@ -58,6 +58,7 @@
  * 
  * @see BeanModel
  * @see BeanModelSource
+ * @see PropertyEditor
  */
 @SupportsInformalParameters
 public class BeanEditForm implements ClientElement, FormValidationControl
@@ -67,7 +68,7 @@
     private String _submitLabel;
 
     /**
-     * The object to be editted by the BeanEditor. This will be read when the 
component renders and
+     * The object to be edited by the BeanEditor. This will be read when the 
component renders and
      * updated when the form for the component is submitted. Typically, the 
container will listen
      * for a "prepare" event, in order to ensure that a non-null value is 
ready to be read or
      * updated.
@@ -76,7 +77,8 @@
     private Object _object;
 
     /** If true, the default, then the embedded Form component will use 
client-side validation. */
-    @Parameter("true")
+    @SuppressWarnings("unused")
+    @Parameter
     private boolean _clientValidation;
 
     @Inject
@@ -85,23 +87,11 @@
     @Inject
     private BeanModelSource _modelSource;
 
-    @Inject
-    private TranslatorDefaultSource _translatorDefaultSource;
-
-    @Inject
-    private FieldValidatorDefaultSource _fieldValidatorDefaultSource;
-
-    @Component(parameters = "clientValidation=clientValidation")
+    @Component(parameters = "clientValidation=inherit:clientValidation")
     private Form _form;
 
-    @Inject
-    private Messages _messages;
-
-    @Inject
-    private Locale _locale;
-
     /**
-     * The model that identifies the parameters to be editted, their order, 
and every other aspect.
+     * The model that identifies the parameters to be edited, their order, and 
every other aspect.
      * If not specified, a default bean model will be created from the type of 
the object bound to
      * the object parameter.
      */
@@ -112,21 +102,9 @@
 
     private String _propertyName;
 
-    private PropertyModel _propertyEditModel;
-
-    private Block _blockForProperty;
-
-    @Inject
-    private Environment _environment;
-
-    @Inject
-    private BeanBlockSource _beanBlockSource;
-
     @Inject
     private ComponentDefaultProvider _defaultProvider;
 
-    private boolean _mustPopBeanEditContext;
-
     /**
      * Defaults the object parameter to a property of the container matching 
the BeanEditForm's id.
      */
@@ -149,88 +127,10 @@
     {
         _propertyName = propertyName;
 
-        _propertyEditModel = _model.get(propertyName);
-
-        _blockForProperty = null;
-
-        Block override = 
_resources.getBlockParameter(_propertyEditModel.getId());
-
-        if (override != null)
-        {
-            _blockForProperty = override;
-            return;
-        }
-
-        String dataType = _propertyEditModel.getDataType();
-
-        try
-        {
-            _blockForProperty = _beanBlockSource.getEditBlock(dataType);
-        }
-        catch (RuntimeException ex)
-        {
-            String message = _messages.format("block-error", _propertyName, 
dataType, _object, ex);
-
-            throw new TapestryException(message, _resources.getLocation(), ex);
-        }
     }
 
     boolean onPrepareFromForm()
     {
-        PropertyEditContext context = new PropertyEditContext()
-        {
-            public Messages getContainerMessages()
-            {
-                return _resources.getContainerMessages();
-            }
-
-            public String getLabel()
-            {
-                return _propertyEditModel.getLabel();
-            }
-
-            public String getPropertyId()
-            {
-                return _propertyEditModel.getId();
-            }
-
-            public Class getPropertyType()
-            {
-                return _propertyEditModel.getPropertyType();
-            }
-
-            public Object getPropertyValue()
-            {
-                return _propertyEditModel.getConduit().get(getObject());
-            }
-
-            public Translator getTranslator()
-            {
-                return 
_translatorDefaultSource.find(_propertyEditModel.getPropertyType());
-            }
-
-            public FieldValidator getValidator(Field field)
-            {
-                return _fieldValidatorDefaultSource.createDefaultValidator(
-                        field,
-                        _propertyName,
-                        _resources.getContainerMessages(),
-                        _locale,
-                        _propertyEditModel.getPropertyType(),
-                        _propertyEditModel.getConduit());
-            }
-
-            public void setPropertyValue(Object value)
-            {
-                _propertyEditModel.getConduit().set(getObject(), value);
-            }
-        };
-
-        _environment.push(PropertyEditContext.class, context);
-        // Depending on whether we're rendering or processing the form 
submission we'll have two
-        // different places to clean up the Environment.
-        _mustPopBeanEditContext = true;
-
         // Fire a new prepare event to be consumed by the container. This is 
the container's
         // chance to ensure that there's an object to edit.
 
@@ -239,7 +139,7 @@
         // Now check to see if the value is null.
 
         // The only problem here is that if the bound property is backed by a 
persistent field, it
-        // is assigned (and stored to the session, and propogated around the 
cluster) first,
+        // is assigned (and stored to the session, and propagated around the 
cluster) first,
         // before values are assigned.
 
         if (_object == null) _object = createDefaultObject();
@@ -253,37 +153,19 @@
             _model = _modelSource.create(beanType, true, 
_resources.getContainerResources());
         }
 
-        return true; // abort the form's prepare event
-    }
-
-    private void cleanupBeanEditContext()
-    {
-        if (_mustPopBeanEditContext)
-        {
-            _environment.pop(PropertyEditContext.class);
-            _mustPopBeanEditContext = false;
-        }
-    }
-
-    void onSubmit()
-    {
-        cleanupBeanEditContext();
-    }
-
-    void afterRender()
-    {
-        cleanupBeanEditContext();
+        // Abort the form's prepare event, as we've already sent a prepare on 
its behalf.
+        return true;
     }
 
     /** Used for testing. */
-    void inject(ComponentResources resources, BeanModelSource modelSource, 
Environment environment)
+    void inject(ComponentResources resources, BeanModelSource modelSource)
     {
         _resources = resources;
         _modelSource = modelSource;
-        _environment = environment;
     }
 
-    Object getObject()
+    /** Returns the object being edited. */
+    public Object getObject()
     {
         return _object;
     }
@@ -305,11 +187,6 @@
         }
     }
 
-    public Block getBlockForProperty()
-    {
-        return _blockForProperty;
-    }
-
     /** Returns the client id of the embedded form. */
     public String getClientId()
     {
@@ -319,11 +196,6 @@
     public String getSubmitLabel()
     {
         return _submitLabel;
-    }
-
-    public boolean getClientValidation()
-    {
-        return _clientValidation;
     }
 
     public void clearErrors()

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java?rev=572450&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java
 Mon Sep  3 16:38:47 2007
@@ -0,0 +1,270 @@
+// 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.corelib.components;
+
+import java.util.Locale;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BeanBlockSource;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.FieldValidatorDefaultSource;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.PropertyEditContext;
+import org.apache.tapestry.services.TranslatorDefaultSource;
+
+/**
+ * Used to edit a single property of a bean. This is used primarily by [EMAIL 
PROTECTED] BeanEditForm}. Unlike
+ * BeanEditForm, the object to be edited must already exist and the [EMAIL 
PROTECTED] BeanModel model}
+ * must be passed in explicitly.
+ */
+public class PropertyEditor
+{
+    /**
+     * Configures and stores a [EMAIL PROTECTED] PropertyEditContext} into the 
[EMAIL PROTECTED] Environment}.
+     */
+    static class SetupEnvironment implements ComponentAction<PropertyEditor>
+    {
+        private static final long serialVersionUID = 5337049721509981997L;
+
+        private final String _property;
+
+        public SetupEnvironment(String property)
+        {
+            _property = property;
+        }
+
+        public void execute(PropertyEditor component)
+        {
+            component.setupEnvironment(_property);
+        }
+    };
+
+    static class CleanupEnvironment implements ComponentAction<PropertyEditor>
+    {
+        private static final long serialVersionUID = 7878694042753046523L;
+
+        public void execute(PropertyEditor component)
+        {
+            component.cleanupEnvironment();
+        }
+    };
+
+    /**
+     * The object to be edited by the BeanEditor. This will be read when the 
component renders and
+     * updated when the form for the component is submitted. Typically, the 
container will listen
+     * for a "prepare" event, in order to ensure that a non-null value is 
ready to be read or
+     * updated.
+     */
+    @Parameter(required = true)
+    private Object _object;
+
+    /**
+     * Where to search for local overrides of property editing blocks as block 
parameters. Further,
+     * the container of the overrides is used as the source for overridden 
validation messages. This
+     * is normally the component itself, but when the component is used within 
a BeanEditForm, it
+     * will be the BeanEditForm's block parameter that will be searched.
+     */
+    @Parameter(value = "componentResources")
+    private ComponentResources _overrides;
+
+    /**
+     * Identifies the property to be edited by the editor.
+     */
+    @Parameter(required = true)
+    private String _property;
+
+    /**
+     * The model that identifies the parameters to be edited, their order, and 
every other aspect.
+     */
+    @Parameter(required = true)
+    private BeanModel _model;
+
+    @Inject
+    private TranslatorDefaultSource _translatorDefaultSource;
+
+    @Inject
+    private FieldValidatorDefaultSource _fieldValidatorDefaultSource;
+
+    @Inject
+    private Environment _environment;
+
+    @Inject
+    private BeanBlockSource _beanBlockSource;
+
+    @Inject
+    private Messages _messages;
+
+    @Inject
+    private Locale _locale;
+
+    @Inject
+    private ComponentResources _resources;
+
+    @Environmental
+    private FormSupport _formSupport;
+
+    private PropertyModel _propertyModel;
+
+    /** Creates a [EMAIL PROTECTED] PropertyEditContext} and pushes it onto 
the [EMAIL PROTECTED] Environment} stack. */
+    void setupEnvironment(final String propertyName)
+    {
+        _propertyModel = _model.get(propertyName);
+
+        PropertyEditContext context = new PropertyEditContext()
+        {
+            public Messages getContainerMessages()
+            {
+                return _resources.getContainerMessages();
+            }
+
+            public String getLabel()
+            {
+                return _propertyModel.getLabel();
+            }
+
+            public String getPropertyId()
+            {
+                return _propertyModel.getId();
+            }
+
+            public Class getPropertyType()
+            {
+                return _propertyModel.getPropertyType();
+            }
+
+            public Object getPropertyValue()
+            {
+                return _propertyModel.getConduit().get(_object);
+            }
+
+            public Translator getTranslator()
+            {
+                return 
_translatorDefaultSource.find(_propertyModel.getPropertyType());
+            }
+
+            public FieldValidator getValidator(Field field)
+            {
+                return _fieldValidatorDefaultSource.createDefaultValidator(
+                        field,
+                        propertyName,
+                        _overrides.getContainerMessages(),
+                        _locale,
+                        _propertyModel.getPropertyType(),
+                        _propertyModel.getConduit());
+            }
+
+            public void setPropertyValue(Object value)
+            {
+                _propertyModel.getConduit().set(_object, value);
+            }
+        };
+
+        _environment.push(PropertyEditContext.class, context);
+    }
+
+    /**
+     * Called at the end of the form render (or at the end of the form 
submission) to clean up the
+     * [EMAIL PROTECTED] Environment} stack.
+     */
+    void cleanupEnvironment()
+    {
+        _environment.pop(PropertyEditContext.class);
+    }
+
+    /**
+     * Record into the Form what's needed to process the property.
+     */
+    void setupRender()
+    {
+        // Sets up the PropertyEditContext for the duration of the render of 
this component
+        // (which will include the duration of the editor block).
+
+        _formSupport.storeAndExecute(this, new SetupEnvironment(_property));
+    }
+
+    /**
+     * Records into the Form the cleanup logic for the property.
+     */
+    void cleanupRender()
+    {
+        // Removes the PropertyEditContext after this component (including the 
editor block)
+        // has rendered.
+
+        _formSupport.storeAndExecute(this, new CleanupEnvironment());
+    }
+
+    /**
+     * Returns a Block for rendering the property. The Block will be able to 
access the
+     * [EMAIL PROTECTED] PropertyEditContext} via the [EMAIL PROTECTED] 
Environmental} annotation.
+     */
+    Block beginRender()
+    {
+        Block override = _overrides.getBlockParameter(_propertyModel.getId());
+
+        if (override != null) { return override; }
+
+        String dataType = _propertyModel.getDataType();
+
+        try
+        {
+            return _beanBlockSource.getEditBlock(dataType);
+        }
+        catch (RuntimeException ex)
+        {
+            String message = _messages.format(
+                    "block-error",
+                    _propertyModel.getPropertyName(),
+                    dataType,
+                    _object,
+                    ex);
+
+            throw new TapestryException(message, _resources.getLocation(), ex);
+        }
+
+    }
+
+    /**
+     * Returns false, to prevent the rendering of the body of the component. 
PropertyEditor should
+     * not have a body.
+     */
+    boolean beforeRenderBody()
+    {
+        return false;
+    }
+
+    /** Used for testing. */
+    void inject(ComponentResources resources, ComponentResources overrides, 
PropertyModel propertyModel,
+            BeanBlockSource beanBlockSource, Messages messages, Object object)
+    {
+        _resources = resources;
+        _overrides = overrides;
+        _propertyModel = propertyModel;
+        _beanBlockSource = beanBlockSource;
+        _messages = messages;
+        _object = object;
+    }
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyEditContext.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyEditContext.java?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyEditContext.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyEditContext.java
 Mon Sep  3 16:38:47 2007
@@ -24,7 +24,7 @@
 import org.apache.tapestry.ioc.Messages;
 
 /**
- * Defines a context for editting a property of a bean via [EMAIL PROTECTED] 
BeanEditForm}. This value is made
+ * Defines a context for editing a property of a bean via [EMAIL PROTECTED] 
BeanEditForm}. This value is made
  * available to blocks via the [EMAIL PROTECTED] Environmental} annotation.
  * 
  * @see BeanBlockSource
@@ -32,13 +32,13 @@
 public interface PropertyEditContext
 {
     /**
-     * Returns the current value of the property being editted (the context 
encapsulates the object
+     * Returns the current value of the property being edited (the context 
encapsulates the object
      * containing the property).
      */
     Object getPropertyValue();
 
     /**
-     * Updates the value of the property being editted (the context 
encapsulates the object
+     * Updates the value of the property being edited (the context 
encapsulates the object
      * containing the property).
      * 
      * @param value
@@ -74,7 +74,7 @@
     String getPropertyId();
 
     /**
-     * Returns the type of the property being editted.
+     * Returns the type of the property being edited.
      */
     Class getPropertyType();
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
 Mon Sep  3 16:38:47 2007
@@ -26,7 +26,9 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.logging.Log;
 import org.apache.tapestry.Asset;
+import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.Link;
 import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.PageRenderSupport;
@@ -187,6 +189,7 @@
 import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.ioc.util.StrategyRegistry;
 import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.ComponentResourcesAware;
 import org.apache.tapestry.runtime.RenderCommand;
 import org.apache.tapestry.translator.DoubleTranslator;
 import org.apache.tapestry.translator.IntegerTranslator;
@@ -726,6 +729,7 @@
      * <li>null to [EMAIL PROTECTED] GridDataSource}
      * <li>String to [EMAIL PROTECTED] GridPagerPosition}
      * <li>List to [EMAIL PROTECTED] SelectModel}
+     * <li>[EMAIL PROTECTED] ComponentResourcesAware} (typically, a component) 
to [EMAIL PROTECTED] ComponentResources}
      * </ul>
      */
     public static void contributeTypeCoercer(Configuration<CoercionTuple> 
configuration)
@@ -788,6 +792,18 @@
             }
         });
 
+        add(
+                configuration,
+                ComponentResourcesAware.class,
+                ComponentResources.class,
+                new Coercion<ComponentResourcesAware, ComponentResources>()
+                {
+
+                    public ComponentResources coerce(ComponentResourcesAware 
input)
+                    {
+                        return input.getComponentResources();
+                    }
+                });
     }
 
     /**

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
 Mon Sep  3 16:38:47 2007
@@ -295,7 +295,7 @@
         return newMock(PropertyConduit.class);
     }
 
-    protected final PropertyModel mockPropertyEditModel()
+    protected final PropertyModel mockPropertyModel()
     {
         return newMock(PropertyModel.class);
     }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.html
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.html?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.html
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.html
 Mon Sep  3 16:38:47 2007
@@ -2,9 +2,9 @@
     <t:errors/>
 
     <div class="t-beaneditor">
-        <div class="t-beaneditor-row" t:type="loop" 
t:source="model.propertyNames"
+        <div class="t-beaneditor-row" t:type="loop" 
t:source="model.propertyNames" t:volatile="true"
             t:value="propertyName">
-            <t:delegate to="blockForProperty"/>
+            <t:propertyEditor property="propertyName" object="object" 
model="model" overrides="this"/>
         </div>
         <div class="t-beaneditor-row">
             <input type="submit" value="${submitLabel}"/>

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties
 Mon Sep  3 16:38:47 2007
@@ -13,4 +13,3 @@
 # limitations under the License.
 
 submit-label=Create/Update
-block-error=Unable to locate a block to edit property '%s' (with data type 
'%s') of object %s: %s
\ No newline at end of file

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties?rev=572450&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties
 Mon Sep  3 16:38:47 2007
@@ -0,0 +1,15 @@
+# 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.
+
+block-error=Unable to locate a block to edit property '%s' (with data type 
'%s') of object %s: %s
\ No newline at end of file

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=572450&r1=572449&r2=572450&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 
Mon Sep  3 16:38:47 2007
@@ -6,7 +6,7 @@
 
   Tapestry includes a powerful component capable of generating a complete 
create/edit user interface for a typical JavaBean, BeanEditForm.
   
-  BeanEditForm analyzes the the properties of the bean, locating just those 
properties that are readable and writeable. It filters down
+  BeanEditForm analyzes the the properties of the bean, locating just those 
properties that are readable and writable. It filters down
   to properties whose type is mapped to a known editor (this is described in 
more detail below).
   
   The default ordering for properties is in the order in which the <getter 
methods> for the properties are defined.
@@ -26,11 +26,13 @@
   
   []
   
-  Resolving a property type to an editor type involves a search up the 
inheritance hiearchy: thus the super-type of Integer, Long, BigDecimal, etc. is
+  Resolving a property type to an editor type involves a search up the 
inheritance hierarchy: thus the super-type of Integer, Long, BigDecimal, etc. is
   Number, which uses a text field for data entry.
+  
+  The list of supported property types is extensible (this is documented 
below).
     
     
-* Automatic Creation
+* Automatic Object Creation
 
   When a page is rendered, the BeanEditForm component will read its object 
parameter as the JavaBean to edit (with the current properties
   of the JavaBean becoming the defaults for the various fields).  Likewise, 
when the form is submitted by the user, the object parameter
@@ -47,14 +49,14 @@
   
 * Non-Visual Properties
 
-  In some cases, a property may be updatable and of a supported type for 
editting, but should not be presented to the user for editting: for example,
+  In some cases, a property may be updatable and of a supported type for 
editing, but should not be presented to the user for editing: for example,
   a property that holds the primary key of a database entity. In such a case, 
the
   {{{../../apidocs/org/apache/tapestry/beaneditor/NonVisual.html}NonVisual}} 
annotation may be applied to the property (either the getter
   or the setter method). 
     
 * Default Validation
 
-  Default validation for fields is primarly determined by property type.
+  Default validation for fields is primary determined by property type.
   
   If desired, additional validation may be specified using the 
   {{{../../apidocs/org/apache/tapestry/beaneditor/Validate.html}Validate}} 
annotation.
@@ -66,12 +68,12 @@
   
 * Default Label
 
-  Tapestry will attempt to provide a reasonable default label for each field, 
based on the property name being editted.  The property name
+  Tapestry will attempt to provide a reasonable default label for each field, 
based on the property name being emitted.  The property name
   is capitalized, and spaces are added before case changes, thus property 
"name" becomes label "Name" and property "streetAddress" becomes label
-  "Street Adresss".  
+  "Street Address".  
   
   BeanEditForm also searches for a label for the field in the containing 
component's message catalog.  The message key is the property name suffixed 
with "-label".
-  If such a label is found, it takes precendence.
+  If such a label is found, it takes precedence.
   
 Property Editor Overrides
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditFormTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditFormTest.java?rev=572450&r1=572449&r2=572450&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditFormTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditFormTest.java
 Mon Sep  3 16:38:47 2007
@@ -37,12 +37,9 @@
         ComponentResources containerResources = mockComponentResources();
         BeanModelSource source = mockBeanModelSource();
         BeanModel model = mockBeanModel();
-        Environment environment = mockEnvironment();
 
         expect(resources.triggerEvent(Form.PREPARE, null, 
null)).andReturn(false);
 
-        train_push(environment, PropertyEditContext.class);
-
         train_getBoundType(resources, RegistrationData.class);
 
         train_getContainerResources(resources, containerResources);
@@ -53,7 +50,7 @@
 
         BeanEditForm component = new BeanEditForm();
 
-        component.inject(resources, source, environment);
+        component.inject(resources, source);
 
         assertTrue(component.onPrepareFromForm());
 
@@ -70,12 +67,9 @@
     {
         ComponentResources resources = mockComponentResources();
         Location l = mockLocation();
-        Environment environment = mockEnvironment();
 
         expect(resources.triggerEvent(Form.PREPARE, null, 
null)).andReturn(false);
 
-        train_push(environment, PropertyEditContext.class);
-
         train_getBoundType(resources, Runnable.class);
 
         train_getCompleteId(resources, "Foo.bar");
@@ -86,7 +80,7 @@
 
         BeanEditForm component = new BeanEditForm();
 
-        component.inject(resources, null, environment);
+        component.inject(resources, null);
 
         try
         {

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java?rev=572450&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java
 Mon Sep  3 16:38:47 2007
@@ -0,0 +1,81 @@
+// 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.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BeanBlockSource;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * Tests an error case for the PropertyEditor component. The success cases are 
mixed into the
+ * BeanEditForm component's integration tests.
+ */
+public class PropertyEditorTest extends TapestryTestCase
+{
+    @Test
+    public void no_editor_block_available()
+    {
+        PropertyModel model = mockPropertyModel();
+        ComponentResources overrides = mockComponentResources();
+        ComponentResources resources = mockComponentResources();
+        BeanBlockSource source = newMock(BeanBlockSource.class);
+        RuntimeException exception = new RuntimeException("Simulated 
failure.");
+        Messages messages = mockMessages();
+        Location l = mockLocation();
+
+        String propertyId = "foo";
+        String dataType = "unk";
+        String propertyName = "fooProp";
+        Object object = "[OBJECT]";
+        String formattedMessage = "formatted-message";
+
+        expect(model.getId()).andReturn(propertyId);
+
+        expect(overrides.getBlockParameter(propertyId)).andReturn(null);
+
+        expect(model.getDataType()).andReturn(dataType);
+
+        expect(source.getEditBlock(dataType)).andThrow(exception);
+        expect(model.getPropertyName()).andReturn(propertyName);
+
+        train_getLocation(resources, l);
+
+        expect(messages.format("block-error", propertyName, dataType, object, 
exception))
+                .andReturn(formattedMessage);
+
+        replay();
+
+        PropertyEditor pe = new PropertyEditor();
+
+        pe.inject(resources, overrides, model, source, messages, object);
+
+        try
+        {
+            pe.beginRender();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getMessage(), formattedMessage);
+            assertSame(ex.getLocation(), l);
+        }
+
+    }
+}

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=572450&r1=572449&r2=572450&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
 Mon Sep  3 16:38:47 2007
@@ -25,6 +25,7 @@
 import java.util.TreeMap;
 import java.util.regex.Pattern;
 
+import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.OptionModel;
 import org.apache.tapestry.PropertyConduit;
 import org.apache.tapestry.SelectModel;
@@ -35,6 +36,7 @@
 import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
 import org.apache.tapestry.ioc.services.PropertyAccess;
 import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.runtime.ComponentResourcesAware;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
@@ -476,4 +478,23 @@
         assertEquals(pattern.toString(), input);
     }
 
+    @Test
+    public void 
type_coersion_from_component_resources_aware_to_component_resources()
+    {
+        ComponentResourcesAware input = newMock(ComponentResourcesAware.class);
+        ComponentResources resources = mockComponentResources();
+
+        expect(input.getComponentResources()).andReturn(resources);
+
+        TypeCoercer coercer = getObject(TypeCoercer.class, null);
+
+        replay();
+
+        ComponentResources actual = coercer.coerce(input, 
ComponentResources.class);
+
+        assertSame(actual, resources);
+
+        verify();
+
+    }
 }


Reply via email to