Reputation: 6656
I'm implementing a JSF component and need to conditionally add some attributes. This question is similar to a previous JSF: p:dataTable with f:attribute results in "argument type mismatch" error, but with a completely different error message, so I raised a new question.
<composite:interface>
<composite:attribute name="filter" required="false" default="false"
type="java.lang.Boolean"/>
<composite:attribute name="rows" required="false" default="15"
type="java.lang.Integer"/>
...
</composite:interface>
<composite:implementation>
<p:dataTable ivar="p" value="#{cc.attrs.dm}">
<c:if test="#{cc.attrs.filter}">
<f:attribute name="paginator" value="#{true}"/>
<f:attribute name="rows" value="#{cc.attrs.rows}"/>
</c:if>
...
<p:dataTable>
</composite:implementation>
This results in an error java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
. Even if I manually set this, I get errors:
<f:attribute name="rows" value="15"/> ... argument type mismatch
<f:attribute name="rows" value="#{15}"/> ... java.lang.Long cannot be cast
to java.lang.Integer
If I add the attribute directly, there is no exception and the correct number of rows is diplayed:
<p:dataTable var="p" value="#{cc.attrs.dm}" rows="#{cc.attrs.rows}">
Upvotes: 4
Views: 2688
Reputation: 1109855
This is indeed an unfortunate corner case with numbers in EL and composite component attributes. There's no solution for this. The type information is not available in #{cc.attrs}
when used in <f:attribute>
and thus treated as String
. The #{15}
cannot be represented as an integer in EL either, all numbers are always implicitly treated as Long
when the type information is absent. The ClassCastException
can be prevented by using a tag file instead of a composite component.
Your best bet is doing the check in the actual rows
attribute itself.
<p:dataTable ... rows="#{cc.attrs.filter ? cc.attrs.rows : null}">
Upvotes: 3