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; } } ```

Original source