[
https://jira.jboss.org/jira/browse/JBSEAM-3916?page=com.atlassian.jira.pl...
]
Christian Bauer reopened JBSEAM-3916:
-------------------------------------
The fix breaks other functionality. You can verify this with the examples/wiki/ start
page. The problematic line 83 in SeamELResolver.java:
private Object resolveInMap(ELContext context, Map map, Object property) {
if (map.containsKey(property)) {
return null;
}
You can't call containsKey() on the map in UIComponent:
return new AbstractMap<String, UIComponent>()
{
@Override
public Set<Map.Entry<String, UIComponent>> entrySet()
{
throw new UnsupportedOperationException();
}
Test code:
<h:outputText id="foo" value="FOO"/>
<h:outputText value="#{uiComponent[foo]}"/>
With this stacktrace:
Caused by: java.lang.UnsupportedOperationException
at org.jboss.seam.faces.UiComponent$1.entrySet(UiComponent.java:42)
at java.util.AbstractMap.containsKey(AbstractMap.java:136)
at org.jboss.seam.el.SeamELResolver.resolveInMap(SeamELResolver.java:84)
at org.jboss.seam.el.SeamELResolver.getValue(SeamELResolver.java:63)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
at
com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
The #{uiComponent} access by client identifier is typically used to get the row index when
iterating with datatable, like this:
<h:outputText value="#{uiComponent['attachmentTable'].rowIndex +
1}"/>
SeamELResolver.resolveInMap() will resolve a property
"size" to ((Map)base).size() even if the Map contains a key named
"size" - instead, it should return null and allow javax.el.MapELResolver to
resolve the property to ((Map)base).get("size")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: JBSEAM-3916
URL:
https://jira.jboss.org/jira/browse/JBSEAM-3916
Project: Seam
Issue Type: Bug
Components: EL
Affects Versions: 2.1.0.SP1
Reporter: Ian Springer
Assignee: Norman Richards
Priority: Critical
Fix For: 2.1.2.CR1
I have an expression:
#{MyBean.someMap['size']}
In my non-Seam JSF app, this expression was resolving to
MyBean.getSomeMap().get("size"). However, when I integrated Seam into my app,
the expression started instead resolving to MyBean.getSomeMap().size(), which broke my
app. This is occurring because SeamELResolver is ahead of javax.el.MapELResolver in the
CompositeELResolver resolver list, and its resolveInMap() function ensures a property
named "size" resolves to ((Map)base).size() This makes it impossible for me to
obtain the value of the element with key "size" from my Map via EL.
To solve this, I suggest changing SeamELResolver.resolveInMap() to the following:
private Object resolveInMap(ELContext context, Object base, Object property)
{
if ( !( (Map) base ).containsKey("size") &&
"size".equals(property) )
{
context.setPropertyResolved(true);
return ( (Map) base ).size();
}
else if ( !( (Map) base ).containsKey("values") &&
"values".equals(property) )
{
context.setPropertyResolved(true);
return ( (Map) base ).values();
}
else if ( !( (Map) base ).containsKey("keySet") &&
"keySet".equals(property) )
{
context.setPropertyResolved(true);
return ( (Map) base ).keySet();
}
else if ( !( (Map) base ).containsKey("entrySet") &&
"entrySet".equals(property) )
{
context.setPropertyResolved(true);
return ( (Map) base ).entrySet();
}
else
{
return null;
}
}
The only disadvantage of this is that if you actually are trying to get at map.size(),
there will be no way to do so if the Map happens to contain a key named "size".
However, in such a case, #{MyBean.someMap.keySet.size} or #{MyBean.someMap.values.size}
could instead be used to obtain the Map's size.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira