You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by "Geoff Callender (JIRA)" <de...@tapestry.apache.org> on 2007/11/24 02:09:43 UTC

[jira] Created: (TAPESTRY-1928) Coercion from null to Boolean yields false instead of null

Coercion from null to Boolean yields false instead of null
----------------------------------------------------------

                 Key: TAPESTRY-1928
                 URL: https://issues.apache.org/jira/browse/TAPESTRY-1928
             Project: Tapestry
          Issue Type: Bug
          Components: tapestry-ioc
    Affects Versions: 5.0.6
            Reporter: Geoff Callender


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).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


[jira] Commented: (TAPESTRY-1928) Coercion from null to Boolean yields false instead of null

Posted by "Howard M. Lewis Ship (JIRA)" <de...@tapestry.apache.org>.
    [ https://issues.apache.org/jira/browse/TAPESTRY-1928?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12546957 ] 

Howard M. Lewis Ship commented on TAPESTRY-1928:
------------------------------------------------

I think we're seeing a bigger issue here and it really related to the TextField and Select components and not to the TypeCoercer service.    The question is how these components should handle blanks/nulls.

Workaround: don't use Booleans, create a ThreeState enum with values ON, OFF, UNKNOWN.

> Coercion from null to Boolean yields false instead of null
> ----------------------------------------------------------
>
>                 Key: TAPESTRY-1928
>                 URL: https://issues.apache.org/jira/browse/TAPESTRY-1928
>             Project: Tapestry
>          Issue Type: Bug
>          Components: tapestry-ioc
>    Affects Versions: 5.0.6
>            Reporter: Geoff Callender
>
> 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).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


[jira] Commented: (TAPESTRY-1928) Coercion from null to Boolean yields false instead of null

Posted by "Howard M. Lewis Ship (JIRA)" <de...@tapestry.apache.org>.
    [ https://issues.apache.org/jira/browse/TAPESTRY-1928?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12553814 ] 

Howard M. Lewis Ship commented on TAPESTRY-1928:
------------------------------------------------

This is predicated on the idea that the best way to represent a yes/no/maybe is with a Boolean, and I disagree on that.  Nulls are a dangerous thing that should be avoided when possible.  I think that null handling is a complex issue and not one size fits all and I'm noodling about that ... I suspect that there will be a new parameter on most fields to specify how to handle nulls.  Some of the other code in 5.0.7 (the new events for printing, parsing and validating) may also be useful for these cases.



> Coercion from null to Boolean yields false instead of null
> ----------------------------------------------------------
>
>                 Key: TAPESTRY-1928
>                 URL: https://issues.apache.org/jira/browse/TAPESTRY-1928
>             Project: Tapestry
>          Issue Type: Bug
>          Components: tapestry-ioc
>    Affects Versions: 5.0.6
>            Reporter: Geoff Callender
>
> 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).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


[jira] Updated: (TAPESTRY-1928) Coercion from null to Boolean yields false instead of null

Posted by "Geoff Callender (JIRA)" <de...@tapestry.apache.org>.
     [ https://issues.apache.org/jira/browse/TAPESTRY-1928?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Geoff Callender updated TAPESTRY-1928:
--------------------------------------

    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).

  was:
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).


> Coercion from null to Boolean yields false instead of null
> ----------------------------------------------------------
>
>                 Key: TAPESTRY-1928
>                 URL: https://issues.apache.org/jira/browse/TAPESTRY-1928
>             Project: Tapestry
>          Issue Type: Bug
>          Components: tapestry-ioc
>    Affects Versions: 5.0.6
>            Reporter: Geoff Callender
>
> 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).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


[jira] Commented: (TAPESTRY-1928) Coercion from null to Boolean yields false instead of null

Posted by "Geoff Callender (JIRA)" <de...@tapestry.apache.org>.
    [ https://issues.apache.org/jira/browse/TAPESTRY-1928?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12547082 ] 

Geoff Callender commented on TAPESTRY-1928:
-------------------------------------------

I stepped down into the code and I'm pretty sure the type coercer was the villain.  

Howard, I'm not sure if I'm interpreting your comment correctly - are you agreeing that the behaviour is incorrect?

The workaround is OK for page fields - define them as ThreeState or similar - but I should point out to the unwary that it means you can't work directly on a Boolean in a domain entity, eg.

   <select t:id="active" t:type="Select" value="policyHolder.smoker" model="smokerModel" encoder="booleanValueEncoder"/> 

It wouldn't matter what encoder you put on it, the type coercer would treat policyHolder.smoker like a boolean instead of a Boolean.  Unless I've interpreted this problem wrongly!



> Coercion from null to Boolean yields false instead of null
> ----------------------------------------------------------
>
>                 Key: TAPESTRY-1928
>                 URL: https://issues.apache.org/jira/browse/TAPESTRY-1928
>             Project: Tapestry
>          Issue Type: Bug
>          Components: tapestry-ioc
>    Affects Versions: 5.0.6
>            Reporter: Geoff Callender
>
> 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).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


[jira] Closed: (TAPESTRY-1928) Coercion from null to Boolean yields false instead of null

Posted by "Howard M. Lewis Ship (JIRA)" <de...@tapestry.apache.org>.
     [ https://issues.apache.org/jira/browse/TAPESTRY-1928?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Howard M. Lewis Ship closed TAPESTRY-1928.
------------------------------------------

    Resolution: Invalid
      Assignee: Howard M. Lewis Ship

Again, this is desired, expected behavior.  And, again, I think we need to revisit null handling to control more explicitly how nulls are treated when rendering and when submitting.

> Coercion from null to Boolean yields false instead of null
> ----------------------------------------------------------
>
>                 Key: TAPESTRY-1928
>                 URL: https://issues.apache.org/jira/browse/TAPESTRY-1928
>             Project: Tapestry
>          Issue Type: Bug
>          Components: tapestry-ioc
>    Affects Versions: 5.0.6
>            Reporter: Geoff Callender
>            Assignee: Howard M. Lewis Ship
>
> 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).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org