JsfELExpressionParser and supporting classes for SWF-301, making JSF-managed beans available to expressions in the FlowDefinition via the unified EL.

This commit is contained in:
Jeremy Grelle
2007-07-31 23:33:22 +00:00
parent 50c5174729
commit 99416e44ba
3 changed files with 220 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
package org.springframework.webflow.executor.jsf;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;
import javax.faces.context.FacesContext;
import javax.faces.el.EvaluationException;
import javax.faces.el.PropertyNotFoundException;
import javax.faces.el.PropertyResolver;
import javax.faces.el.VariableResolver;
/**
* An adapter for using JSF 1.1 {@link VariableResolver}s and {@link PropertyResolver}s in an {@link ELContext}.
* @author Jeremy Grelle
*
*/
public class ELResolverAdapter extends ELResolver {
private FacesContext facesContext;
public ELResolverAdapter(FacesContext facesContext) {
this.facesContext = facesContext;
}
public Class getCommonPropertyType(ELContext context, Object base) {
return Object.class;
}
public Iterator getFeatureDescriptors(ELContext context, Object base) {
return Collections.EMPTY_LIST.iterator();
}
public Class getType(ELContext context, Object base, Object property) {
if (property == null) {
return null;
}
try {
context.setPropertyResolved(true);
if (base == null) {
Object var = getVariableResolver().resolveVariable(facesContext, property.toString());
return (var != null) ? var.getClass() : null;
} else {
if (base instanceof List || base.getClass().isArray()) {
return getPropertyResolver().getType(base, Integer.parseInt(property.toString()));
} else {
return getPropertyResolver().getType(base, property);
}
}
} catch (PropertyNotFoundException ex) {
throw new javax.el.PropertyNotFoundException(ex.getMessage(), ex.getCause());
} catch (EvaluationException ex) {
throw new ELException(ex.getMessage(), ex.getCause());
}
}
public Object getValue(ELContext context, Object base, Object property) {
if (property == null) {
return null;
}
try {
context.setPropertyResolved(true);
if (base == null) {
return getVariableResolver().resolveVariable(facesContext, property.toString());
} else {
if (base instanceof List || base.getClass().isArray()) {
return getPropertyResolver().getValue(base, Integer.parseInt(property.toString()));
} else {
return getPropertyResolver().getValue(base, property);
}
}
} catch (PropertyNotFoundException ex) {
throw new javax.el.PropertyNotFoundException(ex.getMessage(), ex.getCause());
} catch (EvaluationException ex) {
throw new ELException(ex.getMessage(), ex.getCause());
}
}
public boolean isReadOnly(ELContext context, Object base, Object property) {
if (property == null) {
return true;
}
try {
context.setPropertyResolved(true);
if (base == null) {
return false; // VariableResolver provides no way to determine isReadOnly
} else {
if (base instanceof List || base.getClass().isArray()) {
return getPropertyResolver().isReadOnly(base, Integer.parseInt(property.toString()));
} else {
return getPropertyResolver().isReadOnly(base, property);
}
}
} catch (PropertyNotFoundException ex) {
throw new javax.el.PropertyNotFoundException(ex.getMessage(), ex.getCause());
} catch (EvaluationException ex) {
throw new ELException(ex.getMessage(), ex.getCause());
}
}
public void setValue(ELContext context, Object base, Object property, Object value) {
if (property == null) {
throw new PropertyNotWritableException("Property is Null");
}
try {
context.setPropertyResolved(true);
if (base instanceof List || base.getClass().isArray()) {
getPropertyResolver().setValue(base, Integer.parseInt(property.toString()), value);
} else {
getPropertyResolver().setValue(base, property, value);
}
} catch (PropertyNotFoundException ex) {
throw new javax.el.PropertyNotFoundException(ex.getMessage(), ex.getCause());
} catch (EvaluationException ex) {
throw new ELException(ex.getMessage(), ex.getCause());
}
}
private VariableResolver getVariableResolver() {
return facesContext.getApplication().getVariableResolver();
}
private PropertyResolver getPropertyResolver() {
return facesContext.getApplication().getPropertyResolver();
}
}

View File

@@ -0,0 +1,25 @@
package org.springframework.webflow.executor.jsf;
import javax.faces.application.Application;
public class FacesAPI {
private static final int version = specifyVersion();
private FacesAPI() {
}
private final static int specifyVersion() {
try {
Application.class.getMethod("getExpressionFactory", null);
} catch (NoSuchMethodException e) {
return 11;
}
return 12;
}
public final static int getVersion() {
return version;
}
}

View File

@@ -0,0 +1,63 @@
package org.springframework.webflow.executor.jsf;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.FunctionMapper;
import javax.el.VariableMapper;
import javax.faces.context.FacesContext;
import org.springframework.binding.expression.el.ELContextFactory;
import org.springframework.binding.expression.el.JBossELExpressionParser;
/**
* A JSF-aware ExpressionParser that allows JSF managed beans to be referenced in expressions in the FlowDefinition.
* @author Jeremy Grelle
*
*/
public class JsfELExpressionParser extends JBossELExpressionParser {
public JsfELExpressionParser() {
super(new JsfELContextFactory());
}
public JsfELExpressionParser(ELContextFactory contextFactory) {
super(contextFactory);
}
private static class JsfELContextFactory implements ELContextFactory {
public ELContext getELContext(Object target) {
FacesContext context = FacesContext.getCurrentInstance();
if (FacesAPI.getVersion() < 12) {
return new Jsf11ELContext(context);
}
if (context != null) {
return context.getELContext();
}
return null;
}
private static class Jsf11ELContext extends ELContext {
ELResolver baseResolver;
public Jsf11ELContext(FacesContext context) {
baseResolver = new ELResolverAdapter(context);
}
public ELResolver getELResolver() {
return baseResolver;
}
public FunctionMapper getFunctionMapper() {
return null;
}
public VariableMapper getVariableMapper() {
return null;
}
}
}
}