Skip to main content
This revision made July 26, 2011 17:50, by Kin-man Chung
« earlier revision revert to this later revision »

Introduction

This is the API for using EL stand-alone, outside of a web container. ELProcessor is the main engine that EL users would be using most of the time. ELManager can be used to manage the environment/context for EL processing.

One design philosophy used here is to hide most of the implementation details from the users of this API. Things like ELContext, ELResolver, or even ValueExpression are not used. To be revisited

An instance of ELProcessor can be obtained from the ExpressionFactory. In it there is a default ELManager, which contains a default ELContext, which in term contains a default ELResolver, FunctionMapper, and VariableMapper. They are mostly empty, except for the default ELResolver, which contain enough ELResolvers to handle beans properties, arrays etc. details to be defined.

The following example shows how the api can be used.

  // Get an instnace of ELProcessor.  Container can inject one too.
  ELProcess el = ExpressionFactory.newInstance().newELProcessor();
  ELManager mgr = el.getELManager();
  mgr.addBeanNameResolver(new BeanNameResolver() {
    public Object getBean(String name) {
      return myBeans.get(name);
    }
  });
  // Evaluate an EL expression
  Object bar = el.getValue("#{foo.bar}");

ELProcessor.java

/*

 * Defines an API for EL expression processing.
 */

interface ELProcessor {

    /*
     * Return the ELManager used for EL porcessing.
     */
    ELManager getELManager();
    /*
     * Evaluate an EL expression, without coercion.
     */
    Object getValue(String expression);
    /*
     * Evaluate an EL expression, with coercion.
     */
    Object getValue(String expression, Class expectedType);
    /*
     * Set a value to an EL expression that is a LHS
     */
    void setValue(String expression, Object value);
    /*
     * Define a EL variable
     */
    void defineVariable(String var, String expression);
    /*
     * Define a EL function
     * @param prefix The prefix of the function, or "" if prefix not used.
     * @param localName The short name of the function.
     * @param function The static fucntion e.g "org.acme.App.meth"
     * TODO: need parameters types?
     */
    void defineFunction(String prefix, String localName, String function);

}

ELManager.java

/*

 * Manages EL parsing and evaluateion enviroment.
 */

inteface ELManager {

    /*
     * Return the ExpressionFactory instance used for EL evaluations
     */
    ExpressionFactory getExpressionFactory();
    /*
     * Return the ELContext used.
     */
    ELContext getELContext();
    /*
     * Register bean name lookup
     * Implicitly adds a BeanNameELResolver to the list of ELResolvers
     */
    void addBeanNameResolver(BeanNameResolver bnr);
    /*
     * Add user defined ELResolver to the currect list of ELResolvers
     * Can be called multiple times with additive effect.
     */
    void addELResolver(ELResolver elr);
    /*
     * Set the ELResolver to be used for EL expression processing.
     * Note that the ELResolvers added in previous calls addELResolver and
     * addBeanNameResolver  will not be automatically added to the new
     * ELResolver.
     * @return The previous ELResolver or null if there is none.
     */
    ELResolver setELResolver(ELResolver elr);

}

BeanNameResolver.java

/*

 * An abstract class that can be extended to return a bean object given its name * or to set a value to an existing bean.
 */

abstract class BeanNameResolver {

    /*
     * Return the bean known by its name
     */
    String getBean(String beanName) {
        return null;
    }
    /*
     * Set a value to an existing bean of the given name.
     */
    void setBeanValue(String beanName, Object value)
             throws PropertyNotWritableException {
        throw new PropertyNotWritableException();
    }

}

BeanNameELResolver.java

/*

 * An ELResolver that help to resolve user or container managed beans.
 */

public class BeanNameELResolver extends ELResolver {

    private BeanNameResolver beanNameResolver;
    public BeanNameELResolver(BeanNameResolver beanNameResolver) {
        this.beanNameResolver = beanNameResolver;
    }
    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (context == null) {
            throw new NullPointerException();
        }
        if (base == null && property instanceof String) {
            Object bean = beanNameResolver.getBean((String) property);
            if (bean != null) {
                context.setPropertyResolved(true);
                return bean;
            }
        }
        return null;
    }
    @Override
    public void setValue(ELContext context, Object base, Object property,
                         Object value) {
        if (context == null) {
            throw new NullPointerException();
        }
        if (base == null && property instanceof String) {
            Object bean = beanNameResolver.getBean((String) property);
            if (bean != null) {
                context.setPropertyResolved(true);
                beanNameResolver.setBeanValue((String) property, value);
            }
        }
    }

}

ExpreesionFactory.java

public abstract class ExpressionFactory {

    ...
    /*
     * Get a new instance of an implementation of ELProcessor
     */
    public abstract ELProcessor newELProcessor();

}

 
 
Close
loading
Please Confirm
Close