Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Invalid
-
5.0.6
-
None
-
None
Description
Boolean has 3 states: null, true, false, but the coercer coerces null to false. While this is correct behaviour for the boolean primitive (which has only 2 states), it is not correct for Boolean.
The same argument applies here as in TAPESTRY-1648 which dealt with null BigDecimal and Integer.
A practical consequence is that a BooleanValueEncoder that is 3-value aware becomes useless because the coercer will override it.
For example I combined a BooleanValueEncoder with Select to allow a user to choose between "", "true", and "false". But when the user chooses "", they unexpectedly get the same result as choosing "false". Here's the template code:
<select t:id="active" t:type="Select" value="active" model="actives" encoder="booleanValueEncoder"/>
Here's the relevant java:
static private final Boolean[] ACTIVES =
{ null, Boolean.TRUE, Boolean.FALSE };
static private final BooleanValueEncoder BOOLEAN_VALUE_ENCODER = new BooleanValueEncoder();
public Boolean getActive()
{ return _active; }public void setActive(Boolean active)
{ _active = active; }public Boolean[] getActives()
{ return ACTIVES; }public BooleanValueEncoder getBooleanValueEncoder()
{ return BOOLEAN_VALUE_ENCODER; }Here's a BooleanValueEncoder:
public class BooleanValueEncoder implements ValueEncoder<Boolean> {
public String toClient(Boolean value)
{ return value == null ? "" : value.toString(); }public Boolean toValue(String clientValue)
{ return clientValue.equals("") ? null : Boolean.valueOf(clientValue); }}
When the user chooses "", Tapestry calls setActive(Boolean.FALSE) instead of setActive(null).