Expression alignment and related polishing (backported from master)

This commit is contained in:
Juergen Hoeller
2017-07-14 15:41:38 +02:00
parent bffcd33ea3
commit bb6d9fabee
8 changed files with 273 additions and 257 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -58,7 +58,8 @@ public abstract class FileSystemUtils {
* @throws IOException in the case of I/O errors
*/
public static void copyRecursively(File src, File dest) throws IOException {
Assert.isTrue(src != null && (src.isDirectory() || src.isFile()), "Source File must denote a directory or file");
Assert.isTrue(src != null && (src.isDirectory() || src.isFile()),
"Source File must denote a directory or file");
Assert.notNull(dest, "Destination File must not be null");
doCopyRecursively(src, dest);
}
@@ -86,9 +87,7 @@ public abstract class FileSystemUtils {
dest.createNewFile();
}
catch (IOException ex) {
IOException ioex = new IOException("Failed to create file: " + dest);
ioex.initCause(ex);
throw ioex;
throw new IOException("Failed to create file: " + dest, ex);
}
FileCopyUtils.copy(src, dest);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 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.
@@ -29,6 +29,12 @@ import org.springframework.core.convert.TypeDescriptor;
*/
public interface Expression {
/**
* Return the original string used to create this expression, unmodified.
* @return the original expression string
*/
String getExpressionString();
/**
* Evaluate this expression in the default standard context.
* @return the evaluation result
@@ -36,14 +42,6 @@ public interface Expression {
*/
Object getValue() throws EvaluationException;
/**
* Evaluate this expression against the specified root object
* @param rootObject the root object against which properties/etc will be resolved
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
Object getValue(Object rootObject) throws EvaluationException;
/**
* Evaluate the expression in the default context. If the result of the evaluation does not match (and
* cannot be converted to) the expected result type then an exception will be returned.
@@ -53,6 +51,14 @@ public interface Expression {
*/
<T> T getValue(Class<T> desiredResultType) throws EvaluationException;
/**
* Evaluate this expression against the specified root object
* @param rootObject the root object against which properties/etc will be resolved
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
Object getValue(Object rootObject) throws EvaluationException;
/**
* Evaluate the expression in the default context against the specified root object. If the
* result of the evaluation does not match (and cannot be converted to) the expected result type
@@ -151,7 +157,7 @@ public interface Expression {
TypeDescriptor getValueTypeDescriptor() throws EvaluationException;
/**
* Returns the most general type that can be passed to the {@link #setValue(EvaluationContext, Object)}
* Return the most general type that can be passed to the {@link #setValue(EvaluationContext, Object)}
* method using the default context.
* @param rootObject the root object against which to evaluate the expression
* @return a type descriptor for the most general type of value that can be set on this context
@@ -160,7 +166,7 @@ public interface Expression {
TypeDescriptor getValueTypeDescriptor(Object rootObject) throws EvaluationException;
/**
* Returns the most general type that can be passed to the {@link #setValue(EvaluationContext, Object)}
* Return 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
@@ -169,7 +175,7 @@ public interface Expression {
TypeDescriptor getValueTypeDescriptor(EvaluationContext context) throws EvaluationException;
/**
* Returns the most general type that can be passed to the {@link #setValue(EvaluationContext, Object)} method for
* Return the most general type that can be passed to the {@link #setValue(EvaluationContext, Object)} method for
* the given context. The supplied root object overrides any specified in the context.
* @param context the context in which to evaluate the expression
* @param rootObject the root object against which to evaluate the expression
@@ -178,6 +184,14 @@ public interface Expression {
*/
TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject) throws EvaluationException;
/**
* Determine if an expression can be written to, i.e. setValue() can be called.
* @param rootObject the root object against which to evaluate the expression
* @return true if the expression is writable
* @throws EvaluationException if there is a problem determining if it is writable
*/
boolean isWritable(Object rootObject) throws EvaluationException;
/**
* Determine if an expression can be written to, i.e. setValue() can be called.
* @param context the context in which the expression should be checked
@@ -196,23 +210,6 @@ public interface Expression {
*/
boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException;
/**
* Determine if an expression can be written to, i.e. setValue() can be called.
* @param rootObject the root object against which to evaluate the expression
* @return true if the expression is writable
* @throws EvaluationException if there is a problem determining if it is writable
*/
boolean isWritable(Object rootObject) throws EvaluationException;
/**
* Set this expression in the provided context to the value provided.
*
* @param context the context in which to set the value of the expression
* @param value the new value
* @throws EvaluationException if there is a problem during evaluation
*/
void setValue(EvaluationContext context, Object value) throws EvaluationException;
/**
* Set this expression in the provided context to the value provided.
* @param rootObject the root object against which to evaluate the expression
@@ -221,6 +218,14 @@ public interface Expression {
*/
void setValue(Object rootObject, Object value) throws EvaluationException;
/**
* Set this expression in the provided context to the value provided.
* @param context the context in which to set the value of the expression
* @param value the new value
* @throws EvaluationException if there is a problem during evaluation
*/
void setValue(EvaluationContext context, Object value) throws EvaluationException;
/**
* Set this expression in the provided context to the value provided.
* The supplied root object overrides any specified in the context.
@@ -231,10 +236,4 @@ public interface Expression {
*/
void setValue(EvaluationContext context, Object rootObject, Object value) throws EvaluationException;
/**
* Returns the original string used to create this expression, unmodified.
* @return the original expression string
*/
String getExpressionString();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 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.
@@ -58,6 +58,10 @@ public class CompositeStringExpression implements Expression {
return this.expressionString;
}
public final Expression[] getExpressions() {
return this.expressions;
}
@Override
public String getValue() throws EvaluationException {
StringBuilder sb = new StringBuilder();
@@ -70,6 +74,12 @@ public class CompositeStringExpression implements Expression {
return sb.toString();
}
@Override
public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
Object value = getValue();
return ExpressionUtils.convertTypedValue(null, new TypedValue(value), expectedResultType);
}
@Override
public String getValue(Object rootObject) throws EvaluationException {
StringBuilder sb = new StringBuilder();
@@ -82,6 +92,12 @@ public class CompositeStringExpression implements Expression {
return sb.toString();
}
@Override
public <T> T getValue(Object rootObject, Class<T> desiredResultType) throws EvaluationException {
Object value = getValue(rootObject);
return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType);
}
@Override
public String getValue(EvaluationContext context) throws EvaluationException {
StringBuilder sb = new StringBuilder();
@@ -94,6 +110,14 @@ public class CompositeStringExpression implements Expression {
return sb.toString();
}
@Override
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType)
throws EvaluationException {
Object value = getValue(context);
return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType);
}
@Override
public String getValue(EvaluationContext context, Object rootObject) throws EvaluationException {
StringBuilder sb = new StringBuilder();
@@ -107,8 +131,11 @@ public class CompositeStringExpression implements Expression {
}
@Override
public Class<?> getValueType(EvaluationContext context) {
return String.class;
public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> desiredResultType)
throws EvaluationException {
Object value = getValue(context,rootObject);
return ExpressionUtils.convertTypedValue(context, new TypedValue(value), desiredResultType);
}
@Override
@@ -117,53 +144,8 @@ public class CompositeStringExpression implements Expression {
}
@Override
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) {
return TypeDescriptor.valueOf(String.class);
}
@Override
public TypeDescriptor getValueTypeDescriptor() {
return TypeDescriptor.valueOf(String.class);
}
@Override
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression");
}
@Override
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) throws EvaluationException {
Object value = getValue(context);
return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType);
}
@Override
public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
Object value = getValue();
return ExpressionUtils.convertTypedValue(null, new TypedValue(value), expectedResultType);
}
@Override
public boolean isWritable(EvaluationContext context) {
return false;
}
public Expression[] getExpressions() {
return this.expressions;
}
@Override
public <T> T getValue(Object rootObject, Class<T> desiredResultType) throws EvaluationException {
Object value = getValue(rootObject);
return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType);
}
@Override
public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> desiredResultType)
throws EvaluationException {
Object value = getValue(context,rootObject);
return ExpressionUtils.convertTypedValue(context, new TypedValue(value), desiredResultType);
public Class<?> getValueType(EvaluationContext context) {
return String.class;
}
@Override
@@ -176,24 +158,26 @@ public class CompositeStringExpression implements Expression {
return String.class;
}
@Override
public TypeDescriptor getValueTypeDescriptor() {
return TypeDescriptor.valueOf(String.class);
}
@Override
public TypeDescriptor getValueTypeDescriptor(Object rootObject) throws EvaluationException {
return TypeDescriptor.valueOf(String.class);
}
@Override
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject) throws EvaluationException {
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) {
return TypeDescriptor.valueOf(String.class);
}
@Override
public boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException {
return false;
}
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject)
throws EvaluationException {
@Override
public void setValue(EvaluationContext context, Object rootObject, Object value) throws EvaluationException {
throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression");
return TypeDescriptor.valueOf(String.class);
}
@Override
@@ -201,9 +185,29 @@ public class CompositeStringExpression implements Expression {
return false;
}
@Override
public boolean isWritable(EvaluationContext context) {
return false;
}
@Override
public boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException {
return false;
}
@Override
public void setValue(Object rootObject, Object value) throws EvaluationException {
throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression");
}
@Override
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression");
}
@Override
public void setValue(EvaluationContext context, Object rootObject, Object value) throws EvaluationException {
throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 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.
@@ -25,10 +25,11 @@ import org.springframework.expression.TypedValue;
/**
* A very simple hardcoded implementation of the Expression interface that represents a
* string literal. It is used with CompositeStringExpression when representing a template
* expression which is made up of pieces - some being real expressions to be handled by an
* EL implementation like Spel, and some being just textual elements.
* expression which is made up of pieces - some being real expressions to be handled by
* an EL implementation like SpEL, and some being just textual elements.
*
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
public class LiteralExpression implements Expression {
@@ -47,45 +48,14 @@ public class LiteralExpression implements Expression {
return this.literalValue;
}
@Override
public String getValue() {
return this.literalValue;
}
@Override
public String getValue(EvaluationContext context) {
return this.literalValue;
}
@Override
public String getValue(Object rootObject) {
return this.literalValue;
}
@Override
public Class<?> getValueType(EvaluationContext context) {
return String.class;
}
@Override
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) {
return TypeDescriptor.valueOf(String.class);
}
@Override
public TypeDescriptor getValueTypeDescriptor() {
return TypeDescriptor.valueOf(String.class);
}
@Override
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
}
@Override
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) throws EvaluationException {
Object value = getValue(context);
return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType);
public String getValue() {
return this.literalValue;
}
@Override
@@ -95,13 +65,8 @@ public class LiteralExpression implements Expression {
}
@Override
public boolean isWritable(EvaluationContext context) {
return false;
}
@Override
public Class<?> getValueType() {
return String.class;
public String getValue(Object rootObject) {
return this.literalValue;
}
@Override
@@ -110,17 +75,37 @@ public class LiteralExpression implements Expression {
return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType);
}
@Override
public String getValue(EvaluationContext context) {
return this.literalValue;
}
@Override
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType)
throws EvaluationException {
Object value = getValue(context);
return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType);
}
@Override
public String getValue(EvaluationContext context, Object rootObject) throws EvaluationException {
return this.literalValue;
}
@Override
public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> desiredResultType) throws EvaluationException {
public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> desiredResultType)
throws EvaluationException {
Object value = getValue(context, rootObject);
return ExpressionUtils.convertTypedValue(context, new TypedValue(value), desiredResultType);
}
@Override
public Class<?> getValueType() {
return String.class;
}
@Override
public Class<?> getValueType(Object rootObject) throws EvaluationException {
return String.class;
@@ -131,28 +116,38 @@ public class LiteralExpression implements Expression {
return String.class;
}
@Override
public TypeDescriptor getValueTypeDescriptor() {
return TypeDescriptor.valueOf(String.class);
}
@Override
public TypeDescriptor getValueTypeDescriptor(Object rootObject) throws EvaluationException {
return TypeDescriptor.valueOf(String.class);
}
@Override
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) {
return TypeDescriptor.valueOf(String.class);
}
@Override
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject) throws EvaluationException {
return TypeDescriptor.valueOf(String.class);
}
@Override
public boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException {
public boolean isWritable(Object rootObject) throws EvaluationException {
return false;
}
@Override
public void setValue(EvaluationContext context, Object rootObject, Object value) throws EvaluationException {
throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
public boolean isWritable(EvaluationContext context) {
return false;
}
@Override
public boolean isWritable(Object rootObject) throws EvaluationException {
public boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException {
return false;
}
@@ -161,4 +156,14 @@ public class LiteralExpression implements Expression {
throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
}
@Override
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
}
@Override
public void setValue(EvaluationContext context, Object rootObject, Object value) throws EvaluationException {
throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 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.
@@ -40,6 +40,7 @@ import org.springframework.util.Assert;
* references to types, beans, properties, and methods.
*
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
public class SpelExpression implements Expression {
@@ -104,13 +105,20 @@ public class SpelExpression implements Expression {
// implementing Expression
@Override
public String getExpressionString() {
return this.expression;
}
@Override
public Object getValue() throws EvaluationException {
Object result;
if (this.compiledAst != null) {
try {
TypedValue contextRoot = evaluationContext == null ? null : evaluationContext.getRootObject();
return this.compiledAst.getValue(contextRoot == null ? null : contextRoot.getValue(), evaluationContext);
TypedValue contextRoot =
(this.evaluationContext != null ? this.evaluationContext.getRootObject() : null);
return this.compiledAst.getValue(
(contextRoot != null ? contextRoot.getValue() : null), this.evaluationContext);
}
catch (Throwable ex) {
// If running in mixed mode, revert to interpreted
@@ -130,6 +138,42 @@ public class SpelExpression implements Expression {
return result;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
if (this.compiledAst != null) {
try {
TypedValue contextRoot =
(this.evaluationContext != null ? this.evaluationContext.getRootObject() : null);
Object result = this.compiledAst.getValue(
(contextRoot != null ? contextRoot.getValue() : null), this.evaluationContext);
if (expectedResultType == null) {
return (T) result;
}
else {
return ExpressionUtils.convertTypedValue(
getEvaluationContext(), new TypedValue(result), expectedResultType);
}
}
catch (Throwable ex) {
// If running in mixed mode, revert to interpreted
if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) {
this.interpretedCount = 0;
this.compiledAst = null;
}
else {
// Running in SpelCompilerMode.immediate mode - propagate exception to caller
throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION);
}
}
}
ExpressionState expressionState = new ExpressionState(getEvaluationContext(), this.configuration);
TypedValue typedResultValue = this.ast.getTypedValue(expressionState);
checkCompile(expressionState);
return ExpressionUtils.convertTypedValue(
expressionState.getEvaluationContext(), typedResultValue, expectedResultType);
}
@Override
public Object getValue(Object rootObject) throws EvaluationException {
Object result;
@@ -149,44 +193,13 @@ public class SpelExpression implements Expression {
}
}
}
ExpressionState expressionState = new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration);
ExpressionState expressionState =
new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration);
result = this.ast.getValue(expressionState);
checkCompile(expressionState);
return result;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
if (this.compiledAst != null) {
try {
TypedValue contextRoot = evaluationContext == null ? null : evaluationContext.getRootObject();
Object result = this.compiledAst.getValue(contextRoot == null ? null : contextRoot.getValue(), evaluationContext);
if (expectedResultType == null) {
return (T)result;
}
else {
return ExpressionUtils.convertTypedValue(getEvaluationContext(), new TypedValue(result), expectedResultType);
}
}
catch (Throwable ex) {
// If running in mixed mode, revert to interpreted
if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) {
this.interpretedCount = 0;
this.compiledAst = null;
}
else {
// Running in SpelCompilerMode.immediate mode - propagate exception to caller
throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION);
}
}
}
ExpressionState expressionState = new ExpressionState(getEvaluationContext(), this.configuration);
TypedValue typedResultValue = this.ast.getTypedValue(expressionState);
checkCompile(expressionState);
return ExpressionUtils.convertTypedValue(expressionState.getEvaluationContext(), typedResultValue, expectedResultType);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getValue(Object rootObject, Class<T> expectedResultType) throws EvaluationException {
@@ -197,7 +210,8 @@ public class SpelExpression implements Expression {
return (T)result;
}
else {
return ExpressionUtils.convertTypedValue(getEvaluationContext(), new TypedValue(result), expectedResultType);
return ExpressionUtils.convertTypedValue(
getEvaluationContext(), new TypedValue(result), expectedResultType);
}
}
catch (Throwable ex) {
@@ -212,10 +226,12 @@ public class SpelExpression implements Expression {
}
}
}
ExpressionState expressionState = new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration);
ExpressionState expressionState =
new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration);
TypedValue typedResultValue = this.ast.getTypedValue(expressionState);
checkCompile(expressionState);
return ExpressionUtils.convertTypedValue(expressionState.getEvaluationContext(), typedResultValue, expectedResultType);
return ExpressionUtils.convertTypedValue(
expressionState.getEvaluationContext(), typedResultValue, expectedResultType);
}
@Override
@@ -223,8 +239,8 @@ public class SpelExpression implements Expression {
Assert.notNull(context, "EvaluationContext is required");
if (compiledAst!= null) {
try {
TypedValue contextRoot = context == null ? null : context.getRootObject();
return this.compiledAst.getValue(contextRoot != null ? contextRoot.getValue() : null, context);
TypedValue contextRoot = context.getRootObject();
return this.compiledAst.getValue(contextRoot.getValue(), context);
}
catch (Throwable ex) {
// If running in mixed mode, revert to interpreted
@@ -244,6 +260,39 @@ public class SpelExpression implements Expression {
return result;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) throws EvaluationException {
Assert.notNull(context, "EvaluationContext is required");
if (this.compiledAst != null) {
try {
TypedValue contextRoot = context.getRootObject();
Object result = this.compiledAst.getValue(contextRoot.getValue(), context);
if (expectedResultType != null) {
return ExpressionUtils.convertTypedValue(context, new TypedValue(result), expectedResultType);
}
else {
return (T) result;
}
}
catch (Throwable ex) {
// If running in mixed mode, revert to interpreted
if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) {
this.interpretedCount = 0;
this.compiledAst = null;
}
else {
// Running in SpelCompilerMode.immediate mode - propagate exception to caller
throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION);
}
}
}
ExpressionState expressionState = new ExpressionState(context, this.configuration);
TypedValue typedResultValue = this.ast.getTypedValue(expressionState);
checkCompile(expressionState);
return ExpressionUtils.convertTypedValue(context, typedResultValue, expectedResultType);
}
@Override
public Object getValue(EvaluationContext context, Object rootObject) throws EvaluationException {
Assert.notNull(context, "EvaluationContext is required");
@@ -271,39 +320,9 @@ public class SpelExpression implements Expression {
@SuppressWarnings("unchecked")
@Override
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) throws EvaluationException {
if (this.compiledAst != null) {
try {
TypedValue contextRoot = context == null ? null : context.getRootObject();
Object result = this.compiledAst.getValue(contextRoot==null?null:contextRoot.getValue(),context);
if (expectedResultType != null) {
return ExpressionUtils.convertTypedValue(context, new TypedValue(result), expectedResultType);
}
else {
return (T) result;
}
}
catch (Throwable ex) {
// If running in mixed mode, revert to interpreted
if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) {
this.interpretedCount = 0;
this.compiledAst = null;
}
else {
// Running in SpelCompilerMode.immediate mode - propagate exception to caller
throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION);
}
}
}
ExpressionState expressionState = new ExpressionState(context, this.configuration);
TypedValue typedResultValue = this.ast.getTypedValue(expressionState);
checkCompile(expressionState);
return ExpressionUtils.convertTypedValue(context, typedResultValue, expectedResultType);
}
public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> expectedResultType)
throws EvaluationException {
@SuppressWarnings("unchecked")
@Override
public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> expectedResultType) throws EvaluationException {
if (this.compiledAst != null) {
try {
Object result = this.compiledAst.getValue(rootObject,context);
@@ -377,15 +396,17 @@ public class SpelExpression implements Expression {
}
@Override
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject) throws EvaluationException {
public TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject)
throws EvaluationException {
Assert.notNull(context, "EvaluationContext is required");
ExpressionState expressionState = new ExpressionState(context, toTypedValue(rootObject), this.configuration);
return this.ast.getValueInternal(expressionState).getTypeDescriptor();
}
@Override
public String getExpressionString() {
return this.expression;
public boolean isWritable(Object rootObject) throws EvaluationException {
return this.ast.isWritable(new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration));
}
@Override
@@ -394,17 +415,18 @@ public class SpelExpression implements Expression {
return this.ast.isWritable(new ExpressionState(context, this.configuration));
}
@Override
public boolean isWritable(Object rootObject) throws EvaluationException {
return this.ast.isWritable(new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration));
}
@Override
public boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException {
Assert.notNull(context, "EvaluationContext is required");
return this.ast.isWritable(new ExpressionState(context, toTypedValue(rootObject), this.configuration));
}
@Override
public void setValue(Object rootObject, Object value) throws EvaluationException {
this.ast.setValue(
new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration), value);
}
@Override
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
Assert.notNull(context, "EvaluationContext is required");
@@ -412,12 +434,9 @@ public class SpelExpression implements Expression {
}
@Override
public void setValue(Object rootObject, Object value) throws EvaluationException {
this.ast.setValue(new ExpressionState(getEvaluationContext(), toTypedValue(rootObject), this.configuration), value);
}
public void setValue(EvaluationContext context, Object rootObject, Object value)
throws EvaluationException {
@Override
public void setValue(EvaluationContext context, Object rootObject, Object value) throws EvaluationException {
Assert.notNull(context, "EvaluationContext is required");
this.ast.setValue(new ExpressionState(context, toTypedValue(rootObject), this.configuration), value);
}
@@ -502,12 +521,7 @@ public class SpelExpression implements Expression {
}
private TypedValue toTypedValue(Object object) {
if (object == null) {
return TypedValue.NULL;
}
else {
return new TypedValue(object);
}
return (object != null ? new TypedValue(object) : TypedValue.NULL);
}
}

View File

@@ -453,7 +453,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
expression = parser.parseExpression("T(Integer).valueOf(42)");
expression.getValue(Integer.class);
assertCanCompile(expression);
assertEquals(new Integer(42), expression.getValue(null, Integer.class));
assertEquals(new Integer(42), expression.getValue(Integer.class));
// Code gen is different for -1 .. 6 because there are bytecode instructions specifically for those
// values
@@ -832,9 +832,9 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
assertEquals("4.0", expression.getValue(ctx).toString());
}
// Confirms visibility of what is being called.
@Test
public void functionReferenceVisibility_SPR12359() throws Exception {
// Confirms visibility of what is being called.
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] {"1"});
context.registerFunction("doCompare", SomeCompareMethod.class.getDeclaredMethod(
"compare", Object.class, Object.class));
@@ -845,7 +845,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
assertCantCompile(expression);
// type not public but method is
context = new StandardEvaluationContext(new Object[] {"1"});
context = new StandardEvaluationContext(new Object[] {"1"});
context.registerFunction("doCompare", SomeCompareMethod.class.getDeclaredMethod(
"compare2", Object.class, Object.class));
context.setVariable("arg", "2");
@@ -856,7 +856,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
@Test
public void functionReferenceNonCompilableArguments_SPR12359() throws Exception {
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] {"1"});
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] {"1"});
context.registerFunction("negate", SomeCompareMethod2.class.getDeclaredMethod(
"negate", Integer.TYPE));
context.setVariable("arg", "2");
@@ -3072,7 +3072,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, getClass().getClassLoader()));
Person3 person = new Person3("foo", 1);
SpelExpression expression = parser.parseRaw("#it?.age?.equals([0])");
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] { 1 });
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] {1});
context.setVariable("it", person);
expression.setEvaluationContext(context);
assertTrue(expression.getValue(Boolean.class));
@@ -3099,8 +3099,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
// code generation for ENGLISH should notice there is something on the stack that
// is not required and pop it off.
expression = parser.parseExpression("#userId.toString().toLowerCase(T(java.util.Locale).ENGLISH)");
StandardEvaluationContext context =
new StandardEvaluationContext();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("userId", "RoDnEy");
assertEquals("rodney", expression.getValue(context));
assertCanCompile(expression);
@@ -3249,8 +3248,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
expression = parser.parseExpression("#it?.age.equals([0])");
Person person = new Person(1);
StandardEvaluationContext context =
new StandardEvaluationContext(new Object[] { person.getAge() });
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] {person.getAge()});
context.setVariable("it", person);
assertTrue(expression.getValue(context, Boolean.class));
assertCanCompile(expression);
@@ -3258,26 +3256,23 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
// Variant of above more like what was in the bug report:
SpelExpressionParser parser = new SpelExpressionParser(
new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
getClass().getClassLoader()));
new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, getClass().getClassLoader()));
SpelExpression ex = parser.parseRaw("#it?.age.equals([0])");
context = new StandardEvaluationContext(new Object[] { person.getAge() });
context = new StandardEvaluationContext(new Object[] {person.getAge()});
context.setVariable("it", person);
assertTrue(ex.getValue(context, Boolean.class));
assertTrue(ex.getValue(context, Boolean.class));
PersonInOtherPackage person2 = new PersonInOtherPackage(1);
ex = parser.parseRaw("#it?.age.equals([0])");
context =
new StandardEvaluationContext(new Object[] { person2.getAge() });
context = new StandardEvaluationContext(new Object[] {person2.getAge()});
context.setVariable("it", person2);
assertTrue(ex.getValue(context, Boolean.class));
assertTrue(ex.getValue(context, Boolean.class));
ex = parser.parseRaw("#it?.age.equals([0])");
context =
new StandardEvaluationContext(new Object[] { person2.getAge() });
context = new StandardEvaluationContext(new Object[] {person2.getAge()});
context.setVariable("it", person2);
assertTrue((Boolean)ex.getValue(context));
assertTrue((Boolean)ex.getValue(context));

View File

@@ -165,7 +165,8 @@ public class Jaxb2CollectionHttpMessageConverter<T extends Collection>
return result;
}
catch (UnmarshalException ex) {
throw new HttpMessageNotReadableException("Could not unmarshal to [" + elementClass + "]: " + ex.getMessage(), ex);
throw new HttpMessageNotReadableException(
"Could not unmarshal to [" + elementClass + "]: " + ex.getMessage(), ex);
}
catch (JAXBException ex) {
throw new HttpMessageConversionException("Could not instantiate JAXBContext: " + ex.getMessage(), ex);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -140,8 +140,7 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
catch (NullPointerException ex) {
if (!isSupportDtd()) {
throw new HttpMessageNotReadableException("NPE while unmarshalling. " +
"This can happen on JDK 1.6 due to the presence of DTD " +
"declarations, which are disabled.", ex);
"This can happen due to the presence of DTD declarations which are disabled.", ex);
}
throw ex;
}