myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "l.penet@senat.fr" <l.pe...@senat.fr>
Subject null Long values displayed as 0
Date Wed, 16 Jul 2014 17:00:41 GMT
Dear all,

I just finished to struggle with the display of nullable Long or Integer 
values. I am using Primefaces 5.0.1 / MyFaces 2.2.4 / OpenWebBeans 1.2.2 
/ Tomcat 7.0.39.

Those values are the result of the evaluation of EL expressions that I 
create with the following function :

     public static ValueExpression createValueExpression(String 
expression, Class clazz) {
             FacesContext fc = FacesContext.getCurrentInstance();
             ELContext elContext = fc.getELContext();
             FacesELContext felContext = (FacesELContext)fc.getELContext();
             SenatFunctionMapper sfm = SenatFunctionMapper.getInstance();
             felContext.setFunctionMapper(sfm);
             ExpressionFactory expFactory = 
fc.getApplication().getExpressionFactory();
             ValueExpression ret = null;
             if(clazz==null) {
                 clazz = Object.class;
             }
             try {
                 ret = expFactory.createValueExpression(elContext, 
expression, clazz);
             } catch (ELException ex) {
                 log.fatal("Erreur de compilation de l'expression EL : 
'" + expression + "'", ex);
             }
             return ret;
         }

Until now, I created those value expressions with the real expected 
class as the third parameter of ExpressionFactory#createValueExpression. 
The name of this parameter is "expectedType", so it seems logical to me 
to provide the best information I had. So, I provided 
java.lang.Integer.class or java.lang.Long.class, etc.

But when I do that, null values are displayed as 0, either with 
h:inputText (standard MyFaces control) or p:inputText (PrimeFaces version).

The reason being that

org.apache.el.ValueExpressionImpl#getValue

is implemented the following way

     @Override
     public Object getValue(ELContext context) throws 
PropertyNotFoundException,
             ELException {
         EvaluationContext ctx = new EvaluationContext(context, 
this.fnMapper,
                 this.varMapper);
         Object value = this.getNode().getValue(ctx);
         if (this.expectedType != null) {
             return ELSupport.coerceToType(value, this.expectedType);
         }
         return value;
     }

and that ELSupport.coerceToType of a Long or Integer null value is 
defined as... 0

As those type are numeric, coerceToType calls coerceToNumber, which 
starts with :

     public static final Number coerceToNumber(final Object obj,
             final Class<?> type) throws ELException {
         if (obj == null || "".equals(obj)) {
             return coerceToNumber(ZERO, type);
         }
...
     }

thus, the ZERO value.

For the time being, I solved my Ā«problemĀ» by passing a null third 
parameter to ExpressionFactory#createValueExpression. It works. It has 
no apparent drawbacks. But I don't get the logic of it. Should'nt 
ELSupport#coerceToNumber handles this differently ?

Thanks in advance for your explanations,

Ludovic
|
| AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT.
|


Mime
View raw message