![JAR search and dependency download from the Maven repository](/logo.png)
net.sourceforge.stripes.validation.expression.Jsp21ExpressionExecutor Maven / Gradle / Ivy
/* Copyright 2008 Tim Fennell
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sourceforge.stripes.validation.expression;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.controller.ParameterName;
import net.sourceforge.stripes.controller.StripesFilter;
import net.sourceforge.stripes.controller.StripesConstants;
import net.sourceforge.stripes.validation.ValidationMetadata;
import net.sourceforge.stripes.validation.ValidationErrors;
import net.sourceforge.stripes.validation.ValidationError;
import net.sourceforge.stripes.validation.ScopedLocalizableError;
import net.sourceforge.stripes.util.Log;
import net.sourceforge.stripes.util.bean.BeanUtil;
import net.sourceforge.stripes.exception.StripesRuntimeException;
import javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.ServletContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;
import javax.el.FunctionMapper;
import javax.el.VariableMapper;
import javax.el.ELException;
import java.util.List;
import java.util.Iterator;
import java.beans.FeatureDescriptor;
import java.lang.reflect.Method;
/**
* An implementation of {@link ExpressionExecutor} that uses the new EL API available in Java
* EE 5 in the {@link javax.el} package. While more complicated that the JSP 2.0 API it has
* one advantage which is that it can be used without the need to allocate a PageContext
* object and without any other libraries being available.
*
* @author tfenne
* @since Stripes 1.5
*/
public class Jsp21ExpressionExecutor implements ExpressionExecutor {
private static final Log log = Log.getInstance(Jsp21ExpressionExecutor.class);
/**
* Implementation of the EL interface to resolve variables. Resolves variables by
* checking two special names ("this" and "actionBean") and then falling back to
* retrieving property values from the ActionBean passed in to the constructor.
*
* @author Tim Fennell
* @since Stripes 1.5
*/
protected static class StripesELResolver extends ELResolver {
private ActionBean bean;
private Object currentValue;
/** Constructs a resolver based on the action bean . */
StripesELResolver(ActionBean bean) {
this.bean = bean;
}
/** Sets the value that the 'this' variable will point at. */
void setCurrentValue(Object value) {
this.currentValue = value;
}
/**
* Attempts to resolve the value as described in the class level javadoc.
* @param ctx the ELContext for the expression
* @param base the object on which the property resides (null == root property)
* @param prop the name of the property being looked for
* @return the value of the property or null if one can't be found
*/
@Override
public Object getValue(ELContext ctx, Object base, Object prop) {
if ("this".equals(prop)) {
ctx.setPropertyResolved(true);
return this.currentValue;
}
else if (StripesConstants.REQ_ATTR_ACTION_BEAN.equals(prop)) {
ctx.setPropertyResolved(true);
return this.bean;
}
else {
try {
base = base == null ? this.bean : base;
Object retval = BeanUtil.getPropertyValue(String.valueOf(prop), base);
ctx.setPropertyResolved(true);
return retval;
}
catch (Exception e) { return null; }
}
}
/** Does nothing. Always returns Object.class. */
@Override
public Class> getType(final ELContext ctx, final Object base, final Object prop) {
ctx.setPropertyResolved(true);
return Object.class;
}
/** Does nothing. Always throws PropertyNotWritableException. */
@Override
public void setValue(ELContext elContext, Object o, Object o1, Object o2) throws PropertyNotWritableException {
throw new PropertyNotWritableException("Unsupported Op");
}
/** Always returns true. */
@Override
public boolean isReadOnly(final ELContext elContext, final Object o, final Object o1) { return true; }
/** Always returns null. */
@Override
public Iterator getFeatureDescriptors(final ELContext elContext, final Object o) { return null; }
/** Always returns Object.class. */
@Override
public Class> getCommonPropertyType(final ELContext elContext, final Object o) { return Object.class; }
}
/**
* Implementation of the EL interface for managing expression context. Resolves variables
* using the StripesELResolver above. Both the FunctionMapper and VariableResolver are
* essentially no-op implementations.
*
* @author Tim Fennell
* @since Stripes 1.5
*/
protected static class StripesELContext extends ELContext {
@SuppressWarnings("unused")
private ActionBean bean;
private StripesELResolver resolver;
private VariableMapper vmapper;
private static final FunctionMapper fmapper = new FunctionMapper() {
@Override
public Method resolveFunction(final String s, final String s1) { return null; }
};
/**
* Constructs a new instance using the ActionBean provided as the source for most
* property resolutions.
*
* @param bean the ActionBean to resolve properties against
*/
public StripesELContext(ActionBean bean) {
this.bean = bean;
this.resolver = new StripesELResolver(bean);
this.vmapper = new VariableMapper() {
@Override
public ValueExpression resolveVariable(final String s) {
return null;
}
@Override
public ValueExpression setVariable(final String s, final ValueExpression valueExpression) {
return null;
}
};
}
/** Sets the current value of the 'this' special variable. */
public void setCurrentValue(final Object value) {resolver.setCurrentValue(value);}
/** Returns the StripesELResovler. */
@Override
public StripesELResolver getELResolver() { return this.resolver; }
/** Returns a no-op implementation of FunctionMapper. */
@Override
public FunctionMapper getFunctionMapper() { return fmapper; }
/** Returns a no-op implementation of VariableMapper. */
@Override
public VariableMapper getVariableMapper() { return vmapper; }
}
/** Default constructor that throws an exception if the JSP2.1 APIs are not available. */
public Jsp21ExpressionExecutor() {
if (getExpressionFactory() == null) {
throw new StripesRuntimeException("Could not create a JSP2.1 ExpressionFactory.");
}
}
// See interface for javadoc.
public void evaluate(final ActionBean bean, final ParameterName name, final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy