5

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 ! :)

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
jruillier
  • 365
  • 4
  • 16

2 Answers2

4

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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

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.

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
  • This would imply that you need to add a getter to the interface/abstract class everytime whenever you create a new implementation of `Person`. Not really useful. – BalusC Nov 19 '10 at 19:27
  • boolean attribute can changed to any other. but i agree, not the most beatiful solution. – Vladimir Ivanov Nov 19 '10 at 20:08