After developing a test case and trying to add this improvement, I realized that it's not possible to accomplish this in the way we intended.
For lazy loading cases, we simply pass the property name itself to the load method, so that the app developer can identify which column was filtered and/or sorted, since we can't do the filtering and sorting from our component code since the entire data set is not in memory. Thus, we allow developers to proceed in any way they want.
For example, if a column is defined like this:
<ace:column headerText="Artist" sortBy="#{track.artist}" filterBy="#{track.artist}"/>
We would pass the string 'artist' to the load() method of LazyDataModel as part of both the 'sortCriteria' and 'filters' objects. We do this by simply parsing the original expression string from the ValueExpression object and obtaining the property name. The problem described by this JIRA is that it's not possible to define columns using c:forEach, since the property names for sortBy and filterBy are incorrectly parsed/resolved. However, this seems not to be possible after all, as explained below.
In the test case I developed, I define a set of columns in this way:
<c:forEach var="col" items="#{tableBean.cols}">
<ace:column headerText="#{col.header}" sortBy="#{track[col.prop]}" filterBy="#{track[col.prop]}"/>
</c:forEach>
And in the backing bean I have this:
private List<Col> cols = null;
public List<Col> getCols() {
if (cols == null) {
cols = new ArrayList<Col>();
cols.add(new Col("Artist", "artist"));
cols.add(new Col("Album", "album"));
cols.add(new Col("Name", "name"));
cols.add(new Col("AMG", "AMGReview"));
cols.add(new Col("Pitchfork", "pitchforkReview"));
cols.add(new Col("iTunes", "iTunesSales"));
cols.add(new Col("Brick and Mortar", "bAndMSales"));
}
return cols;
}
public static class Col {
private String header;
private String prop;
public Col(String header, String prop) {
this.header = header;
this.prop = prop;
}
public String getHeader() {
return this.header;
}
public String getProp() {
return this.prop;
}
}
In other words, there's a "column model" class (Col) that is used to dynamically define columns by specifying a header name and a property name, for sorting and filtering purposes, using c:forEach.
The problem is that when using this approach, we cannot resolve the property names for sorting and filtering. With the current code, we simply pass a "prop]" string in all cases, because our parsing function doesn't account for dynamic EL expressions (or expressions containing the [] notation). Moreover, after trying to resolve these EL expressions properly, I found out that it's impossible; the returned value of evaluating such expression is always null. It seems to be due to the fact that the c:forEach variable ('col' in this case) is no longer in the ELContext object, since the c:forEach tag had already been processed to create those components. So, in this case, it's not possible to resolve the value of the 'col' variable. Besides that, there doesn't seem to be a way to partially evaluate a (dynamic) EL expression to obtain a new expression string that we could parse. Only the original expression string is available (in this case, '#{track[col.prop]}'). Also, using $ or # expressions makes no difference.
I also tried pushing and popping the column components to/from EL when trying to evaluate the expressions, and I also tried creating new custom value expressions and try to resolve a simpler expression involving the c:forEach variable, but none of that worked.
After developing a test case and trying to add this improvement, I realized that it's not possible to accomplish this in the way we intended.
For lazy loading cases, we simply pass the property name itself to the load method, so that the app developer can identify which column was filtered and/or sorted, since we can't do the filtering and sorting from our component code since the entire data set is not in memory. Thus, we allow developers to proceed in any way they want.
For example, if a column is defined like this:
<ace:column headerText="Artist" sortBy="#{track.artist}" filterBy="#{track.artist}"/>
We would pass the string 'artist' to the load() method of LazyDataModel as part of both the 'sortCriteria' and 'filters' objects. We do this by simply parsing the original expression string from the ValueExpression object and obtaining the property name. The problem described by this JIRA is that it's not possible to define columns using c:forEach, since the property names for sortBy and filterBy are incorrectly parsed/resolved. However, this seems not to be possible after all, as explained below.
In the test case I developed, I define a set of columns in this way:
And in the backing bean I have this:
In other words, there's a "column model" class (Col) that is used to dynamically define columns by specifying a header name and a property name, for sorting and filtering purposes, using c:forEach.
The problem is that when using this approach, we cannot resolve the property names for sorting and filtering. With the current code, we simply pass a "prop]" string in all cases, because our parsing function doesn't account for dynamic EL expressions (or expressions containing the [] notation). Moreover, after trying to resolve these EL expressions properly, I found out that it's impossible; the returned value of evaluating such expression is always null. It seems to be due to the fact that the c:forEach variable ('col' in this case) is no longer in the ELContext object, since the c:forEach tag had already been processed to create those components. So, in this case, it's not possible to resolve the value of the 'col' variable. Besides that, there doesn't seem to be a way to partially evaluate a (dynamic) EL expression to obtain a new expression string that we could parse. Only the original expression string is available (in this case, '#{track[col.prop]}'). Also, using $ or # expressions makes no difference.
I also tried pushing and popping the column components to/from EL when trying to evaluate the expressions, and I also tried creating new custom value expressions and try to resolve a simpler expression involving the c:forEach variable, but none of that worked.