Merging of SWF-367 back into trunk. This has all of the SWF 2.0 goodies.
This commit is contained in:
@@ -18,15 +18,12 @@ package org.springframework.binding.convert.support;
|
||||
import org.springframework.binding.convert.ConversionContext;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.binding.expression.support.StaticExpression;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Converter that converts a String into an Expression object.
|
||||
*
|
||||
* @see org.springframework.binding.expression.Expression
|
||||
* @see org.springframework.binding.expression.SettableExpression
|
||||
*
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
@@ -58,15 +55,11 @@ public class TextToExpression extends AbstractConverter {
|
||||
}
|
||||
|
||||
public Class[] getTargetClasses() {
|
||||
return new Class[] { Expression.class, SettableExpression.class };
|
||||
return new Class[] { Expression.class };
|
||||
}
|
||||
|
||||
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
|
||||
String expressionString = (String) source;
|
||||
if (getExpressionParser().isDelimitedExpression(expressionString)) {
|
||||
return getExpressionParser().parseExpression((String) source);
|
||||
} else {
|
||||
return new StaticExpression(expressionString);
|
||||
}
|
||||
return expressionParser.parseExpression(expressionString, Object.class, Object.class, null);
|
||||
}
|
||||
}
|
||||
@@ -34,21 +34,14 @@ public class EvaluationAttempt {
|
||||
*/
|
||||
private Object target;
|
||||
|
||||
/**
|
||||
* The evaluation context.
|
||||
*/
|
||||
private EvaluationContext context;
|
||||
|
||||
/**
|
||||
* Create an evaluation attempt.
|
||||
* @param expression the expression that failed to evaluate
|
||||
* @param target the target of the expression
|
||||
* @param context the context attributes that might have affected evaluation behavior
|
||||
*/
|
||||
public EvaluationAttempt(Expression expression, Object target, EvaluationContext context) {
|
||||
public EvaluationAttempt(Expression expression, Object target) {
|
||||
this.expression = expression;
|
||||
this.target = target;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,18 +58,11 @@ public class EvaluationAttempt {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns context attributes that may have influenced the evaluation process.
|
||||
*/
|
||||
public EvaluationContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return createToString(new ToStringCreator(this)).toString();
|
||||
}
|
||||
|
||||
protected ToStringCreator createToString(ToStringCreator creator) {
|
||||
return creator.append("expression", expression).append("target", target).append("context", context);
|
||||
return creator.append("expression", expression).append("target", target);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.binding.expression;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A context object with two main responsibities:
|
||||
* <ol>
|
||||
* <li>Exposing information to an expression to influence an evaluation attempt.
|
||||
* <li>Providing operations for recording progress or errors during the expression evaluation process.
|
||||
* </ol>
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface EvaluationContext {
|
||||
|
||||
/**
|
||||
* Returns a map of attributes that can be used to influence expression evaluation.
|
||||
* @return the evaluation attributes
|
||||
*/
|
||||
public Map getAttributes();
|
||||
|
||||
}
|
||||
@@ -27,9 +27,16 @@ public interface Expression {
|
||||
* Evaluate the expression encapsulated by this evaluator against the provided target object and return the result
|
||||
* of the evaluation.
|
||||
* @param target the target of the expression
|
||||
* @param context the expression evaluation context
|
||||
* @return the evaluation result
|
||||
* @throws EvaluationException an exception occured during evaluation
|
||||
*/
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException;
|
||||
public Object getValue(Object target) throws EvaluationException;
|
||||
|
||||
/**
|
||||
* Evaluate this expression against the target object to set its value to the value provided.
|
||||
* @param target the target object
|
||||
* @param value the new value to be set
|
||||
* @throws EvaluationException an exception occurred during evaluation
|
||||
*/
|
||||
public void setValue(Object target, Object value) throws EvaluationException;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.binding.expression;
|
||||
|
||||
/**
|
||||
* Parses expression strings, returing a configured evaluator instance capable of performing parsed expression
|
||||
* Parses expression strings, returning a configured evaluator instance capable of performing parsed expression
|
||||
* evaluation in a thread safe way.
|
||||
*
|
||||
* @author Keith Donald
|
||||
@@ -24,30 +24,38 @@ package org.springframework.binding.expression;
|
||||
public interface ExpressionParser {
|
||||
|
||||
/**
|
||||
* Is this expression string delimited in a manner that indicates it is a parseable expression? For example
|
||||
* "${expression}".
|
||||
* @param expressionString the proposed expression string
|
||||
* @return true if yes, false if not
|
||||
* Is the provided expression string an "eval" expression: meaning an expression that validates to a dynamic value,
|
||||
* and not a literal expression? "Eval" expressions are normally enclosed in delimiters like #{}, where literal
|
||||
* expressions are not delimited.
|
||||
* @param string the string
|
||||
* @return true if the expression is an eval expression string, false otherwise.
|
||||
*/
|
||||
public boolean isDelimitedExpression(String expressionString);
|
||||
public boolean isEvalExpressionString(String string);
|
||||
|
||||
/**
|
||||
* Parse the provided expression string, returning an evaluator capable of evaluating it against input.
|
||||
* @param expressionString the parseable expression string
|
||||
* @return the evaluator for the parsed expression
|
||||
* @throws ParserException an exception occured during parsing
|
||||
* Parse the raw string into an "eval" expression string that when parsed produces a dynamic value when evaluated
|
||||
* against a target object. For example, the raw expression string "person.id" might become #{person.id}. If the
|
||||
* string is already an eval expression string, the string argument is returned unchanged. If the string is an
|
||||
* composite expression string that mixes eval and literal expressions, a parser exception is thrown.
|
||||
* @param string the raw string to be transformed into a parseable eval expression string
|
||||
* @return the eval expression spring
|
||||
* @throws ParserException an exception occurred during parsing
|
||||
*/
|
||||
public Expression parseExpression(String expressionString) throws ParserException;
|
||||
public String parseEvalExpressionString(String string) throws ParserException;
|
||||
|
||||
/**
|
||||
* Parse the provided settable expression string, returning an evaluator capable of evaluating its value as well as
|
||||
* setting its value.
|
||||
* Parse the provided expression string, returning an expression evaluator capable of evaluating it. The expression
|
||||
* string may be a literal expression string like "foo", an eval-expression string like #{foo}, or a
|
||||
* composite-expression string like "foo#{foo}bar#{bar}".
|
||||
* @param expressionString the parseable expression string
|
||||
* @param expressionTargetType the class of target object this expression can successfully evaluate; for example,
|
||||
* <code>Map.class</code> for an expression that is expected to evaluate against Maps.
|
||||
* @param expectedEvaluationResultType the class of object this expression is expected to return or set: for
|
||||
* example, <code>Boolean.class</code> for an expression that is expected to get or set a boolean value.
|
||||
* @param expressionVariables variables providing aliases for this expression during evaluation parsing. Optional.
|
||||
* @return the evaluator for the parsed expression
|
||||
* @throws ParserException an exception occured during parsing
|
||||
* @throws UnsupportedOperationException this parser does not support settable expressions
|
||||
* @throws ParserException an exception occurred during parsing
|
||||
*/
|
||||
public SettableExpression parseSettableExpression(String expressionString) throws ParserException,
|
||||
UnsupportedOperationException;
|
||||
|
||||
public Expression parseExpression(String expressionString, Class expressionTargetType,
|
||||
Class expectedEvaluationResultType, ExpressionVariable[] expressionVariables) throws ParserException;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.springframework.binding.expression;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A simple, convenient alias for a more-complex expression.
|
||||
*
|
||||
* TODO - consider making the valueExpressionString a parsed Expression object for more flexibility.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ExpressionVariable {
|
||||
|
||||
private String name;
|
||||
|
||||
private String valueExpressionString;
|
||||
|
||||
/**
|
||||
* Creates a new expression variable
|
||||
* @param name the name of the variable, acting as an convenient alias
|
||||
* @param valueExpressionString the complex expression to be aliased in string form
|
||||
*/
|
||||
public ExpressionVariable(String name, String valueExpressionString) {
|
||||
Assert.hasText(name, "The expression variable must be named");
|
||||
Assert.hasText(valueExpressionString, "The expression value expression string is required");
|
||||
this.name = name;
|
||||
this.valueExpressionString = valueExpressionString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the variable name, typically vary simple like "index".
|
||||
* @return the variable name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expression that will be evaluated when the variable is referenced by its name in another expression.
|
||||
* @return the expression value.
|
||||
*/
|
||||
public String getValueExpressionString() {
|
||||
return valueExpressionString;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ExpressionVariable)) {
|
||||
return false;
|
||||
}
|
||||
ExpressionVariable var = (ExpressionVariable) o;
|
||||
return name.equals(var.name);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[Expression Variable '" + name + "']";
|
||||
}
|
||||
}
|
||||
@@ -34,10 +34,9 @@ public class SetValueAttempt extends EvaluationAttempt {
|
||||
* @param expression the settable expression
|
||||
* @param target the target of the expression
|
||||
* @param value the value that was attempted to be set
|
||||
* @param context context attributes that may have influenced the evaluation and set process
|
||||
*/
|
||||
public SetValueAttempt(SettableExpression expression, Object target, Object value, EvaluationContext context) {
|
||||
super(expression, target, context);
|
||||
public SetValueAttempt(Expression expression, Object target, Object value) {
|
||||
super(expression, target);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.binding.expression;
|
||||
|
||||
/**
|
||||
* An evaluator that is capable of setting a value on a target object at the path defined by this expression.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface SettableExpression extends Expression {
|
||||
|
||||
/**
|
||||
* Evaluate this expression against the target object to set its value to the value provided.
|
||||
* @param target the target object
|
||||
* @param value the new value to be set
|
||||
* @param context the evaluation context
|
||||
* @throws EvaluationException an exception occured during evaluation
|
||||
*/
|
||||
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package org.springframework.binding.expression.el;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.FunctionMapper;
|
||||
import javax.el.VariableMapper;
|
||||
|
||||
/**
|
||||
* A default {@link ELContextFactory} for facilitating use of EL for expression evaluation.
|
||||
* @author Jeremy Grelle
|
||||
*
|
||||
*/
|
||||
public class DefaultELContextFactory implements ELContextFactory {
|
||||
|
||||
/**
|
||||
* Configures and returns a simple EL context to use to parse EL expressions.
|
||||
* @return The configured simple ELContext instance.
|
||||
*/
|
||||
public ELContext getParseContext() {
|
||||
return new SimpleELContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures and returns a simple EL context to use to evaluate EL expressions on the given base target object.
|
||||
* @return The configured simple ELContext instance.
|
||||
*/
|
||||
public ELContext getEvaluationContext(Object target) {
|
||||
return new SimpleELContext(target);
|
||||
}
|
||||
|
||||
private static class SimpleELContext extends ELContext {
|
||||
private DefaultELResolver resolver = new DefaultELResolver();
|
||||
|
||||
public SimpleELContext() {
|
||||
|
||||
}
|
||||
|
||||
public SimpleELContext(Object target) {
|
||||
this.resolver.setTarget(target);
|
||||
}
|
||||
|
||||
public ELResolver getELResolver() {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
public FunctionMapper getFunctionMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public VariableMapper getVariableMapper() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
package org.springframework.binding.expression.el;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.el.ArrayELResolver;
|
||||
import javax.el.BeanELResolver;
|
||||
import javax.el.CompositeELResolver;
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.ListELResolver;
|
||||
import javax.el.MapELResolver;
|
||||
import javax.el.PropertyNotFoundException;
|
||||
import javax.el.PropertyNotWritableException;
|
||||
import javax.el.ResourceBundleELResolver;
|
||||
|
||||
import org.springframework.binding.collection.MapAdaptable;
|
||||
|
||||
/**
|
||||
* A generic ELResolver to be used as a default when no other ELResolvers have been configured by the client
|
||||
* application.
|
||||
@@ -27,55 +27,48 @@ public class DefaultELResolver extends CompositeELResolver {
|
||||
|
||||
private Object target;
|
||||
|
||||
public DefaultELResolver() {
|
||||
configureResolvers();
|
||||
}
|
||||
|
||||
public Class getType(ELContext context, Object base, Object property) {
|
||||
return super.getType(context, adaptIfNecessary(base), property);
|
||||
}
|
||||
|
||||
public Object getValue(ELContext context, Object base, Object property) {
|
||||
if (base == null) {
|
||||
try {
|
||||
return super.getValue(context, target, property);
|
||||
} catch (PropertyNotFoundException ex) {
|
||||
context.setPropertyResolved(false);
|
||||
}
|
||||
}
|
||||
return super.getValue(context, adaptIfNecessary(base), property);
|
||||
}
|
||||
|
||||
public void setValue(ELContext context, Object base, Object property, Object val) {
|
||||
if (base == null) {
|
||||
try {
|
||||
super.setValue(context, target, property, val);
|
||||
if (context.isPropertyResolved())
|
||||
return;
|
||||
} catch (PropertyNotWritableException ex) {
|
||||
context.setPropertyResolved(false);
|
||||
}
|
||||
}
|
||||
super.setValue(context, adaptIfNecessary(base), property, val);
|
||||
/**
|
||||
* Creates a new default EL resolver for resolving properties of the root object.
|
||||
* @param target the target, or "root", object of the expression
|
||||
*/
|
||||
public DefaultELResolver(Object target, List customResolvers) {
|
||||
this.target = target;
|
||||
configureResolvers(customResolvers);
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(Object target) {
|
||||
this.target = adaptIfNecessary(target);
|
||||
public Class getType(ELContext context, Object base, Object property) {
|
||||
return super.getType(context, base, property);
|
||||
}
|
||||
|
||||
private Object adaptIfNecessary(Object base) {
|
||||
if (base instanceof MapAdaptable) {
|
||||
return ((MapAdaptable) base).asMap();
|
||||
public Object getValue(ELContext context, Object base, Object property) {
|
||||
if (base == null) {
|
||||
return super.getValue(context, target, property);
|
||||
} else {
|
||||
return base;
|
||||
return super.getValue(context, base, property);
|
||||
}
|
||||
}
|
||||
|
||||
private void configureResolvers() {
|
||||
public void setValue(ELContext context, Object base, Object property, Object val) {
|
||||
if (base == null) {
|
||||
super.setValue(context, target, property, val);
|
||||
} else {
|
||||
super.setValue(context, base, property, val);
|
||||
}
|
||||
}
|
||||
|
||||
private void configureResolvers(List customResolvers) {
|
||||
if (customResolvers != null) {
|
||||
Iterator i = customResolvers.iterator();
|
||||
while (i.hasNext()) {
|
||||
ELResolver resolver = (ELResolver) i.next();
|
||||
add(resolver);
|
||||
}
|
||||
}
|
||||
add(new MapAdaptableELResolver());
|
||||
add(new ArrayELResolver());
|
||||
add(new ListELResolver());
|
||||
add(new MapELResolver());
|
||||
@@ -83,4 +76,4 @@ public class DefaultELResolver extends CompositeELResolver {
|
||||
add(new BeanELResolver());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.springframework.binding.expression.el;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.VariableMapper;
|
||||
|
||||
/**
|
||||
* A factory for creating a EL context object that will be used to evaluate a target object of an EL expression.
|
||||
@@ -10,19 +11,14 @@ import javax.el.ELResolver;
|
||||
*/
|
||||
public interface ELContextFactory {
|
||||
|
||||
/**
|
||||
* Configures and returns an {@link ELContext} to be used in parsing EL expressions.
|
||||
* @return ELContext The configured ELContext instance for parsing expressions.
|
||||
*/
|
||||
public ELContext getParseContext();
|
||||
|
||||
/**
|
||||
* Configures and returns an {@link ELContext} to be used in evaluating EL expressions on the given base target
|
||||
* object. In certain environments the target will be null and the base object of the expression is expected to be
|
||||
* resolved via the ELContext's {@link ELResolver} chain.
|
||||
* @param target The base object for the expression evaluation.
|
||||
* @param target The base object for the expression evaluation
|
||||
* @param variableMapper The mapping storing variables needed during expression evaluation
|
||||
* @return ELContext The configured ELContext instance for evaluating expressions.
|
||||
*/
|
||||
public ELContext getEvaluationContext(Object target);
|
||||
public ELContext getELContext(Object target, VariableMapper variableMapper);
|
||||
|
||||
}
|
||||
@@ -3,68 +3,60 @@ package org.springframework.binding.expression.el;
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELException;
|
||||
import javax.el.ValueExpression;
|
||||
import javax.el.VariableMapper;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationAttempt;
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Evaluates a parsed EL expression.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class ELExpression implements SettableExpression {
|
||||
public class ELExpression implements Expression {
|
||||
|
||||
private ELContextFactory factory;
|
||||
private ELContextFactory elContextFactory;
|
||||
|
||||
private ValueExpression expression;
|
||||
private ValueExpression valueExpression;
|
||||
|
||||
public ELExpression(ELContextFactory factory, ValueExpression expression) {
|
||||
this.factory = factory;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
|
||||
ELContext ctx = getELContext(target);
|
||||
try {
|
||||
expression.setValue(ctx, value);
|
||||
} catch (ELException ex) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
|
||||
ELContext ctx = getELContext(target);
|
||||
try {
|
||||
return expression.getValue(ctx);
|
||||
} catch (ELException ex) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected Class getType(Object target, EvaluationContext context) throws EvaluationException {
|
||||
ELContext ctx = getELContext(target);
|
||||
try {
|
||||
return expression.getType(ctx);
|
||||
} catch (ELException ex) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
|
||||
}
|
||||
}
|
||||
private VariableMapper variableMapper;
|
||||
|
||||
/**
|
||||
* Retrieves an {@link ELContext} instance, configured with a DefaultELResolver if no other resolvers have been
|
||||
* configured.
|
||||
*
|
||||
* @return {@link ELContext} The thread-bound {@link ELContext} instance.
|
||||
* Creates a new el expression
|
||||
* @param factory the el context factory for creating the EL context that will be used during expression evaluation
|
||||
* @param valueExpression the value expression to evaluate
|
||||
* @param variableMapper the variable mapper containing variables needed during expression evaluation
|
||||
*/
|
||||
protected ELContext getELContext(Object target) {
|
||||
ELContext ctx = factory.getEvaluationContext(target);
|
||||
return ctx;
|
||||
public ELExpression(ELContextFactory factory, ValueExpression valueExpression, VariableMapper variableMapper) {
|
||||
Assert.notNull(factory, "The ELContextFactory is required to evaluate EL expressions");
|
||||
Assert.notNull(valueExpression, "The EL value expression is required for evaluation");
|
||||
this.elContextFactory = factory;
|
||||
this.valueExpression = valueExpression;
|
||||
this.variableMapper = variableMapper;
|
||||
}
|
||||
|
||||
public Object getValue(Object target) throws EvaluationException {
|
||||
ELContext ctx = elContextFactory.getELContext(target, variableMapper);
|
||||
try {
|
||||
return valueExpression.getValue(ctx);
|
||||
} catch (ELException ex) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(Object target, Object value) throws EvaluationException {
|
||||
ELContext ctx = elContextFactory.getELContext(target, variableMapper);
|
||||
try {
|
||||
valueExpression.setValue(ctx, value);
|
||||
} catch (ELException ex) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return expression.hashCode();
|
||||
return valueExpression.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
@@ -72,11 +64,11 @@ public class ELExpression implements SettableExpression {
|
||||
return false;
|
||||
}
|
||||
ELExpression other = (ELExpression) o;
|
||||
return expression.equals(other.expression);
|
||||
return valueExpression.equals(other.valueExpression);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return expression.getExpressionString();
|
||||
return valueExpression.getExpressionString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,20 @@
|
||||
package org.springframework.binding.expression.el;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELException;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.ExpressionFactory;
|
||||
import javax.el.FunctionMapper;
|
||||
import javax.el.ValueExpression;
|
||||
import javax.el.VariableMapper;
|
||||
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.ExpressionVariable;
|
||||
import org.springframework.binding.expression.ParserException;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
|
||||
/**
|
||||
* An expression parser that parses EL expressions.
|
||||
@@ -16,90 +23,118 @@ import org.springframework.binding.expression.SettableExpression;
|
||||
public class ELExpressionParser implements ExpressionParser {
|
||||
|
||||
/**
|
||||
* The expression prefix for deferred EL expressions.
|
||||
* The expression prefix.
|
||||
*/
|
||||
private static final String DEFERRED_EL_EXPRESSION_PREFIX = "#{";
|
||||
private static final String EXPRESSION_PREFIX = "#{";
|
||||
|
||||
/**
|
||||
* The expression suffix for deferred EL expressions.
|
||||
* The expression suffix.
|
||||
*/
|
||||
private static final String DEFERRED_EL_EXPRESSION_SUFFIX = "}";
|
||||
|
||||
/**
|
||||
* The marked expression delimiter prefix.
|
||||
*/
|
||||
private String expressionPrefix = DEFERRED_EL_EXPRESSION_PREFIX;
|
||||
|
||||
/**
|
||||
* The marked expression delimiter suffix.
|
||||
*/
|
||||
private String expressionSuffix = DEFERRED_EL_EXPRESSION_SUFFIX;
|
||||
|
||||
/**
|
||||
* The {@link ELContextFactory} for retrieving a configured ELContext.
|
||||
*/
|
||||
private ELContextFactory contextFactory;
|
||||
private static final String EXPRESSION_SUFFIX = "}";
|
||||
|
||||
/**
|
||||
* The ExpressionFactory for constructing EL expressions
|
||||
*/
|
||||
private ExpressionFactory expressionFactory;
|
||||
|
||||
private Map contextFactories = new HashMap();
|
||||
|
||||
/**
|
||||
* Creates a new EL expression parser for standalone usage.
|
||||
*/
|
||||
public ELExpressionParser(ExpressionFactory expressionFactory) {
|
||||
this.expressionFactory = expressionFactory;
|
||||
this.contextFactory = new DefaultELContextFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new EL expression parser with a custom context factory for a specific environment.
|
||||
*
|
||||
* @param contextFactory the context factory
|
||||
* Register the ELContextFactory for expressions that evaluate the given class of target object.
|
||||
* @param expressionTargetType the expression target class
|
||||
* @param contextFactory the context factory to use for expressions that evaluate those types of targets
|
||||
*/
|
||||
public ELExpressionParser(ExpressionFactory expressionFactory, ELContextFactory contextFactory) {
|
||||
this.expressionFactory = expressionFactory;
|
||||
this.contextFactory = contextFactory;
|
||||
public void putContextFactory(Class expressionTargetType, ELContextFactory contextFactory) {
|
||||
this.contextFactories.put(expressionTargetType, contextFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not given criteria are expressed as an expression.
|
||||
*/
|
||||
public boolean isDelimitedExpression(String expressionString) {
|
||||
int prefixIndex = expressionString.indexOf(expressionPrefix);
|
||||
if (prefixIndex == -1) {
|
||||
return false;
|
||||
}
|
||||
int suffixIndex = expressionString.indexOf(expressionSuffix, prefixIndex);
|
||||
if (suffixIndex == -1) {
|
||||
return false;
|
||||
} else {
|
||||
if (suffixIndex == prefixIndex + expressionPrefix.length()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public boolean isEvalExpressionString(String expressionString) {
|
||||
return expressionString.startsWith(EXPRESSION_PREFIX) && expressionString.endsWith(EXPRESSION_SUFFIX);
|
||||
}
|
||||
|
||||
public final Expression parseExpression(String expressionString) throws ParserException {
|
||||
return parseSettableExpression(expressionString);
|
||||
public String parseEvalExpressionString(String string) {
|
||||
return encloseInDelimitersIfNecessary(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the expression string into an EL value expression.
|
||||
* @param expressionString
|
||||
* @throws ParserException
|
||||
*/
|
||||
public final SettableExpression parseSettableExpression(String expressionString) throws ParserException,
|
||||
UnsupportedOperationException {
|
||||
ELContext ctx = contextFactory.getParseContext();
|
||||
public Expression parseExpression(String expressionString, Class expressionTargetType,
|
||||
Class expectedEvaluationResultType, ExpressionVariable[] expressionVariables) throws ParserException {
|
||||
ParserELContext context = new ParserELContext();
|
||||
try {
|
||||
return new ELExpression(contextFactory, expressionFactory.createValueExpression(ctx, expressionString,
|
||||
Object.class));
|
||||
context.mapVariables(expressionVariables, expressionFactory);
|
||||
ValueExpression expression = expressionFactory.createValueExpression(context, expressionString,
|
||||
expectedEvaluationResultType);
|
||||
ELContextFactory contextFactory = getContextFactory(expressionString, expressionTargetType);
|
||||
return new ELExpression(contextFactory, expression, context.getVariableMapper());
|
||||
} catch (ELException ex) {
|
||||
throw new ParserException(expressionString, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String encloseInDelimitersIfNecessary(String expressionString) {
|
||||
if (isEvalExpressionString(expressionString)) {
|
||||
return expressionString;
|
||||
} else {
|
||||
return EXPRESSION_PREFIX + expressionString + EXPRESSION_SUFFIX;
|
||||
}
|
||||
}
|
||||
|
||||
private ELContextFactory getContextFactory(String expressionString, Class expressionTargetType) {
|
||||
if (!contextFactories.containsKey(expressionTargetType)) {
|
||||
throw new ParserException(expressionString, new IllegalArgumentException(
|
||||
"No ELContextFactory registered for expressionTargetType [" + expressionTargetType + "]"));
|
||||
}
|
||||
return (ELContextFactory) contextFactories.get(expressionTargetType);
|
||||
}
|
||||
|
||||
private static class ParserELContext extends ELContext {
|
||||
private VariableMapper variableMapper;
|
||||
|
||||
public ELResolver getELResolver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public FunctionMapper getFunctionMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public VariableMapper getVariableMapper() {
|
||||
return variableMapper;
|
||||
}
|
||||
|
||||
public void mapVariables(ExpressionVariable[] variables, ExpressionFactory expressionFactory) {
|
||||
if (variables != null && variables.length > 0) {
|
||||
variableMapper = new VariableMapperImpl();
|
||||
for (int i = 0; i < variables.length; i++) {
|
||||
ExpressionVariable var = variables[i];
|
||||
ValueExpression expr = expressionFactory.createValueExpression(this,
|
||||
var.getValueExpressionString(), Object.class);
|
||||
variableMapper.setVariable(var.getName(), expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class VariableMapperImpl extends VariableMapper {
|
||||
private Map variables = new HashMap();
|
||||
|
||||
public ValueExpression resolveVariable(String name) {
|
||||
return (ValueExpression) variables.get(name);
|
||||
}
|
||||
|
||||
public ValueExpression setVariable(String name, ValueExpression value) {
|
||||
return (ValueExpression) variables.put(name, value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return variables.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.springframework.binding.expression.el;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.MapELResolver;
|
||||
|
||||
import org.springframework.binding.collection.MapAdaptable;
|
||||
|
||||
/**
|
||||
* An {@link ELResolver} for properly resolving variables in an instance of {@link MapAdaptable}
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class MapAdaptableELResolver extends MapELResolver {
|
||||
|
||||
public Class getType(ELContext context, Object base, Object property) {
|
||||
if (base instanceof MapAdaptable) {
|
||||
return super.getType(context, adapt(base), property);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getValue(ELContext context, Object base, Object property) {
|
||||
if (base instanceof MapAdaptable) {
|
||||
return super.getValue(context, adapt(base), property);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReadOnly(ELContext context, Object base, Object property) {
|
||||
if (base instanceof MapAdaptable) {
|
||||
return super.isReadOnly(context, adapt(base), property);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(ELContext context, Object base, Object property, Object value) {
|
||||
if (base instanceof MapAdaptable) {
|
||||
super.setValue(context, adapt(base), property, value);
|
||||
}
|
||||
}
|
||||
|
||||
private Map adapt(Object base) {
|
||||
MapAdaptable adaptable = (MapAdaptable) base;
|
||||
return adaptable.asMap();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,16 +16,14 @@
|
||||
package org.springframework.binding.expression.ognl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import ognl.Ognl;
|
||||
import ognl.OgnlException;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationAttempt;
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.SetValueAttempt;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -36,7 +34,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class OgnlExpression implements SettableExpression {
|
||||
class OgnlExpression implements Expression {
|
||||
|
||||
/**
|
||||
* The expression.
|
||||
@@ -65,29 +63,29 @@ class OgnlExpression implements SettableExpression {
|
||||
return expression.equals(other.expression);
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
|
||||
public Object getValue(Object target) throws EvaluationException {
|
||||
Assert.notNull(target, "The target object to evaluate is required");
|
||||
Map contextAttributes = (context != null ? context.getAttributes() : Collections.EMPTY_MAP);
|
||||
try {
|
||||
return Ognl.getValue(expression, contextAttributes, target);
|
||||
// TODO context map
|
||||
return Ognl.getValue(expression, Collections.EMPTY_MAP, target);
|
||||
} catch (OgnlException e) {
|
||||
if (e.getReason() != null && e.getReason() != e) {
|
||||
// unwrap the OgnlException since the actual exception is wrapped inside it
|
||||
// and there is not generic (getCause) way to get to it later on
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target, context), e.getReason());
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target), e.getReason());
|
||||
} else {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target, context), e);
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void evaluateToSet(Object target, Object value, EvaluationContext context) {
|
||||
public void setValue(Object target, Object value) {
|
||||
Assert.notNull(target, "The target object to evaluate is required");
|
||||
Map contextAttributes = (context != null ? context.getAttributes() : Collections.EMPTY_MAP);
|
||||
try {
|
||||
Ognl.setValue(expression, contextAttributes, target, value);
|
||||
// TODO context map
|
||||
Ognl.setValue(expression, Collections.EMPTY_MAP, target, value);
|
||||
} catch (OgnlException e) {
|
||||
throw new EvaluationException(new SetValueAttempt(this, target, value, context), e);
|
||||
throw new EvaluationException(new SetValueAttempt(this, target, value), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import ognl.PropertyAccessor;
|
||||
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ParserException;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.binding.expression.support.AbstractExpressionParser;
|
||||
|
||||
/**
|
||||
@@ -33,10 +32,6 @@ import org.springframework.binding.expression.support.AbstractExpressionParser;
|
||||
public class OgnlExpressionParser extends AbstractExpressionParser {
|
||||
|
||||
protected Expression doParseExpression(String expressionString) throws ParserException {
|
||||
return doParseSettableExpression(expressionString);
|
||||
}
|
||||
|
||||
public SettableExpression doParseSettableExpression(String expressionString) throws ParserException {
|
||||
try {
|
||||
return new OgnlExpression(Ognl.parseExpression(expressionString));
|
||||
} catch (OgnlException e) {
|
||||
|
||||
@@ -20,8 +20,8 @@ import java.util.List;
|
||||
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.ExpressionVariable;
|
||||
import org.springframework.binding.expression.ParserException;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -80,27 +80,17 @@ public abstract class AbstractExpressionParser implements ExpressionParser {
|
||||
this.expressionSuffix = expressionSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not given criteria are expressed as an expression.
|
||||
*/
|
||||
public boolean isDelimitedExpression(String expressionString) {
|
||||
int prefixIndex = expressionString.indexOf(getExpressionPrefix());
|
||||
if (prefixIndex == -1) {
|
||||
return false;
|
||||
}
|
||||
int suffixIndex = expressionString.indexOf(getExpressionSuffix(), prefixIndex);
|
||||
if (suffixIndex == -1) {
|
||||
return false;
|
||||
} else {
|
||||
if (suffixIndex == prefixIndex + getExpressionPrefix().length()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public boolean isEvalExpressionString(String string) {
|
||||
return string.startsWith(expressionPrefix) && string.endsWith(expressionSuffix);
|
||||
}
|
||||
|
||||
public final Expression parseExpression(String expressionString) throws ParserException {
|
||||
public String parseEvalExpressionString(String string) {
|
||||
return encloseInDelimitersIfNecessary(string);
|
||||
}
|
||||
|
||||
public Expression parseExpression(String expressionString, Class expressionTargetType,
|
||||
Class expectedEvaluationResultType, ExpressionVariable[] expressionVariables) throws ParserException {
|
||||
// TODO variables
|
||||
Expression[] expressions = parseExpressions(expressionString);
|
||||
if (expressions.length == 1) {
|
||||
return expressions[0];
|
||||
@@ -109,15 +99,12 @@ public abstract class AbstractExpressionParser implements ExpressionParser {
|
||||
}
|
||||
}
|
||||
|
||||
public final SettableExpression parseSettableExpression(String expressionString) throws ParserException,
|
||||
UnsupportedOperationException {
|
||||
expressionString = expressionString.trim();
|
||||
// a settable expression should just be a single expression
|
||||
if (expressionString.startsWith(getExpressionPrefix()) && expressionString.endsWith(getExpressionSuffix())) {
|
||||
expressionString = expressionString.substring(getExpressionPrefix().length(), expressionString.length()
|
||||
- getExpressionSuffix().length());
|
||||
private String encloseInDelimitersIfNecessary(String expressionString) {
|
||||
if (isEvalExpressionString(expressionString)) {
|
||||
return expressionString;
|
||||
} else {
|
||||
return expressionPrefix + expressionString + expressionSuffix;
|
||||
}
|
||||
return doParseSettableExpression(expressionString);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,14 +178,4 @@ public abstract class AbstractExpressionParser implements ExpressionParser {
|
||||
*/
|
||||
protected abstract Expression doParseExpression(String expressionString) throws ParserException;
|
||||
|
||||
/**
|
||||
* Template method for parsing a filtered settable expression string. Subclasses should override.
|
||||
* @param expressionString the expression string
|
||||
* @return the parsed expression
|
||||
* @throws ParserException an exception occured during parsing
|
||||
* @throws UnsupportedOperationException this parser does not support settable expressions
|
||||
*/
|
||||
protected abstract SettableExpression doParseSettableExpression(String expressionString) throws ParserException,
|
||||
UnsupportedOperationException;
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.binding.expression.support;
|
||||
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.binding.expression.EvaluationAttempt;
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.SetValueAttempt;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An expression evaluator that uses the Spring bean wrapper.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class BeanWrapperExpression implements SettableExpression {
|
||||
|
||||
/**
|
||||
* The expression.
|
||||
*/
|
||||
private String expression;
|
||||
|
||||
public BeanWrapperExpression(String expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return expression.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof BeanWrapperExpression)) {
|
||||
return false;
|
||||
}
|
||||
BeanWrapperExpression other = (BeanWrapperExpression) o;
|
||||
return expression.equals(other.expression);
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
|
||||
try {
|
||||
return new BeanWrapperImpl(target).getPropertyValue(expression);
|
||||
} catch (BeansException e) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, target, context), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
|
||||
try {
|
||||
Assert.notNull(target, "The target object to evaluate is required");
|
||||
new BeanWrapperImpl(target).setPropertyValue(expression, value);
|
||||
} catch (BeansException e) {
|
||||
throw new EvaluationException(new SetValueAttempt(this, target, value, context), e);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.binding.expression.support;
|
||||
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ParserException;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
|
||||
/**
|
||||
* An expression parser that parses bean wrapper expressions.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class BeanWrapperExpressionParser extends AbstractExpressionParser {
|
||||
|
||||
protected Expression doParseExpression(String expressionString) throws ParserException {
|
||||
return doParseSettableExpression(expressionString);
|
||||
}
|
||||
|
||||
public SettableExpression doParseSettableExpression(String expressionString) throws ParserException {
|
||||
return new BeanWrapperExpression(expressionString);
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,9 @@ package org.springframework.binding.expression.support;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.SetValueAttempt;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -30,7 +28,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class CollectionAddingExpression implements SettableExpression {
|
||||
public class CollectionAddingExpression implements Expression {
|
||||
|
||||
/**
|
||||
* The expression that resolves a mutable collection reference.
|
||||
@@ -45,14 +43,14 @@ public class CollectionAddingExpression implements SettableExpression {
|
||||
this.collectionExpression = collectionExpression;
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
|
||||
return collectionExpression.evaluate(target, context);
|
||||
public Object getValue(Object target) throws EvaluationException {
|
||||
return collectionExpression.getValue(target);
|
||||
}
|
||||
|
||||
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
|
||||
Object result = evaluate(target, context);
|
||||
public void setValue(Object target, Object value) throws EvaluationException {
|
||||
Object result = getValue(target);
|
||||
if (result == null) {
|
||||
throw new EvaluationException(new SetValueAttempt(this, target, value, null), new IllegalArgumentException(
|
||||
throw new EvaluationException(new SetValueAttempt(this, target, value), new IllegalArgumentException(
|
||||
"The collection expression evaluated to a [null] reference"));
|
||||
}
|
||||
Assert.isInstanceOf(Collection.class, result, "Not a collection: ");
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.binding.expression.support;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
@@ -41,14 +40,18 @@ public class CompositeStringExpression implements Expression {
|
||||
this.expressions = expressions;
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext evaluationContext) throws EvaluationException {
|
||||
public Object getValue(Object target) throws EvaluationException {
|
||||
StringBuffer buffer = new StringBuffer(128);
|
||||
for (int i = 0; i < expressions.length; i++) {
|
||||
buffer.append(expressions[i].evaluate(target, evaluationContext));
|
||||
buffer.append(expressions[i].getValue(target));
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void setValue(Object target, Object value) throws EvaluationException {
|
||||
throw new UnsupportedOperationException("Cannot set a composite string expression value");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("expressions", expressions).toString();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.binding.expression.support;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -25,7 +24,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StaticExpression implements Expression {
|
||||
public final class StaticExpression implements Expression {
|
||||
|
||||
/**
|
||||
* The value expression.
|
||||
@@ -56,10 +55,14 @@ public class StaticExpression implements Expression {
|
||||
return ObjectUtils.nullSafeEquals(value, other.value);
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
|
||||
public Object getValue(Object target) throws EvaluationException {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object target, Object value) throws EvaluationException {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -41,7 +40,7 @@ public class Mapping implements AttributeMapper {
|
||||
/**
|
||||
* The target expression to set on a target object to map to.
|
||||
*/
|
||||
private final SettableExpression targetExpression;
|
||||
private final Expression targetExpression;
|
||||
|
||||
/**
|
||||
* A type converter to apply during the mapping process.
|
||||
@@ -59,7 +58,7 @@ public class Mapping implements AttributeMapper {
|
||||
* @param targetExpression the target expression
|
||||
* @param typeConverter a type converter
|
||||
*/
|
||||
public Mapping(Expression sourceExpression, SettableExpression targetExpression, ConversionExecutor typeConverter) {
|
||||
public Mapping(Expression sourceExpression, Expression targetExpression, ConversionExecutor typeConverter) {
|
||||
this(sourceExpression, targetExpression, typeConverter, false);
|
||||
}
|
||||
|
||||
@@ -70,8 +69,8 @@ public class Mapping implements AttributeMapper {
|
||||
* @param typeConverter a type converter
|
||||
* @param required whether or not this mapping is required
|
||||
*/
|
||||
protected Mapping(Expression sourceExpression, SettableExpression targetExpression,
|
||||
ConversionExecutor typeConverter, boolean required) {
|
||||
protected Mapping(Expression sourceExpression, Expression targetExpression, ConversionExecutor typeConverter,
|
||||
boolean required) {
|
||||
Assert.notNull(sourceExpression, "The source expression is required");
|
||||
Assert.notNull(targetExpression, "The target expression is required");
|
||||
this.sourceExpression = sourceExpression;
|
||||
@@ -88,7 +87,7 @@ public class Mapping implements AttributeMapper {
|
||||
*/
|
||||
public void map(Object source, Object target, MappingContext context) {
|
||||
// get source value
|
||||
Object sourceValue = sourceExpression.evaluate(source, null);
|
||||
Object sourceValue = sourceExpression.getValue(source);
|
||||
if (sourceValue == null) {
|
||||
if (required) {
|
||||
throw new RequiredMappingException("This mapping is required; evaluation of expression '"
|
||||
@@ -108,7 +107,7 @@ public class Mapping implements AttributeMapper {
|
||||
logger.debug("Mapping '" + sourceExpression + "' value [" + sourceValue + "] to target property '"
|
||||
+ targetExpression + "'; setting property value to [" + targetValue + "]");
|
||||
}
|
||||
targetExpression.evaluateToSet(target, targetValue, null);
|
||||
targetExpression.setValue(target, targetValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.support.DefaultConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.binding.expression.support.CollectionAddingExpression;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -61,7 +60,7 @@ public class MappingBuilder {
|
||||
/**
|
||||
* The target mapping settable expression.
|
||||
*/
|
||||
private SettableExpression targetExpression;
|
||||
private Expression targetExpression;
|
||||
|
||||
/**
|
||||
* The type of the object returned by evaluating the source expression.
|
||||
@@ -102,7 +101,7 @@ public class MappingBuilder {
|
||||
* @return this, to support call-chaining
|
||||
*/
|
||||
public MappingBuilder source(String expressionString) {
|
||||
sourceExpression = expressionParser.parseExpression(expressionString);
|
||||
sourceExpression = expressionParser.parseExpression(expressionString, Object.class, Object.class, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ public class MappingBuilder {
|
||||
* @return this, to support call-chaining
|
||||
*/
|
||||
public MappingBuilder target(String expressionString) {
|
||||
targetExpression = (SettableExpression) expressionParser.parseExpression(expressionString);
|
||||
targetExpression = expressionParser.parseExpression(expressionString, Object.class, Object.class, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -122,7 +121,8 @@ public class MappingBuilder {
|
||||
* @return this, to support call-chaining
|
||||
*/
|
||||
public MappingBuilder targetCollection(String expressionString) {
|
||||
targetExpression = new CollectionAddingExpression(expressionParser.parseSettableExpression(expressionString));
|
||||
targetExpression = new CollectionAddingExpression(expressionParser.parseExpression(expressionString,
|
||||
Object.class, Object.class, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ public class MappingBuilder {
|
||||
public Mapping value() {
|
||||
Assert.notNull(sourceExpression, "The source expression must be set at a minimum");
|
||||
if (targetExpression == null) {
|
||||
targetExpression = (SettableExpression) sourceExpression;
|
||||
targetExpression = sourceExpression;
|
||||
}
|
||||
ConversionExecutor typeConverter = null;
|
||||
if (sourceType != null) {
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.binding.mapping;
|
||||
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
|
||||
/**
|
||||
* A mapping that is required.
|
||||
@@ -32,7 +31,7 @@ public class RequiredMapping extends Mapping {
|
||||
* @param targetPropertyExpression the target property expression
|
||||
* @param typeConverter a type converter
|
||||
*/
|
||||
public RequiredMapping(Expression sourceExpression, SettableExpression targetPropertyExpression,
|
||||
public RequiredMapping(Expression sourceExpression, Expression targetPropertyExpression,
|
||||
ConversionExecutor typeConverter) {
|
||||
super(sourceExpression, targetPropertyExpression, typeConverter, true);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CachingMapDecorator;
|
||||
|
||||
/**
|
||||
* Default message context factory that simply stores messages indexed in a map by their source. Suitable for use in
|
||||
* most Spring applications that use Spring message sources for message resource bundles. Holds a reference to a Spring
|
||||
* message resource bundle for performing message text resolution.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class DefaultMessageContextFactory implements MessageContextFactory {
|
||||
|
||||
private MessageSource messageSource;
|
||||
|
||||
/**
|
||||
* Create a new message context factory.
|
||||
* @param messageSource
|
||||
*/
|
||||
public DefaultMessageContextFactory(MessageSource messageSource) {
|
||||
Assert.notNull(messageSource, "The message source is required");
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
public StateManageableMessageContext createMessageContext() {
|
||||
return new MessageContextImpl(messageSource);
|
||||
}
|
||||
|
||||
private static class MessageContextImpl implements StateManageableMessageContext {
|
||||
|
||||
private MessageSource messageSource;
|
||||
|
||||
private Map objectMessages = new CachingMapDecorator() {
|
||||
protected Object create(Object objectId) {
|
||||
return new ArrayList();
|
||||
}
|
||||
};
|
||||
|
||||
public MessageContextImpl(MessageSource messageSource) {
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
public Serializable createMessagesMemento() {
|
||||
return new HashMap(objectMessages);
|
||||
}
|
||||
|
||||
public void restoreMessages(Serializable messagesMemento) {
|
||||
this.objectMessages.putAll((Map) messagesMemento);
|
||||
}
|
||||
|
||||
public void addMessage(MessageResolver messageResolver) {
|
||||
Locale currentLocale = LocaleContextHolder.getLocale();
|
||||
Message message = messageResolver.resolveMessage(messageSource, currentLocale);
|
||||
List messages = (List) objectMessages.get(message.getSource());
|
||||
messages.add(message);
|
||||
}
|
||||
|
||||
public Message[] getMessages() {
|
||||
List messages = new ArrayList();
|
||||
Iterator i = objectMessages.keySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
messages.addAll((List) objectMessages.get(i.next()));
|
||||
}
|
||||
return (Message[]) messages.toArray(new Message[messages.size()]);
|
||||
}
|
||||
|
||||
public Message[] getMessages(Object source) {
|
||||
List messages = (List) objectMessages.get(source);
|
||||
return (Message[]) messages.toArray(new Message[messages.size()]);
|
||||
}
|
||||
|
||||
public void clearMessages() {
|
||||
objectMessages.clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An object of communication that provides text information from a source. For example, a validation message may inform
|
||||
* a web application user a business rule was violated. A messages comes from a source, has text providing the basis for
|
||||
* communication, and has severity indicating the priority or intensity of the message for its receiver.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class Message implements Serializable {
|
||||
|
||||
private Object source;
|
||||
|
||||
private String text;
|
||||
|
||||
private Severity severity;
|
||||
|
||||
/**
|
||||
* Creates a new message.
|
||||
* @param source the source of the message
|
||||
* @param text the message text
|
||||
* @param severity the message severity
|
||||
*/
|
||||
public Message(Object source, String text, Severity severity) {
|
||||
super();
|
||||
this.source = source;
|
||||
this.text = text;
|
||||
this.severity = severity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source of this message. The source is the object that sent the message.
|
||||
* @return the source
|
||||
*/
|
||||
public Object getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message text. The text is the message's communication payload.
|
||||
* @return the message text
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the severity of this message. The severity indicates the intensity or priority of the communication.
|
||||
* @return the message severity
|
||||
*/
|
||||
public Severity getSeverity() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
/**
|
||||
* A context for recording and retrieving messages for display.
|
||||
*/
|
||||
public interface MessageContext {
|
||||
|
||||
/**
|
||||
* Get all messages in this context. The messages returned should be suitable for display as-is.
|
||||
* @return the messages
|
||||
*/
|
||||
public Message[] getMessages();
|
||||
|
||||
/**
|
||||
* Get all messages in this context from the source provided.
|
||||
* @param source the source that recorded the message
|
||||
* @return the source's messages
|
||||
*/
|
||||
public Message[] getMessages(Object source);
|
||||
|
||||
/**
|
||||
* Add a new message to this context.
|
||||
* @param messageResolver the resolver that will resolve the message to be added
|
||||
*/
|
||||
public void addMessage(MessageResolver messageResolver);
|
||||
|
||||
/**
|
||||
* Clear all messages added to this context.
|
||||
*/
|
||||
public void clearMessages();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
/**
|
||||
* A factory for creating message context's whose internal state can be externally managed. Encapsulates the message
|
||||
* context implementation used in a given environment.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface MessageContextFactory {
|
||||
|
||||
/**
|
||||
* Create a new message context.
|
||||
* @return the message context, initially empty, capable of having its state managed by an external care-taker.
|
||||
*/
|
||||
public StateManageableMessageContext createMessageContext();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
|
||||
/**
|
||||
* A factory for a Message. Allows a Message to be internationalized and to be resolved from a
|
||||
* {@link MessageSource message resource bundle}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @see Message
|
||||
* @see MessageSource
|
||||
*/
|
||||
public interface MessageResolver {
|
||||
|
||||
/**
|
||||
* Resolve the message from the message source using the current locale.
|
||||
* @param messageSource the message source, an abstraction for a resource bundle
|
||||
* @param locale the current locale of this request
|
||||
* @return the resolved message
|
||||
*/
|
||||
public Message resolveMessage(MessageSource messageSource, Locale locale);
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
|
||||
/**
|
||||
* A convenient factory for creating {@link MessageResolver} objects programmatically. Often used by model code such as
|
||||
* validation logic to conveniently record validation messages. Supports the production of "text" message resolvers that
|
||||
* hard-code their message text, as well as message resolvers that retrieve their text from a
|
||||
* {@link MessageSource message resource bundle}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class Messages implements MessageResolver {
|
||||
|
||||
private Object source;
|
||||
|
||||
private String code;
|
||||
|
||||
private Severity severity;
|
||||
|
||||
private Object[] args;
|
||||
|
||||
private String defaultText;
|
||||
|
||||
private Messages(Object source, String code, Severity severity, Object[] args, String defaultText) {
|
||||
this.source = source;
|
||||
this.code = code;
|
||||
this.severity = severity;
|
||||
this.args = args;
|
||||
this.defaultText = defaultText;
|
||||
}
|
||||
|
||||
public Message resolveMessage(MessageSource messageSource, Locale locale) {
|
||||
if (messageSource != null && (code != null && code.length() > 0)) {
|
||||
return new Message(source, getMessageText(messageSource, locale), severity);
|
||||
} else {
|
||||
return new Message(source, defaultText, severity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a INFO {@link Message} with the text provided.
|
||||
* @param text the raw message text that will be used as-is
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages text(String text) {
|
||||
return new Messages(null, null, Severity.INFO, null, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Message} with the text and severity provided.
|
||||
* @param text the raw message text that will be used as-is
|
||||
* @param severity the desired message severity
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages text(String text, Severity severity) {
|
||||
return new Messages(null, null, severity, null, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#INFO info} {@link Message message} with its text
|
||||
* resolved from a message bundle by using the provided message code.
|
||||
* @param code the message code
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages info(String code) {
|
||||
return new Messages(null, code, Severity.INFO, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#WARNING warning} {@link Message message} with its text
|
||||
* resolved from a message bundle by using the provided message code.
|
||||
* @param code the message code
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages warning(String code) {
|
||||
return new Messages(null, code, Severity.WARNING, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#ERROR error} {@link Message message} with its text
|
||||
* resolved from a message bundle by using the provided message code.
|
||||
* @param code the message code
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages error(String code) {
|
||||
return new Messages(null, code, Severity.ERROR, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#INFO info} {@link Message message} with its text
|
||||
* resolved from a message bundle by using the provided message code and message arguments.
|
||||
* @param code the message code
|
||||
* @param args the message arguments
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages info(String code, Object[] args) {
|
||||
return new Messages(null, code, Severity.INFO, args, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#WARNING warning} {@link Message message} with its text
|
||||
* resolved from a message bundle by using the provided message code and message arguments.
|
||||
* @param code the message code
|
||||
* @param args the message arguments
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages warning(String code, Object[] args) {
|
||||
return new Messages(null, code, Severity.WARNING, args, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#ERROR error} {@link Message message} with its text
|
||||
* resolved from a message bundle by using the provided message code and message arguments.
|
||||
* @param code the message code
|
||||
* @param args the message arguments
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages error(String code, Object[] args) {
|
||||
return new Messages(null, code, Severity.ERROR, args, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#INFO info} {@link Message message} from the source with
|
||||
* the text provided.
|
||||
* @param source the source of the message
|
||||
* @param text the message text
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages text(Object source, String text) {
|
||||
return new Messages(source, null, Severity.INFO, null, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Message message} from the source with the text and severity
|
||||
* provided.
|
||||
* @param source the source of the message
|
||||
* @param text the message text
|
||||
* @param severity the message severity
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages text(Object source, String text, Severity severity) {
|
||||
return new Messages(source, null, severity, null, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#INFO info} {@link Message message} from the source with
|
||||
* its text resolved from a message bundle by using the provided message code.
|
||||
* @param source the source of the message
|
||||
* @param code the message code
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages info(Object source, String code) {
|
||||
return new Messages(source, code, Severity.INFO, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#WARNING warning} {@link Message message} from the
|
||||
* source with its text resolved from a message bundle by using the provided message code.
|
||||
* @param source the source of the message
|
||||
* @param code the message code
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages warning(Object source, String code) {
|
||||
return new Messages(source, code, Severity.WARNING, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#ERROR error} {@link Message message} from the source
|
||||
* with its text resolved from a message bundle by using the provided message code.
|
||||
* @param source the source of the message
|
||||
* @param code the message code
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages error(Object source, String code) {
|
||||
return new Messages(source, code, Severity.ERROR, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#INFO info} {@link Message message} from the source with
|
||||
* its text resolved from a message bundle by using the provided message code and message arguments.
|
||||
* @param source the source of the message
|
||||
* @param code the message code
|
||||
* @param args the message arguments
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages info(Object source, String code, Object[] args) {
|
||||
return new Messages(source, code, Severity.INFO, args, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#WARNING warning} {@link Message message} from the
|
||||
* source with its text resolved from a message bundle by using the provided message code and message arguments.
|
||||
* @param source the source of the message
|
||||
* @param code the message code
|
||||
* @param args the message arguments
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages warning(Object source, String code, Object[] args) {
|
||||
return new Messages(source, code, Severity.WARNING, args, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message resolver that creates a {@link Severity#ERROR error} {@link Message message} from the source
|
||||
* with its text resolved from a message bundle by using the provided message code and message arguments.
|
||||
* @param source the source of the message
|
||||
* @param code the message code
|
||||
* @param args the message arguments
|
||||
* @return the message resolver
|
||||
*/
|
||||
public static Messages error(Object source, String code, Object[] args) {
|
||||
return new Messages(source, code, Severity.ERROR, args, null);
|
||||
}
|
||||
|
||||
private String getMessageText(MessageSource source, Locale locale) {
|
||||
if (defaultText == null) {
|
||||
return source.getMessage(code, args, locale);
|
||||
} else {
|
||||
return source.getMessage(code, args, defaultText, locale);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
import org.springframework.core.enums.StaticLabeledEnum;
|
||||
|
||||
/**
|
||||
* Enum exposing supported message severities.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @see Message
|
||||
*/
|
||||
public class Severity extends StaticLabeledEnum {
|
||||
|
||||
/**
|
||||
* The "Informational" severity. Used to indicate a successful operation or result.
|
||||
*/
|
||||
public static final Severity INFO = new Severity(0, "Info");
|
||||
|
||||
/**
|
||||
* The "Warning" severity. Used to indicate there is a minor problem, or to inform the message receiver of possible
|
||||
* misuse, or to indicate a problem may arise in the future.
|
||||
*/
|
||||
public static final Severity WARNING = new Severity(1, "Warning");
|
||||
|
||||
/**
|
||||
* THe "Error" severity. Used to indicate a significant problem like a business rule violation.
|
||||
*/
|
||||
public static final Severity ERROR = new Severity(2, "Error");
|
||||
|
||||
private Severity(int code, String label) {
|
||||
super(code, label);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.springframework.binding.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A message context whose internal state can be managed by an external care-taker. State management employs the GOF
|
||||
* Memento pattern. This context can produce a serializable memento representing its internal state at any time. A
|
||||
* care-taker can then use that memento at a later time to restore any context instance to a previous state.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface StateManageableMessageContext extends MessageContext {
|
||||
|
||||
/**
|
||||
* Create a serializable memento (token) representing a snapshot of the internal state of this message context.
|
||||
* @return the messages memento
|
||||
*/
|
||||
public Serializable createMessagesMemento();
|
||||
|
||||
/**
|
||||
* Set the state of this context from the memento provided. After this call, the messages in this context will match
|
||||
* what is encapsulated inside the memento. Any previous state will be overridden.
|
||||
* @param messagesMemento the messages memento
|
||||
*/
|
||||
public void restoreMessages(Serializable messagesMemento);
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public class MethodInvoker {
|
||||
Object[] arguments = new Object[parameters.size()];
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
Parameter parameter = parameters.getParameter(i);
|
||||
Object argument = parameter.evaluateArgument(argumentSource, null);
|
||||
Object argument = parameter.evaluateArgument(argumentSource);
|
||||
arguments[i] = applyTypeConversion(argument, parameter.getType());
|
||||
}
|
||||
Class[] parameterTypes = parameters.getTypesArray();
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.binding.method;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -66,12 +65,11 @@ public class Parameter {
|
||||
|
||||
/**
|
||||
* Evaluate this method parameter against the provided argument source, returning a single method argument value.
|
||||
* @param argumentSource the meyhod argument source
|
||||
* @param context the evaluation context
|
||||
* @param argumentSource the method argument source
|
||||
* @return the method argument value
|
||||
*/
|
||||
public Object evaluateArgument(Object argumentSource, EvaluationContext context) {
|
||||
return name.evaluate(argumentSource, context);
|
||||
public Object evaluateArgument(Object argumentSource) {
|
||||
return name.getValue(argumentSource);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
Reference in New Issue
Block a user