Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle polymorphism with JSF2?

I need to display/edit polymorphic entities.

My abstract class is Person. My concrete classes are PhysicalPerson and MoralPerson

Each concrete class has its own custom attributes.

How can I use the appropriate display/edit (composite) component according to entity class ?

Thanks ! :)

like image 411
jruillier Avatar asked Nov 12 '10 15:11

jruillier


2 Answers

There is no such thing as instanceof in EL. You can however (ab)use Object#getClass() and access the getters of Class in EL as well. Then just determine the outcome in the component's rendered attribute.

<h:panelGroup rendered="#{entity.class.name == 'com.example.PhysicalPerson'}">
    <p>According to Class#getName(), this is a PhysicalPerson.</p>
</h:panelGroup>
<h:panelGroup rendered="#{entity.class.simpleName == 'MoralPerson'}">
    <p>According to Class#getSimpleName(), this is a MoralPerson.</p>
</h:panelGroup>

A custom EL function would be more clean however. Note that the above doesn't work on Tomcat 7 and clones due to extremely restrictive restrictions of allowed propertynames in EL. Java reserved literals such as class are not allowed anymore. You'd need #{entity['class'].name} and so on instead.

like image 127
BalusC Avatar answered Nov 10 '22 03:11

BalusC


Another way is to create an abstract method in a base class, which will return you some mark of what instance you have, and implement it in your subclasses, like this:

public abstract class Person {

public abstract boolean isPhysical();

}

public PhysicalPerson extends Person {

public boolean isPhysical() {
     return true;
}

}

and then in jsf:

<h:panelGroup rendered="#{entity.physical}">
    <p>this is a PhysicalPerson.</p>
</h:panelGroup>
<h:panelGroup rendered="#{ not entity.physical}">
    <p>this is a Moral Person.</p>
</h:panelGroup>

However the class checking approach is more universal.

like image 35
Vladimir Ivanov Avatar answered Nov 10 '22 03:11

Vladimir Ivanov