Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > JSF feeds a Set<String> into a Set<Foo>

Reply
Thread Tools

JSF feeds a Set<String> into a Set<Foo>

 
 
Elegie
Guest
Posts: n/a
 
      06-02-2011
Hello,

I am currently learning JSF2.0, and have just encountered a behavior I
do not understand. Basically, I have a test case (see below) where I
have a typed set (Set<Foo>) whose content, automatically populated by
JSF, is made of strings (Set<String>). This should not even compile, yet
this runs. What am I missing?

To provide you with a bit of context, my business scenario is as
follows. I have a web form which will be used to create/update users in
my application, and to assign the user with relevant roles. All roles
will be displayed as checkboxes, the checked checkboxes will represent
the roles that the user possesses. The form will be linked to a backing
bean, whose properties will be automatically populated, using EL
expressions. The bean itself will extend a JPA entity (User), which will
then be copied into a regular User object, then sent to some EJB3.1 for
processing (controls and persistence). Having the backing bean extend
the JPA entity is a simple way, for me, to automatically provide
getters/setters to it.

I could probably achieve my goal using the ui-repeat tag, but it seems
that the selectManyCheckBox tag does precisely that, hence my attempt.
While setting up the scenario though, I encountered a problem with the
way JSF would feed my backing bean - putting String objects where I
expect Role objects. I have trimmed down the problem to the following
test case.

The test case is made of three files:
- an XHTML file, with h:selectManyCheckbox, f:selectItems and
h:commandButton,
- a backing bean whose methods are called by the JSF tags, using EL
expressions. In the application, the bean extends the User class, but
not in the test case,
- a Foo class, with a name, and overriden Object methods (toString,
equals and hashCode). In the application, the Foo class is a Role.

I use JBoss Application Server 6.0.0, and my java -version yields
1.6.0_24-b07.

Since I'm learning JSF, I am trying various approaches while exploring
the technology. After all, the more issues I am faced with, the faster I
progress. The test case could therefore look a bit off to experts, and I
apologize in advance if this is the case. I welcome any comment. Also,
if I am in the wrong group, could you redirect me to the appropriate
group? Thank you.


Kind regards,
Elegie.


===
XHTML file
===

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
<title>Test</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
</h:head>

<h:body>
<div>
<h:form>
<h:selectManyCheckbox
value="#{testCase.foos}"
layout="pageDirection">
<f:selectItems
value="#{testCase.allFoos}"
var="f"
itemLabel="#{f.name}" />
</h:selectManyCheckbox>
<h:commandButton value="Test" action="#{testCase.doTest}" />
</h:form>
</div>
</h:body>
</html>



===
Backing bean - TestCase.java
===

package test ;

import java.io.Serializable;
import java.util.ArrayList ;
import java.util.LinkedHashSet ;
import java.util.List ;
import java.util.Set ;
import javax.faces.bean.ManagedBean ;
import javax.faces.bean.RequestScoped ;

@ManagedBean
@RequestScoped
public class TestCase implements Serializable {

private static final long serialVersionUID = 1L ;

private Set<Foo> myFoos ;

public Set<Foo> getFoos() {
this.myFoos = new LinkedHashSet<Foo>() ;
this.myFoos.add(new Foo("Foo1")) ;
this.myFoos.add(new Foo("Foo3")) ;
this.myFoos.add(new Foo("Foo5")) ;
return this.myFoos ;
}

public void setFoos(Set<Foo> foos) {
this.myFoos = foos ;
}

public List<Foo> getAllFoos() {
ArrayList<Foo> myFoos = new ArrayList<Foo>() ;
myFoos.add(new Foo("Foo1")) ;
myFoos.add(new Foo("Foo2")) ;
myFoos.add(new Foo("Foo3")) ;
myFoos.add(new Foo("Foo4")) ;
myFoos.add(new Foo("Foo5")) ;
myFoos.add(new Foo("Foo6")) ;
return myFoos ;
}

public Object doTest() {
System.out.println("myFoos contains " + this.myFoos) ;
if (!this.myFoos.isEmpty()) {
Object[] content = this.myFoos.toArray() ;
Object candidate = content[0] ;

// Candidate is not a Foo, but a String!
System.out.println("Nice to meet you. I am " + candidate) ;
System.out.println("Am I a foo? " + (candidate instanceof Foo)) ;
System.out.println("What am I? " + (candidate.getClass())) ;

// A real Foo should behave like a Foo!
Foo test = new Foo("fooTest") ;
Object fooTest = (Object) test ;
System.out.println("Nice to meet you. I am " + fooTest) ;
System.out.println("Am I a foo? " + (fooTest instanceof Foo)) ;
System.out.println("What am I? " + (fooTest.getClass())) ;
}
return new String("") ;
}
}



===
POJO - Foo.java
===

package test ;

public class Foo {
private String name ;

public String getName() {
return this.name ;
}

public void setName(String name) {
this.name = name ;
}

public Foo(String name) {
this.name = name ;
}

@Override
public boolean equals(Object o) {
if (o==this) return true ;
if (!(o instanceof Foo)) return false ;
Foo f = (Foo) o ;
return f.name == this.name ;
}

@Override
public int hashCode() {
return this.name.hashCode() ;
}

@Override
public String toString() {
return "I'm a Foo, and my name is " + this.name ;
}
}

 
Reply With Quote
 
 
 
 
Stanimir Stamenkov
Guest
Posts: n/a
 
      06-04-2011
Thu, 02 Jun 2011 21:32:09 +0200, /Elegie/:

> I am currently learning JSF2.0, and have just encountered a behavior
> I do not understand. Basically, I have a test case (see below) where
> I have a typed set (Set<Foo>) whose content, automatically populated
> by JSF, is made of strings (Set<String>). This should not even
> compile, yet this runs. What am I missing?
> (...)


You're missing the generics type erasure [1]. JSF doesn't have the
generics type information at run time. A related (but not the same)
issue [2] has been brought to the JSF Dev mailing list.

To resolve the issue you could attach converter to your input
component explicitly, e.g.:

<h:selectManyCheckbox
value="#{testCase.foos}"
converter="#{...}">
...
</h:selectManyCheckbox>

where you bind the converter instance directly, or:

<h:selectManyCheckbox
value="#{testCase.foos}">
<f:converter converterId="..." />
...
</h:selectManyCheckbox>

where you provide a registered converter ID. With JSF 1.2 one
register a custom converter by adding such an element in the
"faces-config.xml" file:

<converter>
<converter-id>test.FooConverter</converter-id>
<converter-class>test.faces.FooConverter</converter-class>
</converter>

JSF 2.0 may provide more convenient annotation placed on the
converter class directly (don't know, I have really no JSF 2
experience, yet).

[1]
http://download.oracle.com/javase/tu...s/erasure.html
[2] "JSF & Support for Generic Types... Again..."
<http://java.net/projects/javaserverfaces/lists/dev/archive/2011-04/message/15>

--
Stanimir
 
Reply With Quote
 
 
 
 
Elegie
Guest
Posts: n/a
 
      06-04-2011
Le 04/06/2011 16:42, Stanimir Stamenkov a crit :

Hi,

> You're missing the generics type erasure [1]. JSF doesn't have the
> generics type information at run time.


Ah, I see. I did not know about generics type erasure at all, so that
explains it.

> A related (but not the same)
> issue [2] has been brought to the JSF Dev mailing list.


I have also submitted the case as a minor bug to the Java.Net
repository, this morning. I wish I had waited for your explanation
before submitting it, though - making a fool of myself, again... I'll
update the entry with a comment.

> To resolve the issue you could attach converter to your input component
> explicitly, e.g.:
>
> <h:selectManyCheckbox
> value="#{testCase.foos}"
> converter="#{...}">
> ...
> </h:selectManyCheckbox>


This looks like a fine approach, I will investigate it and try to work
it out properly in my design.

Thank you for all your explanations and suggestions!

Kind regards,
Elegie.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Include JSF page within another JSF page BlackIce Java 1 07-05-2006 11:24 PM
JSF debugging / JSF newsgroup Sebastian Fey Java 1 04-07-2006 08:52 PM
[JSF]Need to deploy a jsf application on SunApplicationServer. dudu Java 0 03-03-2006 12:09 PM
How to display "No Rss feeds new availabe" when there are no FEEDS Patrick Olurotimi Ige ASP .Net 2 05-04-2005 11:50 PM
XML RSS news feeds into web pages ? phil altimas HTML 4 10-29-2004 03:45 PM



Advertisments