TAP5-1760: coerce the Radio value to the correct type if it doesn't match the RadioGroup's value's type
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java
index c7c2d06..cd594c1 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/RadioGroup.java
@@ -20,6 +20,7 @@
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.services.ComponentDefaultProvider;
import org.apache.tapestry5.services.Environment;
import org.apache.tapestry5.services.FormSupport;
@@ -28,7 +29,7 @@
/**
* A wrapper component around some number of {@link Radio} components, used to organize the selection and define the
* property to be edited. Examples of its use are in the {@link Radio} documentation.
- *
+ *
* @tapestrydoc
*/
@Events(EventConstants.VALIDATE)
@@ -68,7 +69,7 @@
* selected Radio componnent's "value" parameter) into unique client-side
* strings (typically IDs) and back. Note: this parameter may be OMITTED if
* Tapestry is configured to provide a ValueEncoder automatically for the
- * type of property bound to the "value" parameter.
+ * type of property bound to the "value" parameter.
*/
@Parameter(required = true, allowNull = false)
private ValueEncoder encoder;
@@ -96,6 +97,9 @@
@Inject
private Request request;
+ @Inject
+ private TypeCoercer typeCoercer;
+
@Environmental
private ValidationTracker tracker;
@@ -195,6 +199,8 @@
final String selectedValue = submittedValue != null ? submittedValue : encoder.toClient(value);
+ final Class<?> boundType = resources.getBoundType("value");
+
environment.push(RadioContainer.class, new RadioContainer()
{
public String getControlName()
@@ -207,17 +213,24 @@
return disabled;
}
+ private Object getObjectAsCorrectType(Object val)
+ {
+ if (val != null && boundType != null && !boundType.isAssignableFrom(val.getClass()))
+ {
+ return typeCoercer.coerce(val, boundType);
+ }
+ return val;
+ }
+
@SuppressWarnings("unchecked")
public String toClient(Object value)
{
- // TODO: Ensure that value is of the expected type?
-
- return encoder.toClient(value);
+ return encoder.toClient(getObjectAsCorrectType(value));
}
public boolean isSelected(Object value)
{
- return TapestryInternalUtils.isEqual(encoder.toClient(value), selectedValue);
+ return TapestryInternalUtils.isEqual(encoder.toClient(getObjectAsCorrectType(value)), selectedValue);
}
});
@@ -251,7 +264,7 @@
* Returns null; the radio group does not render as a tag and so doesn't have an id to share. RadioGroup implements
* {@link org.apache.tapestry5.Field} only so it can interact with the
* {@link org.apache.tapestry5.ValidationTracker}.
- *
+ *
* @return null
*/
public String getClientId()
diff --git a/tapestry-core/src/test/app1/RadioDemo.tml b/tapestry-core/src/test/app1/RadioDemo.tml
index 5ffe75e..f0a936f 100644
--- a/tapestry-core/src/test/app1/RadioDemo.tml
+++ b/tapestry-core/src/test/app1/RadioDemo.tml
@@ -40,6 +40,19 @@
</div>
</div>
</t:radiogroup>
+
+ <!-- see TAP5-1760 -->
+ <t:radiogroup t:id="department2" t:validate="required">
+ <div class="well">
+ <div class="radio">
+ <label>
+ <t:radio t:id="radio3" value="literal:ACCOUNTING"/>
+ Accounting
+ </label>
+ </div>
+ </div>
+
+ </t:radiogroup>
<input class="btn btn-primary" type="submit" value="Update"/>
<t:actionlink class="btn btn-default" t:id="reset">reset</t:actionlink>
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RadioDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RadioDemo.java
index ecdeffe..58bfa60 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RadioDemo.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/RadioDemo.java
@@ -16,6 +16,7 @@
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.integration.app1.data.Department;
import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.ioc.Messages;
@@ -25,6 +26,10 @@
{
@Persist
private Department department;
+
+ @Persist
+ @Property
+ private Department department2;
@Persist
private String position;