nesting JSF expression strings
el, java, jsf-2
Solution
This is by default not supported. You need a custom `ELResolver` here. Easiest is to extend the existing `BeanELResolver`.
Here's a kickoff example:
public class ExtendedBeanELResolver extends BeanELResolver {
@Override
public Object getValue(ELContext context, Object base, Object property)
throws NullPointerException, PropertyNotFoundException, ELException
{
if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection) {
return null;
}
String propertyString = property.toString();
if (propertyString.contains(".")) {
Object value = base;
for (String propertyPart : propertyString.split("\\.")) {
value = super.getValue(context, value, propertyPart);
}
return value;
}
else {
return super.getValue(context, base, property);
}
}
}
To get it to run, register it as follows in `faces-config.xml`:
<application>
<el-resolver>com.example.ExtendedBeanELResolver</el-resolver>
</application>
Problem
I want to achieve this using dynamic parameters for value expressions: ``` <h:dataTable value="#{someBean.someValue}" var="field"> <h:column>#{anotherBean[field]}</h:column> </h:dataTable> ``` where `field` is `'user.name'` or `'location.address.zip'` or... Is it possible? Note that this is a simple example, I'm interested in `ValueExpression` not in `dataTable` component. UPDATE now the question is: how to replace standard BeanELResolver? looking in ELUtils: ``` ... composite.addRootELResolver(IMPLICIT_RESOLVER); composite.add(FLASH_RESOLVER); composite.addPropertyELResolver(COMPOSITE_COMPONENT_ATTRIBUTES_EL_RESOLVER); addELResolvers(composite, associate.getELResolversFromFacesConfig()); addVariableResolvers(composite, FacesCompositeELResolver.ELResolverChainType.Faces, associate); addPropertyResolvers(composite, associate); composite.add(associate.getApplicationELResolvers()); composite.addRootELResolver(MANAGED_BEAN_RESOLVER); composite.addPropertyELResolver(RESOURCE_RESOLVER); composite.addPropertyELResolver(BUNDLE_RESOLVER); ... ``` but i don't fully understand resolver chain yet... so i'll go studying :) UPDATE 2 this code works ;) ``` public class ExtendedBeanELResolver extends BeanELResolver { @Override public Object getValue(ELContext context, Object base, Object property) throws NullPointerException, PropertyNotFoundException, ELException { try { return super.getValue(context, base, property); } catch(PropertyNotFoundException e) { try { Object value = base; for(String part : property.toString().split("\\.")) { value = super.getValue(context, value, part); } return value; } catch(PropertyNotFoundException e1) { context.setPropertyResolved(false); } } return null; } } ```