1

So, I have a really annoying problem. I have created JSF custom component class:

@FacesComponent(value = Column.COMPONENT_TYPE)
public class Column extends HtmlColumn {
    ...
    protected enum attr {
        sort, search ...

I have setters and getters for all of the attr and they look like that:

public void setSort(java.lang.Object sort) {
    getStateHelper().put(attr.sort, sort);
}

public java.lang.Object getSort() {
    return getStateHelper().eval(attr.sort, null);
}

public void setSearch(java.lang.Object search) {
    getStateHelper().put(attr.search, search);
}

public java.lang.Object getSearch() {
    return getStateHelper().eval(attr.search, null);
}

Since I'm using StateHelper interface to set attribute values for a component, I'm expecting these setters should work with ValueExpression, but they're NOT.

Here is snippet of .xhtml where I'm trying to set sort and search attributes:

<e:dataTable id="datatable" var="entity" value="#{output.entities}"
    entryId="#{entity.id}">

        <e:column columnHeader="ID" sort="#{entity.id}" search="#{entity.id}">
            <h:outputText value="#{entity.id}"/>
        </e:column>

It works when I use non-value-expression values, but in this case is not an option.

Here's part of taglib if that helps:

<tag>
    <tag-name>column</tag-name>
    <component>
        <component-type>component.Column</component-type>
    </component>

    <attribute>
        <name>rendered</name>
        <required>false</required>
        <type>java.lang.Boolean</type>
    </attribute>

    <attribute>
        <name>visible</name>
        <required>false</required>
        <type>java.lang.Boolean</type>
    </attribute>

    <attribute>
        <name>sort</name>
        <required>false</required>
    </attribute>

    <attribute>
        <name>search</name>
        <required>false</required>
    </attribute>

    <attribute>
        <name>columnHeader</name>
        <required>false</required>
        <type>java.lang.String</type>
    </attribute>
    ...
</tag>

NOTE: we do not use primefaces or any other *faces library for dataTable and columns, because it's simply do not serve our needs.

Any thougths why my setters does not work and how to make it work ? Thanks.

Tiny
  • 27,221
  • 105
  • 339
  • 599
emilancius
  • 296
  • 1
  • 5
  • 15
  • This is technically a duplicate http://stackoverflow.com/q/11866981. In other words, it works as expected. But as your question implies that you're having other problems which seem to be caused by this, it's perhaps useful to tell what problems exactly you faced and why exactly you need those setters to be invoked. – BalusC Mar 25 '16 at 13:34

1 Answers1

2

Since BalusC pointed out that this behaviour is expected, I debugged my way to setValueExpression() method. So if you provide ValueExpression to an attribute, like i did in the question, setter should not be invoked (I thought it should be). Value Expression is handled by setValueExpression method.

The problem was that I was getting null (default evaluated value), when I invoked getSort() or getSearch() methods. So I edited my getters to something like this:

public java.lang.Object getSort() {
    Object sort = getStateHelper().eval(attr.sort, null);

    if (sort == null) {
        ValueExpression ve = getValueExpression("sort");

        if (ve != null) {
            ELContext context = FacesContext.getCurrentInstance().getELContext();
            sort = ve.getValue(context);
        }
    }

    return sort;
}

Now everything works just fine. But I have to point out that this behaviour (setter not invoking on provided value expression) is not really intuitive and might be confusing.

emilancius
  • 296
  • 1
  • 5
  • 15