Repository: tapestry-5
Updated Branches:
  refs/heads/master d29d6dc59 -> 5649174f0


TAP5-2030: Allow blank values to bypass value encoder and go directly to null, 
if enabled by annotation


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/5649174f
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/5649174f
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/5649174f

Branch: refs/heads/master
Commit: 5649174f0fc642bd01baf5dcc81958a48b636556
Parents: d29d6dc
Author: Howard M. Lewis Ship <hls...@apache.org>
Authored: Fri Aug 1 16:26:43 2014 -0700
Committer: Howard M. Lewis Ship <hls...@apache.org>
Committed: Fri Aug 1 16:26:43 2014 -0700

----------------------------------------------------------------------
 54_RELEASE_NOTES.md                             |  9 ++++-
 .../TypeCoercedValueEncoderFactory.java         | 11 ++++--
 .../internal/transform/OnEventWorker.java       | 32 ++++++++++-------
 .../src/test/app1/RequestParameterDemo.tml      |  3 ++
 .../integration/app1/RequestParameterTests.java | 10 ++++--
 .../app1/pages/RequestParameterDemo.java        | 37 ++++++++++++++------
 6 files changed, 74 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/5649174f/54_RELEASE_NOTES.md
----------------------------------------------------------------------
diff --git a/54_RELEASE_NOTES.md b/54_RELEASE_NOTES.md
index 9161e0a..00e3dcb 100644
--- a/54_RELEASE_NOTES.md
+++ b/54_RELEASE_NOTES.md
@@ -418,4 +418,11 @@ where desired.
 
 ## Java 1.6 required
 
-As of version 5.4, Tapestry requires Java 1.6 at least.
\ No newline at end of file
+As of version 5.4, Tapestry requires Java 1.6 at least.
+
+## ValueEncoder Changes
+
+The automatic ValueEncoder from String to any Number type, or ti Boolean have
+changed slightly. An empty input string is encoded to a null rather than being 
passed through
+the type coercer. This reflects the desire that a submitted value (in a URL or 
a form) that is blank
+is the same as no value: null.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/5649174f/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TypeCoercedValueEncoderFactory.java
----------------------------------------------------------------------
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TypeCoercedValueEncoderFactory.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TypeCoercedValueEncoderFactory.java
index bee075d..9d67d87 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TypeCoercedValueEncoderFactory.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TypeCoercedValueEncoderFactory.java
@@ -1,5 +1,3 @@
-// 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
@@ -15,6 +13,7 @@
 package org.apache.tapestry5.internal.services;
 
 import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.services.ValueEncoderFactory;
 
@@ -33,6 +32,10 @@ public class TypeCoercedValueEncoderFactory implements 
ValueEncoderFactory<Objec
 
     public ValueEncoder<Object> create(final Class<Object> type)
     {
+        final boolean blankToNull =
+                Boolean.class.isAssignableFrom(type) ||
+                Number.class.isAssignableFrom(type);
+
         return new ValueEncoder<Object>()
         {
             public String toClient(Object value)
@@ -42,6 +45,10 @@ public class TypeCoercedValueEncoderFactory implements 
ValueEncoderFactory<Objec
 
             public Object toValue(String clientValue)
             {
+                if (blankToNull && InternalUtils.isBlank(clientValue)) {
+                    return null;
+                }
+
                 return typeCoercer.coerce(clientValue, type);
             }
         };

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/5649174f/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
----------------------------------------------------------------------
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
index 9a4a92d..c640158 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
@@ -1,4 +1,3 @@
-// Copyright 2006-2013 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
@@ -432,35 +431,36 @@ public class OnEventWorker implements 
ComponentClassTransformWorker2
             {
                 try
                 {
-                    
+
                     Class parameterType = 
classCache.forName(parameterTypeName);
                     boolean isArray = parameterType.isArray();
-                    
+
                     if (isArray)
                     {
                         parameterType = parameterType.getComponentType();
                     }
-                    
+
                     ValueEncoder valueEncoder = 
valueEncoderSource.getValueEncoder(parameterType);
 
                     String parameterValue = 
request.getParameter(parameterName);
 
-                    if (!allowBlank && parameterValue == null)
+                    if (!allowBlank && InternalUtils.isBlank(parameterValue))
                         throw new RuntimeException(String.format(
                                 "The value for query parameter '%s' was blank, 
but a non-blank value is needed.",
                                 parameterName));
-                    
+
                     Object value;
 
-                    if (!isArray) {
-                        value = coerce(parameterName, parameterType, 
parameterValue, valueEncoder);
-                    }
-                    else {
+                    if (!isArray)
+                    {
+                        value = coerce(parameterName, parameterType, 
parameterValue, valueEncoder, allowBlank);
+                    } else
+                    {
                         String[] parameterValues = 
request.getParameters(parameterName);
                         Object[] array = (Object[]) 
Array.newInstance(parameterType, parameterValues.length);
                         for (int i = 0; i < parameterValues.length; i++)
                         {
-                            array[i] = coerce(parameterName, parameterType, 
parameterValues[i], valueEncoder);
+                            array[i] = coerce(parameterName, parameterType, 
parameterValues[i], valueEncoder, allowBlank);
                         }
                         value = array;
                     }
@@ -477,8 +477,16 @@ public class OnEventWorker implements 
ComponentClassTransformWorker2
             }
 
             private Object coerce(final String parameterName, Class 
parameterType,
-                    String parameterValue, ValueEncoder valueEncoder)
+                                  String parameterValue, ValueEncoder 
valueEncoder, boolean allowBlank)
             {
+
+                if (!allowBlank && InternalUtils.isBlank(parameterValue))
+                {
+                    throw new RuntimeException(String.format(
+                            "The value for query parameter '%s' was blank, but 
a non-blank value is needed.",
+                            parameterName));
+                }
+
                 Object value = valueEncoder.toValue(parameterValue);
 
                 if (parameterType.isPrimitive() && value == null)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/5649174f/tapestry-core/src/test/app1/RequestParameterDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/app1/RequestParameterDemo.tml 
b/tapestry-core/src/test/app1/RequestParameterDemo.tml
index 6d13f2e..683b9c4 100644
--- a/tapestry-core/src/test/app1/RequestParameterDemo.tml
+++ b/tapestry-core/src/test/app1/RequestParameterDemo.tml
@@ -31,5 +31,8 @@
     <li>
       <a href="${nullAllowedLink}">Null Allowed Link</a>
     </li>
+     <li>
+         <a href="${blankAllowedLink}">Blank Allowed Link</a>
+     </li>
   </ul>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/5649174f/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/RequestParameterTests.java
----------------------------------------------------------------------
diff --git 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/RequestParameterTests.java
 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/RequestParameterTests.java
index 0ac0193..f2b8457 100644
--- 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/RequestParameterTests.java
+++ 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/RequestParameterTests.java
@@ -1,5 +1,3 @@
-// Copyright 2010-2013 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
@@ -68,4 +66,12 @@ public class RequestParameterTests extends App1TestCase
                 
"org.apache.tapestry5.integration.app1.pages.RequestParameterDemo.onFrob(int)",
                 "Coercion of frodo to type java.lang.Integer");
     }
+
+    @Test
+    public void blank_allowed_for_wrapper_types_if_enabled() {
+        openLinks("RequestParameter Annotation Demo", "Blank Allowed Link");
+
+        assertText("id=current", "-1");
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/5649174f/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RequestParameterDemo.java
----------------------------------------------------------------------
diff --git 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RequestParameterDemo.java
 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RequestParameterDemo.java
index f7bd799..8e1184c 100644
--- 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RequestParameterDemo.java
+++ 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RequestParameterDemo.java
@@ -1,5 +1,3 @@
-// Copyright 2010 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
@@ -14,9 +12,6 @@
 
 package org.apache.tapestry5.integration.app1.pages;
 
-import java.util.Arrays;
-import java.util.List;
-
 import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.Link;
 import org.apache.tapestry5.annotations.Persist;
@@ -24,12 +19,15 @@ import org.apache.tapestry5.annotations.Property;
 import org.apache.tapestry5.annotations.RequestParameter;
 import org.apache.tapestry5.ioc.annotations.Inject;
 
+import java.util.Arrays;
+import java.util.List;
+
 public class RequestParameterDemo
 {
     private static final String PARAMETER_NAME = "gnip";
 
     private static final String EVENT_NAME = "frob";
-    
+
     private static final String MULTIVALUED_PARAMETER_EVENT_NAME = "frobFrob";
 
     @Property
@@ -50,7 +48,7 @@ public class RequestParameterDemo
 
         return link;
     }
-    
+
     public Link getMultivaluedQueryParameterLink()
     {
         Link link = 
resources.createEventLink(MULTIVALUED_PARAMETER_EVENT_NAME);
@@ -69,6 +67,11 @@ public class RequestParameterDemo
         return link;
     }
 
+    public Link getBlankAllowedLink()
+    {
+        return 
resources.createEventLink("emptyStringAllowed").addParameter(PARAMETER_NAME, 
"");
+    }
+
     public Link getNullLink()
     {
         return resources.createEventLink(EVENT_NAME);
@@ -80,20 +83,32 @@ public class RequestParameterDemo
     }
 
     void onFrob(@RequestParameter(PARAMETER_NAME)
-    int value)
+                int value)
     {
         this.value = value;
     }
-    
+
     void onFrobFrob(@RequestParameter(PARAMETER_NAME)
-    Integer[] values)
+                    Integer[] values)
     {
         this.values = Arrays.asList(values);
     }
 
     void onFrobNullAllowed(@RequestParameter(value = PARAMETER_NAME, 
allowBlank = true)
-    int value)
+                           int value)
     {
         this.value = value;
     }
+
+    void onEmptyStringAllowed(@RequestParameter(value = PARAMETER_NAME, 
allowBlank = true) Integer value)
+    {
+        if (value == null)
+        {
+            this.value = -1;
+        } else
+        {
+            this.value = value.intValue();
+        }
+
+    }
 }

Reply via email to