I have an object (Ticket) that has a list of other objects (Message). The message is abstract and has several subclasses - for example, EditMessage, CreationMessage, etc. So the Ticket object contains a mixture of these messages, and they are ordered by the time they were created.
Now I want to display all these messages on the Facelets page, and I need to display the values of the fields specific to this type of message: for example, the editedField in EditMessage, userName in CreationMessage, ...
The most obvious way seems to be h: dataTable:
<h:dataTable value="#{ticketController.ticket.messages}" var="msg" >
// determine type of message, cast, and use <c:if> to output needed values
</h:dataTable>
The problem is that the Facelets expression language does not have "instanceof" and casts. As far as I can tell, this can be solved with some ugly rounding to a managed bean, defining a message type in standard Java, returning a message of the desired type, etc.
Is there a better, more clear and concise way to do this?
<h / "> <B> Solution
My main problem was the <c: if> tag. It turned out to be a JSTL tag, so it has a slightly different rendering life cycle. Instead, I now use <h: panelGroup> and its "rendered" attribute.
Some codes:
<h:dataTable value="#{ticketController.ticket.messages}" var="msg" >
<h:column>
<h:panelGroup rendered="#{msg.class.name == 'org.rogach.tsnt.TextMessage'}" >
<h:outputText value="msg.text" />
</h:panelGroup>
<h:outputText value="#{msg.creationTime}" />
</h:column>
</h:dataTable>
And no throw is ever needed.