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

Reply via email to