package org.jboss.loom.utils.el;
import java.lang.reflect.Method;
import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
import javax.el.ListELResolver;
import javax.el.MapELResolver;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
/**
* JUEL: http://juel.sourceforge.net/guide/start.html
*/
public class JuelCustomResolverEvaluator implements IExprLangEvaluator {
private static final ExpressionFactory JUEL_FACTORY = new de.odysseus.el.ExpressionFactoryImpl();
private final IVariablesProvider varProvider;
public JuelCustomResolverEvaluator( IVariablesProvider variableProvider ) {
this.varProvider = variableProvider;
}
// TODO: Move ELContext anonymous innter class to normal outer; don't create it for every call.
@Override
public String evaluateEL( String expr ) {
if( expr == null )
throw new IllegalArgumentException("The expression param is null.");
// CompositeELResolver allows to resolve from multiple sources.
final CompositeELResolver resolver = new CompositeELResolver();
// Here I want to use Map to be able to add some values, e.g. from user input.
resolver.add( new MapELResolver() );
resolver.add( new ListELResolver() );
// BeanELDefaultStringResolver is my implementation which returns "" if it can't find given variable
// (instead of throwing an exception).
resolver.add( new BeanELDefaultStringResolver("") );
//de.odysseus.el.util.SimpleContext context = new de.odysseus.el.util.SimpleContext();
ELContext elCtx = new ELContext() {
@Override public ELResolver getELResolver() { return resolver; }
@Override public FunctionMapper getFunctionMapper() { return THROW_MAPPER; }
@Override public VariableMapper getVariableMapper() {
return new ProvidedVariableJuelMapper( JuelCustomResolverEvaluator.this.varProvider );
}
};
try {
ValueExpression valueExpr = JUEL_FACTORY.createValueExpression( elCtx, expr, String.class );
return (String) valueExpr.getValue( elCtx );
} catch( javax.el.PropertyNotFoundException ex ) {
throw new IllegalArgumentException( "Can't eval '" + expr + "':\n " + ex.getMessage(), ex );
} catch( Throwable ex ) {
throw new IllegalArgumentException( "Can't eval '" + expr + "':\n " + ex.getMessage(), ex );
}
}
/**
* Throws UnsupportedOperationException for any call.
*/
static final FunctionMapper THROW_MAPPER =
new FunctionMapper() {
@Override public Method resolveFunction( String prefix, String localName ) {
throw new UnsupportedOperationException( "No functions supported." );
}
};
}// class