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 2008/06/25 00:41:26 UTC

svn commit: r671374 - in /tapestry/tapestry5/trunk: tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ tapestry-core/src/main/java/org/apache/tapestry5/annotations/ tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/ tapestry-...

Author: hlship
Date: Tue Jun 24 15:41:25 2008
New Revision: 671374

URL: http://svn.apache.org/viewvc?rev=671374&view=rev
Log:
TAPESTRY-2476: Unhelpful exception messages when a null value is bound to a required parameter

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullParameterDemo.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NullParameterDemo.java
Modified:
    tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java
    tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Parameter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractPropertyOutput.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractTextField.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ExceptionDisplay.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Label.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Output.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PageLink.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Palette.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/TriggerFragment.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/ParameterModelImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ParameterModel.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ParameterWorkerTest.java

Modified: tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java (original)
+++ tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java Tue Jun 24 15:41:25 2008
@@ -392,6 +392,8 @@
 
                 if (!pd.getCache()) flags.add("NOT Cached");
 
+                if (!pd.getAllowNull()) flags.add("NOT Allow Null");
+
                 Element row = new Element("tr");
                 table.appendChild(row);
 
@@ -403,9 +405,9 @@
                 addChild(row, "td", pd.getDescription());
             }
         }
-        
-        if(cd.isSupportsInformalParameters())
-        	addChild(section, "p", "Informal parameters: supported");
+
+        if (cd.isSupportsInformalParameters())
+            addChild(section, "p", "Informal parameters: supported");
 
         addExternalDocumentation(body, docSearchPath, className);
 
@@ -434,7 +436,6 @@
     {
         String classNamePath = toPath(className);
 
-
         String pathExtension = classNamePath + ".xdoc";
 
         for (File path : docSearchPath)
@@ -744,7 +745,8 @@
             String superClassName = element.getAttributeValue("super-class");
             String supportsInformalParameters = element.getAttributeValue("supports-informal-parameters");
 
-            ClassDescription cd = new ClassDescription(className, superClassName, description, Boolean.valueOf(supportsInformalParameters));
+            ClassDescription cd = new ClassDescription(className, superClassName, description,
+                                                       Boolean.valueOf(supportsInformalParameters));
 
             result.put(className, cd);
 
@@ -771,11 +773,12 @@
             String defaultValue = node.getAttributeValue("default");
             boolean required = Boolean.parseBoolean(node.getAttributeValue("required"));
             boolean cache = Boolean.parseBoolean(node.getAttributeValue("cache"));
+            boolean allowNull = Boolean.parseBoolean(node.getAttributeValue("allowNull"));
             String defaultPrefix = node.getAttributeValue("default-prefix");
             String description = node.getValue();
 
-            ParameterDescription pd = new ParameterDescription(name, type, defaultValue, defaultPrefix, required, cache,
-                                                               description);
+            ParameterDescription pd = new ParameterDescription(name, type, defaultValue, defaultPrefix, required,
+                                                               allowNull, cache, description);
 
             cd.getParameters().put(name, pd);
         }

Modified: tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java (original)
+++ tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java Tue Jun 24 15:41:25 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -26,18 +26,22 @@
 
     private final boolean required;
 
+    private final boolean allowNull;
+
     private final boolean cache;
 
     private final String description;
 
     public ParameterDescription(String name, String type, String defaultValue,
-                                String defaultPrefix, boolean required, boolean cache, String description)
+                                String defaultPrefix, boolean required, boolean allowNull, boolean cache,
+                                String description)
     {
         this.name = name;
         this.type = type;
         this.defaultValue = defaultValue;
         this.defaultPrefix = defaultPrefix;
         this.required = required;
+        this.allowNull = allowNull;
         this.cache = cache;
         this.description = description;
     }
@@ -77,4 +81,8 @@
         return type;
     }
 
+    public boolean getAllowNull()
+    {
+        return allowNull;
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Parameter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Parameter.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Parameter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Parameter.java Tue Jun 24 15:41:25 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -15,7 +15,6 @@
 package org.apache.tapestry5.annotations;
 
 import org.apache.tapestry5.BindingConstants;
-import org.apache.tapestry5.services.BindingFactory;
 
 import java.lang.annotation.Documented;
 import static java.lang.annotation.ElementType.FIELD;
@@ -46,6 +45,13 @@
     boolean required() default false;
 
     /**
+     * If true, and the parameter <em>is</em> bound, then the value for the parameter must not be null. The default is
+     * to allow nulls. This is different than required, in that the parameter may be bound, but bound to a null value.
+     */
+
+    boolean allowNull() default true;
+
+    /**
      * If true (the default), then the value for the parameter is cached while the component is, itself, rendering.
      * Values from invariant bindings (such as literal strings) are always cached, regardless of this setting. Set this
      * attribute to false to force the parameter to be {@link org.apache.tapestry5.Binding#get() re-read} every time the
@@ -62,8 +68,8 @@
     /**
      * The default binding prefix for the parameter, if no specific binding prefix is provided with the binding. There
      * is <em>rarely</em> a reason to override this. Typically, non-standard default binding prefixes are paired with
-     * specific {@link BindingFactory} implementations, and used with parameters whose name reflects the binding
-     * prefix.
+     * specific {@link org.apache.tapestry5.services.BindingFactory} implementations, and used with parameters whose
+     * name reflects the binding prefix.
      *
      * @see org.apache.tapestry5.BindingConstants
      */

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractPropertyOutput.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractPropertyOutput.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractPropertyOutput.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractPropertyOutput.java Tue Jun 24 15:41:25 2008
@@ -42,14 +42,14 @@
     /**
      * Model for property displayed by the cell.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private PropertyModel model;
 
     /**
      * Resources used to search for block parameter overrides (this is normally the enclosing Grid component's
      * resources).
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private ComponentResources overrides;
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractTextField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractTextField.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractTextField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractTextField.java Tue Jun 24 15:41:25 2008
@@ -58,7 +58,7 @@
      * The object which will perform translation between server-side and client-side representations. If not specified,
      * a value will usually be generated based on the type of the value parameter.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private Translator<Object> translate;
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java Tue Jun 24 15:41:25 2008
@@ -75,7 +75,7 @@
     /**
      * Required parameter used to convert server-side objects (provided from the source) into client-side ids and back.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private PrimaryKeyEncoder encoder;
 
     @InjectComponent

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java Tue Jun 24 15:41:25 2008
@@ -43,7 +43,7 @@
      * The object to be rendered; if not explicitly bound, a default binding to a property whose name matches this
      * component's id will be used.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     @Property(write = false)
     private Object object;
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java Tue Jun 24 15:41:25 2008
@@ -59,7 +59,6 @@
      * value is ready to be read or updated. Often, the BeanEditForm can create the object as needed (assuming a public,
      * no arguments constructor).  The object property defaults to a property with the same name as the component id.
      */
-    @SuppressWarnings("unused")
     @Parameter(required = true)
     @Property
     private Object object;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ExceptionDisplay.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ExceptionDisplay.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ExceptionDisplay.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ExceptionDisplay.java Tue Jun 24 15:41:25 2008
@@ -36,7 +36,7 @@
     /**
      * Exception to report.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private Throwable exception;
 
     @Inject

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Label.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Label.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Label.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Label.java Tue Jun 24 15:41:25 2008
@@ -36,7 +36,7 @@
      * The for parameter is used to identify the {@link Field} linked to this label (it is named this way because it
      * results in the for attribute of the label element).
      */
-    @Parameter(name = "for", required = true, defaultPrefix = BindingConstants.COMPONENT)
+    @Parameter(name = "for", required = true, allowNull = false, defaultPrefix = BindingConstants.COMPONENT)
     private Field field;
 
     @Environmental

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java Tue Jun 24 15:41:25 2008
@@ -199,7 +199,7 @@
 
     /**
      * Defines the collection of values for the loop to iterate over. If not specified, defaults to a property of the
-     * container whose name
+     * container whose name matches the Loop cmponent's id.
      */
     @Parameter(required = true, principal = true)
     private Iterable<?> source;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Output.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Output.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Output.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Output.java Tue Jun 24 15:41:25 2008
@@ -41,7 +41,7 @@
     /**
      * The format to be applied to the object.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private Format format;
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PageLink.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PageLink.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PageLink.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PageLink.java Tue Jun 24 15:41:25 2008
@@ -37,7 +37,7 @@
     /**
      * The logical name of the page to link to.
      */
-    @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
+    @Parameter(required = true, allowNull = false, defaultPrefix = BindingConstants.LITERAL)
     private String page;
 
     @Inject

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Palette.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Palette.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Palette.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Palette.java Tue Jun 24 15:41:25 2008
@@ -166,13 +166,13 @@
     /**
      * Encoder used to translate between server-side objects and client-side strings.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private ValueEncoder<Object> encoder;
 
     /**
      * Model used to define the values and labels used when rendering.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private SelectModel model;
 
     /**
@@ -211,9 +211,9 @@
     private Asset select;
 
     /**
-     * The list of selected values from the {@link SelectModel}. This will be updated when the form is submitted. If the
-     * value for the parameter is null, a new list will be created, otherwise the existing list will be cleared. If
-     * unbound, defaults to a property of the container matching this component's id.
+     * The list of selected values from the {@link org.apache.tapestry5.SelectModel}. This will be updated when the form
+     * is submitted. If the value for the parameter is null, a new list will be created, otherwise the existing list
+     * will be cleared. If unbound, defaults to a property of the container matching this component's id.
      */
     @Parameter(required = true)
     private List<Object> selected;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java Tue Jun 24 15:41:25 2008
@@ -82,7 +82,7 @@
      * 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)
+    @Parameter(required = true, allowNull = false)
     private Object object;
 
     /**
@@ -102,7 +102,7 @@
     /**
      * The model that identifies the parameters to be edited, their order, and every other aspect.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private BeanModel model;
 
     @Inject

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java Tue Jun 24 15:41:25 2008
@@ -19,7 +19,10 @@
 import org.apache.tapestry5.annotations.Parameter;
 import org.apache.tapestry5.internal.TapestryInternalUtils;
 import org.apache.tapestry5.ioc.annotations.Inject;
-import org.apache.tapestry5.services.*;
+import org.apache.tapestry5.services.ComponentDefaultProvider;
+import org.apache.tapestry5.services.Environment;
+import org.apache.tapestry5.services.FormSupport;
+import org.apache.tapestry5.services.Request;
 
 public class RadioGroup implements Field
 {
@@ -45,12 +48,10 @@
     private String label;
 
     /**
-     * Allows a specific implementation of {@link ValueEncoder} to be supplied. This is used to create client-side
-     * string values for the different radio button values.
-     *
-     * @see ValueEncoderSource
+     * Allows a specific implementation of {@link org.apache.tapestry5.ValueEncoder} to be supplied. This is used to
+     * create client-side string values for the different radio button values.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private ValueEncoder encoder;
 
     @Inject

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java Tue Jun 24 15:41:25 2008
@@ -82,7 +82,7 @@
      * The model used to identify the option groups and options to be presented to the user. This can be generated
      * automatically for Enum types.
      */
-    @Parameter(required = true)
+    @Parameter(required = true, allowNull = false)
     private SelectModel model;
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/TriggerFragment.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/TriggerFragment.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/TriggerFragment.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/TriggerFragment.java Tue Jun 24 15:41:25 2008
@@ -38,7 +38,7 @@
     /**
      * The {@link org.apache.tapestry5.corelib.components.FormFragment} instance to make dynamically visible or hidden.
      */
-    @Parameter(required = true, defaultPrefix = BindingConstants.COMPONENT)
+    @Parameter(required = true, defaultPrefix = BindingConstants.COMPONENT, allowNull = false)
     private ClientElement fragment;
 
     @Environmental

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java Tue Jun 24 15:41:25 2008
@@ -99,21 +99,20 @@
         return componentClassName;
     }
 
-    public void addParameter(String name, boolean required, String defaultBindingPrefix)
+    public void addParameter(String name, boolean required, boolean allowNull, String defaultBindingPrefix)
     {
         Defense.notBlank(name, "name");
         Defense.notBlank(defaultBindingPrefix, "defaultBindingPrefix");
 
         // TODO: Check for conflict with base model
 
-        if (parameters == null) parameters = CollectionFactory.newCaseInsensitiveMap();
-        else
-        {
-            if (parameters.containsKey(name))
-                throw new IllegalArgumentException(ModelMessages.duplicateParameter(name, componentClassName));
-        }
+        if (parameters == null)
+            parameters = CollectionFactory.newCaseInsensitiveMap();
 
-        parameters.put(name, new ParameterModelImpl(name, required, defaultBindingPrefix));
+        if (parameters.containsKey(name))
+            throw new IllegalArgumentException(ModelMessages.duplicateParameter(name, componentClassName));
+
+        parameters.put(name, new ParameterModelImpl(name, required, allowNull, defaultBindingPrefix));
     }
 
     public ParameterModel getParameterModel(String parameterName)

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/ParameterModelImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/ParameterModelImpl.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/ParameterModelImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/ParameterModelImpl.java Tue Jun 24 15:41:25 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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,12 +22,15 @@
 
     private final boolean required;
 
+    private final boolean allowNull;
+
     private final String defaultBindingPrefix;
 
-    public ParameterModelImpl(String name, boolean required, String defaultBindingPrefix)
+    public ParameterModelImpl(String name, boolean required, boolean allowNull, String defaultBindingPrefix)
     {
         this.name = name;
         this.required = required;
+        this.allowNull = allowNull;
         this.defaultBindingPrefix = defaultBindingPrefix;
     }
 
@@ -45,4 +48,9 @@
     {
         return defaultBindingPrefix;
     }
+
+    public boolean isAllowNull()
+    {
+        return allowNull;
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java Tue Jun 24 15:41:25 2008
@@ -26,6 +26,7 @@
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 import org.apache.tapestry5.model.ComponentModel;
+import org.apache.tapestry5.model.ParameterModel;
 import org.apache.tapestry5.runtime.Component;
 import org.apache.tapestry5.runtime.PageLifecycleListener;
 import org.apache.tapestry5.runtime.RenderQueue;
@@ -228,6 +229,7 @@
     public <T> T readParameter(String parameterName, Class<T> expectedType)
     {
         Binding b = getBinding(parameterName);
+        T result;
 
         try
         {
@@ -236,15 +238,31 @@
 
             Object boundValue = b.get();
 
-            return pageResources.coerce(boundValue, expectedType);
+            result = pageResources.coerce(boundValue, expectedType);
         }
         catch (Exception ex)
         {
             throw new TapestryException(StructureMessages.getParameterFailure(parameterName, getCompleteId(), ex), b,
                                         ex);
         }
+
+        if (result == null && !isAllowNull(parameterName))
+            throw new TapestryException(String.format(
+                    "Parameter '%s' of component %s is bound to null. This parameter is not allowed to be null.",
+                    parameterName,
+                    getCompleteId()), b, null);
+
+        return result;
+    }
+
+    private boolean isAllowNull(String parameterName)
+    {
+        ParameterModel parameterModel = getComponentModel().getParameterModel(parameterName);
+
+        return parameterModel == null ? true : parameterModel.isAllowNull();
     }
 
+
     public Object readParameter(String parameterName, String desiredTypeName)
     {
         Class parameterType = pageResources.toClass(desiredTypeName);

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java Tue Jun 24 15:41:25 2008
@@ -78,7 +78,7 @@
 
         String parameterName = getParameterName(name, annotation.name());
 
-        model.addParameter(parameterName, annotation.required(), annotation.defaultPrefix());
+        model.addParameter(parameterName, annotation.required(), annotation.allowNull(), annotation.defaultPrefix());
 
         String type = transformation.getFieldType(name);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java Tue Jun 24 15:41:25 2008
@@ -30,11 +30,12 @@
      *
      * @param name                 new, unique name for the parameter
      * @param required             if true, the parameter must be bound
-     * @param defaultBindingPrefix the default binding prefix for this parameter
-     * @throws IllegalArgumentException if a parameter with the given name has already been defined for this model
+     * @param allowNull            if true, then parameter may be bound to null, if false a null check will be added
+     * @param defaultBindingPrefix the default binding prefix for this parameter @throws IllegalArgumentException if a
+     *                             parameter with the given name has already been defined for this model
      * @see Parameter
      */
-    void addParameter(String name, boolean required, String defaultBindingPrefix);
+    void addParameter(String name, boolean required, boolean allowNull, String defaultBindingPrefix);
 
     /**
      * Defines a new embedded component.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ParameterModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ParameterModel.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ParameterModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ParameterModel.java Tue Jun 24 15:41:25 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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.
@@ -34,6 +34,11 @@
     boolean isRequired();
 
     /**
+     * If true, then no check is needed. If false, then the bound value must not be null.
+     */
+    boolean isAllowNull();
+
+    /**
      * The default binding prefix for the parameter, usually "prop".
      */
     String getDefaultBindingPrefix();

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullParameterDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullParameterDemo.tml?rev=671374&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullParameterDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullParameterDemo.tml Tue Jun 24 15:41:25 2008
@@ -0,0 +1,6 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:beandisplay object="null"/>
+
+</html>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java Tue Jun 24 15:41:25 2008
@@ -2079,4 +2079,17 @@
         // As usual, Selenium is fighting me in terms of extracting data, so the above check just ensures
         // we made it past the form submit without error.
     }
+
+    /**
+     * TAPESTRY-2476
+     */
+    @Test
+    public void null_parameter_when_not_allowed()
+    {
+        start("Null Parameter Demo");
+
+        assertTextPresent(
+                "Parameter 'object' of component NullParameterDemo:beandisplay is bound to null.");
+    }
+
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NullParameterDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NullParameterDemo.java?rev=671374&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NullParameterDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NullParameterDemo.java Tue Jun 24 15:41:25 2008
@@ -0,0 +1,19 @@
+// Copyright 2008 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.tapestry5.integration.app1.pages;
+
+public class NullParameterDemo
+{
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java Tue Jun 24 15:41:25 2008
@@ -62,6 +62,8 @@
 
     private static final List<Item> ITEMS = CollectionFactory.newList(
 
+            new Item("NullParameterDemo", "Null Parameter Demo", "Binding a not-null parameter to null."),
+
             new Item("nestedbeaneditor", "Nested BeanEditor",
                      "BeanEditor as override for property editor in BeanEditForm"),
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java Tue Jun 24 15:41:25 2008
@@ -70,7 +70,7 @@
 
         String parameterName = "value";
 
-        model.addParameter(parameterName, true, BindingConstants.PROP);
+        model.addParameter(parameterName, true, true, BindingConstants.PROP);
 
         ParameterModel pm = model.getParameterModel(parameterName);
 
@@ -82,7 +82,7 @@
 
         // Verify that the binding prefix is actually stored:
 
-        model.addParameter("fred", true, "flint");
+        model.addParameter("fred", true, true, "flint");
 
         // Checks that parameter names are case insensitive
 
@@ -101,9 +101,9 @@
 
         MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
 
-        model.addParameter("fred", true, BindingConstants.PROP);
-        model.addParameter("wilma", true, BindingConstants.PROP);
-        model.addParameter("barney", true, BindingConstants.PROP);
+        model.addParameter("fred", true, true, BindingConstants.PROP);
+        model.addParameter("wilma", true, true, BindingConstants.PROP);
+        model.addParameter("barney", true, true, BindingConstants.PROP);
 
         assertEquals(model.getDeclaredParameterNames(), Arrays.asList("barney", "fred", "wilma"));
 
@@ -124,9 +124,9 @@
 
         MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
 
-        model.addParameter("fred", true, BindingConstants.PROP);
-        model.addParameter("wilma", true, BindingConstants.PROP);
-        model.addParameter("barney", true, BindingConstants.PROP);
+        model.addParameter("fred", true, true, BindingConstants.PROP);
+        model.addParameter("wilma", true, true, BindingConstants.PROP);
+        model.addParameter("barney", true, true, BindingConstants.PROP);
 
         assertEquals(model.getDeclaredParameterNames(), Arrays.asList("barney", "fred", "wilma"));
         assertEquals(model.getParameterNames(), Arrays.asList("barney", "betty", "fred", "wilma"));
@@ -144,13 +144,13 @@
 
         MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
 
-        model.addParameter("fred", true, BindingConstants.PROP);
+        model.addParameter("fred", true, true, BindingConstants.PROP);
 
         try
         {
             // This also helps check that the comparison is caseless!
 
-            model.addParameter("Fred", true, BindingConstants.PROP);
+            model.addParameter("Fred", true, true, BindingConstants.PROP);
             unreachable();
         }
         catch (IllegalArgumentException ex)
@@ -186,7 +186,7 @@
         replay();
 
         MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
-        model.addParameter("fred", true, BindingConstants.PROP);
+        model.addParameter("fred", true, true, BindingConstants.PROP);
 
         assertNull(model.getParameterModel("barney"));
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ParameterWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ParameterWorkerTest.java?rev=671374&r1=671373&r2=671374&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ParameterWorkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ParameterWorkerTest.java Tue Jun 24 15:41:25 2008
@@ -466,7 +466,7 @@
 
         MutableComponentModel model = mockMutableComponentModel(logger);
 
-        model.addParameter("value", false, BindingConstants.PROP);
+        model.addParameter("value", false, true, BindingConstants.PROP);
 
         Runnable phaseTwoTraining = new Runnable()
         {
@@ -511,7 +511,7 @@
 
         MutableComponentModel model = mockMutableComponentModel(logger);
 
-        model.addParameter("value", false, BindingConstants.PROP);
+        model.addParameter("value", false, true, BindingConstants.PROP);
 
         Runnable phaseTwoTraining = new Runnable()
         {
@@ -563,11 +563,11 @@
         final Logger logger = mockLogger();
         MutableComponentModel model = mockMutableComponentModel(logger);
 
-        model.addParameter("invariantObject", false, BindingConstants.PROP);
-        model.addParameter("invariantPrimitive", false, BindingConstants.PROP);
-        model.addParameter("object", false, BindingConstants.PROP);
-        model.addParameter("primitive", true, BindingConstants.PROP);
-        model.addParameter("uncached", false, BindingConstants.LITERAL);
+        model.addParameter("invariantObject", false, true, BindingConstants.PROP);
+        model.addParameter("invariantPrimitive", false, true, BindingConstants.PROP);
+        model.addParameter("object", false, true, BindingConstants.PROP);
+        model.addParameter("primitive", true, true, BindingConstants.PROP);
+        model.addParameter("uncached", false, true, BindingConstants.LITERAL);
 
 
         Runnable phaseTwoTraining = new Runnable()