Code which implements the custom EL resolver

Lets say we want to implement a mechanism for simple dynamic beans, which allows us to use any property name in EL without implementing all the getters and setters. First, we define an interface for this kind of beans:

public interface DynamicBean {
    Object getProperty(String name);

    void setProperty(String name, Object value);

    Class<?> getPropertyType(String name);
    
    boolean isReadOnly(String name);
}

With this interface, we can implement the resolver which allows to use all expressions like #{bean.name}, provided that “bean” is a bean which implements the above interface. Note that “bean” has already been resolved in an earlier step by one of the default resolvers and is now passed to our methods as base:

public class DynamicBeanELResolver extends ELResolver {
    public DynamicBeanELResolver() {
    }

    @Override
    public Object getValue(ELContext elContext, Object base, Object property) {
        
        // base == null => variable, base != null => property of base
        if (base != null && base instanceof DynamicBean) {
            DynamicBean bean = (DynamicBean) base;
            elContext.setPropertyResolved(true);
            return bean.getProperty(property.toString());
        }

        return null;
    }

    @Override
    public Class getType(ELContext elContext, Object base, Object property) {
        if (base != null && base instanceof DynamicBean) {
            DynamicBean bean = (DynamicBean) base;
            elContext.setPropertyResolved(true);
            return bean.getPropertyType(property.toString());
        }

        return null;
    }

    @Override
    public void setValue(ELContext elContext, Object base, Object property, Object value) {
        if (base != null && base instanceof DynamicBean) {
            DynamicBean bean = (DynamicBean) base;
            elContext.setPropertyResolved(true);
            bean.setProperty(property.toString(), value);
        }
    }

    @Override
    public boolean isReadOnly(ELContext elContext, Object base, Object property) {
        if (base != null && base instanceof DynamicBean) {
            DynamicBean bean = (DynamicBean) base;
            elContext.setPropertyResolved(true);
            return bean.isReadOnly(property.toString());
        }

        return false;
    }

// Design time support methods
    @Override
    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext eLContext, Object object) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Class<?> getCommonPropertyType(ELContext eLContext, Object object) {
        throw new UnsupportedOperationException();
    }
}