updates for Binding code - able to retrieve the type descriptor for a property and ask detailed questions (eg getAnnotations())

This commit is contained in:
Andy Clement 2009-06-02 00:25:59 +00:00
parent 1e0207cf04
commit 1fc8abade7
5 changed files with 66 additions and 9 deletions

View File

@ -16,6 +16,8 @@
package org.springframework.expression;
import org.springframework.core.convert.TypeDescriptor;
/**
* An expression capable of evaluating itself against context objects. Encapsulates the details of a previously parsed
* expression string. Provides a common abstraction for expression evaluation independent of any language like OGNL or
@ -94,6 +96,26 @@ public interface Expression {
*/
public Class getValueType() throws EvaluationException;
/**
* Returns the most general type that can be passed to the {@link #setValue(EvaluationContext, Object)} method for
* the given context.
*
* @param context the context in which to evaluate the expression
* @return a type descriptor for the most general type of value that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) throws EvaluationException;
/**
* Returns the most general type that can be passed to the {@link #setValue(EvaluationContext, Object)} method using
* the default context.
*
* @return a type descriptor for the most general type of value that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
public TypeDescriptor getValueTypeDescriptor() throws EvaluationException;
/**
* Returns the original string used to create this expression, unmodified.
*

View File

@ -16,6 +16,7 @@
package org.springframework.expression.common;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
@ -78,6 +79,14 @@ public class CompositeStringExpression implements Expression {
return String.class;
}
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) {
return TypeDescriptor.valueOf(String.class);
}
public TypeDescriptor getValueTypeDescriptor() {
return TypeDescriptor.valueOf(String.class);
}
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression");
}

View File

@ -16,6 +16,7 @@
package org.springframework.expression.common;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
@ -55,6 +56,14 @@ public class LiteralExpression implements Expression {
return String.class;
}
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) {
return TypeDescriptor.valueOf(String.class);
}
public TypeDescriptor getValueTypeDescriptor() {
return TypeDescriptor.valueOf(String.class);
}
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
throw new EvaluationException(literalValue, "Cannot call setValue() on a LiteralExpression");
}

View File

@ -15,10 +15,12 @@
*/
package org.springframework.expression.spel;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.common.ExpressionUtils;
import org.springframework.expression.spel.ast.SpelNodeImpl;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
@ -33,13 +35,13 @@ public class SpelExpression implements Expression {
private final String expression;
public final SpelNode ast;
public final SpelNodeImpl ast;
/**
* Construct an expression, only used by the parser.
*/
public SpelExpression(String expression, SpelNode ast) {
public SpelExpression(String expression, SpelNodeImpl ast) {
this.expression = expression;
this.ast = ast;
}
@ -119,19 +121,35 @@ public class SpelExpression implements Expression {
* {@inheritDoc}
*/
public Class getValueType(EvaluationContext context) throws EvaluationException {
// TODO both getValueType() methods could use getValueInternal and return a type descriptor from the resultant TypedValue
Object value = getValue(context);
return (value != null ? value.getClass() : null);
ExpressionState eState = new ExpressionState(context);
TypeDescriptor typeDescriptor = this.ast.getValueInternal(eState).getTypeDescriptor();
return typeDescriptor.getType();
}
/**
* {@inheritDoc}
*/
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) throws EvaluationException {
ExpressionState eState = new ExpressionState(context);
TypeDescriptor typeDescriptor = this.ast.getValueInternal(eState).getTypeDescriptor();
return typeDescriptor;
}
/**
* {@inheritDoc}
*/
public Class getValueType() throws EvaluationException {
Object value = getValue();
return (value != null ? value.getClass() : null);
return this.ast.getValueInternal(new ExpressionState(new StandardEvaluationContext())).getTypeDescriptor().getType();
}
/**
* {@inheritDoc}
*/
public TypeDescriptor getValueTypeDescriptor() throws EvaluationException {
return this.ast.getValueInternal(new ExpressionState(new StandardEvaluationContext())).getTypeDescriptor();
}
/**
* {@inheritDoc}
*/

View File

@ -24,7 +24,6 @@ import org.springframework.expression.ParserContext;
import org.springframework.expression.common.TemplateAwareExpressionParser;
import org.springframework.expression.spel.SpelExpression;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.SpelNode;
import org.springframework.expression.spel.SpelParseException;
import org.springframework.expression.spel.ast.Assign;
import org.springframework.expression.spel.ast.BooleanLiteral;
@ -104,7 +103,7 @@ public class SpelExpressionParser extends TemplateAwareExpressionParser {
tokenStreamLength = tokenStream.size();
tokenStreamPointer = 0;
constructedNodes.clear();
SpelNode ast = eatExpression();
SpelNodeImpl ast = eatExpression();
if (moreTokens()) {
throw new SpelParseException(peekToken().startpos,SpelMessages.MORE_INPUT,toString(nextToken()));
}