rearranged spel subpackages in order to avoid package dependency cycle; introduced SpelParserConfiguration object to replace bit flags
This commit is contained in:
@@ -29,7 +29,6 @@ import org.springframework.expression.OperatorOverloader;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypeComparator;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParserConfiguration;
|
||||
|
||||
/**
|
||||
* An ExpressionState is for maintaining per-expression-evaluation state, any changes to it are not seen by other
|
||||
@@ -52,14 +51,15 @@ public class ExpressionState {
|
||||
|
||||
private final TypedValue rootObject;
|
||||
|
||||
private int configuration = 0;
|
||||
private SpelParserConfiguration configuration;
|
||||
|
||||
|
||||
public ExpressionState(EvaluationContext context) {
|
||||
this.relatedContext = context;
|
||||
this.rootObject = context.getRootObject();
|
||||
}
|
||||
|
||||
public ExpressionState(EvaluationContext context, int configuration) {
|
||||
public ExpressionState(EvaluationContext context, SpelParserConfiguration configuration) {
|
||||
this.relatedContext = context;
|
||||
this.configuration = configuration;
|
||||
this.rootObject = context.getRootObject();
|
||||
@@ -70,14 +70,15 @@ public class ExpressionState {
|
||||
this.rootObject = rootObject;
|
||||
}
|
||||
|
||||
public ExpressionState(EvaluationContext context, TypedValue rootObject, int configuration) {
|
||||
public ExpressionState(EvaluationContext context, TypedValue rootObject, SpelParserConfiguration configuration) {
|
||||
this.relatedContext = context;
|
||||
this.configuration = configuration;
|
||||
this.rootObject = rootObject;
|
||||
}
|
||||
|
||||
|
||||
private void ensureVariableScopesInitialized() {
|
||||
if (variableScopes == null) {
|
||||
if (this.variableScopes == null) {
|
||||
this.variableScopes = new Stack<VariableScope>();
|
||||
// top level empty variable scope
|
||||
this.variableScopes.add(new VariableScope());
|
||||
@@ -198,7 +199,11 @@ public class ExpressionState {
|
||||
public EvaluationContext getEvaluationContext() {
|
||||
return this.relatedContext;
|
||||
}
|
||||
|
||||
|
||||
public SpelParserConfiguration getConfiguration() {
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* A new scope is entered when a function is called and it is used to hold the parameters to the function call. If the names
|
||||
* of the parameters clash with those in a higher level scope, those in the higher level scope will not be accessible whilst
|
||||
@@ -233,12 +238,4 @@ public class ExpressionState {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean configuredToGrowCollection() {
|
||||
return (configuration & SpelExpressionParserConfiguration.GrowListsOnIndexBeyondSize)!=0;
|
||||
}
|
||||
|
||||
public boolean configuredToDynamicallyCreateNullObjects() {
|
||||
return (configuration & SpelExpressionParserConfiguration.CreateObjectIfAttemptToReferenceNull)!=0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel.standard;
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.springframework.expression.spel.SpelParseException;
|
||||
|
||||
/**
|
||||
* Wraps a real parse exception. This exception flows to the top parse method and then
|
||||
* Wraps a real parse exception. This exception flows to the top parse method and then
|
||||
* the wrapped exception is thrown as the real problem.
|
||||
*
|
||||
* @author Andy Clement
|
||||
@@ -26,12 +27,12 @@ import org.springframework.expression.spel.SpelParseException;
|
||||
*/
|
||||
public class InternalParseException extends RuntimeException {
|
||||
|
||||
public InternalParseException(SpelParseException t) {
|
||||
super(t);
|
||||
public InternalParseException(SpelParseException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public SpelParseException getCause() {
|
||||
return (SpelParseException)super.getCause();
|
||||
return (SpelParseException) super.getCause();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.expression.spel;
|
||||
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
/**
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SpelExpressionParserFactory {
|
||||
|
||||
public static ExpressionParser getParser() {
|
||||
return new SpelExpressionParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configuration configuration bit flags @see SpelExpressionParserConfiguration
|
||||
* @return an expression parser instance configured appropriately
|
||||
*/
|
||||
public static ExpressionParser getParser(int configuration) {
|
||||
return new SpelExpressionParser(configuration);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.expression.spel;
|
||||
|
||||
/**
|
||||
* Configuration object for the SpEL expression parser.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.expression.spel.standard.SpelExpressionParser#SpelExpressionParser(SpelParserConfiguration)
|
||||
*/
|
||||
public class SpelParserConfiguration {
|
||||
|
||||
private final boolean autoGrowNullReferences;
|
||||
|
||||
private final boolean autoGrowCollections;
|
||||
|
||||
|
||||
public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections) {
|
||||
this.autoGrowNullReferences = autoGrowNullReferences;
|
||||
this.autoGrowCollections = autoGrowCollections;
|
||||
}
|
||||
|
||||
|
||||
public boolean isAutoGrowNullReferences() {
|
||||
return this.autoGrowNullReferences;
|
||||
}
|
||||
|
||||
public boolean isAutoGrowCollections() {
|
||||
return this.autoGrowCollections;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,8 +27,6 @@ import org.springframework.expression.spel.ExpressionState;
|
||||
import org.springframework.expression.spel.SpelEvaluationException;
|
||||
import org.springframework.expression.spel.SpelMessage;
|
||||
|
||||
// TODO support multidimensional arrays
|
||||
// TODO support correct syntax for multidimensional [][][] and not [,,,]
|
||||
/**
|
||||
* An Indexer can index into some proceeding structure to access a particular piece of it. Supported structures are:
|
||||
* strings/collections (lists/sets)/arrays
|
||||
@@ -36,10 +34,12 @@ import org.springframework.expression.spel.SpelMessage;
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
// TODO support multidimensional arrays
|
||||
// TODO support correct syntax for multidimensional [][][] and not [,,,]
|
||||
public class Indexer extends SpelNodeImpl {
|
||||
|
||||
public Indexer(int pos,SpelNodeImpl expr) {
|
||||
super(pos,expr);
|
||||
public Indexer(int pos, SpelNodeImpl expr) {
|
||||
super(pos, expr);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -48,7 +48,7 @@ public class Indexer extends SpelNodeImpl {
|
||||
TypedValue context = state.getActiveContextObject();
|
||||
Object targetObject = context.getValue();
|
||||
TypeDescriptor targetObjectTypeDescriptor = context.getTypeDescriptor();
|
||||
TypedValue indexValue = null;
|
||||
TypedValue indexValue = null;
|
||||
Object index = null;
|
||||
|
||||
// This first part of the if clause prevents a 'double dereference' of the property (SPR-5847)
|
||||
@@ -56,14 +56,16 @@ public class Indexer extends SpelNodeImpl {
|
||||
PropertyOrFieldReference reference = (PropertyOrFieldReference)children[0];
|
||||
index = reference.getName();
|
||||
indexValue = new TypedValue(index, TypeDescriptor.valueOf(String.class));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// In case the map key is unqualified, we want it evaluated against the root object so
|
||||
// temporarily push that on whilst evaluating the key
|
||||
try {
|
||||
state.pushActiveContextObject(state.getRootContextObject());
|
||||
indexValue = children[0].getValueInternal(state);
|
||||
index = indexValue.getValue();
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
state.popActiveContextObject();
|
||||
}
|
||||
}
|
||||
@@ -100,7 +102,7 @@ public class Indexer extends SpelNodeImpl {
|
||||
} else if (targetObject instanceof Collection) {
|
||||
Collection c = (Collection) targetObject;
|
||||
if (idx >= c.size()) {
|
||||
if (state.configuredToGrowCollection()) {
|
||||
if (state.getConfiguration().isAutoGrowCollections()) {
|
||||
// Grow the collection
|
||||
Object newCollectionElement = null;
|
||||
try {
|
||||
@@ -114,14 +116,14 @@ public class Indexer extends SpelNodeImpl {
|
||||
newElements--;
|
||||
}
|
||||
newCollectionElement = targetObjectTypeDescriptor.getElementType().newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_GROW_COLLECTION);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_GROW_COLLECTION);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.UNABLE_TO_GROW_COLLECTION);
|
||||
}
|
||||
c.add(newCollectionElement);
|
||||
return new TypedValue(newCollectionElement,TypeDescriptor.valueOf(targetObjectTypeDescriptor.getElementType()));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new SpelEvaluationException(getStartPosition(),SpelMessage.COLLECTION_INDEX_OUT_OF_BOUNDS, c.size(), idx);
|
||||
}
|
||||
}
|
||||
@@ -175,7 +177,8 @@ public class Indexer extends SpelNodeImpl {
|
||||
if (targetObjectTypeDescriptor.isArray()) {
|
||||
int idx = (Integer)state.convertValue(index, INTEGER_TYPE_DESCRIPTOR);
|
||||
setArrayElement(state, contextObject.getValue(), idx, newValue, targetObjectTypeDescriptor.getElementType());
|
||||
} else if (targetObjectTypeDescriptor.isCollection()) {
|
||||
}
|
||||
else if (targetObjectTypeDescriptor.isCollection()) {
|
||||
int idx = (Integer)state.convertValue(index, INTEGER_TYPE_DESCRIPTOR);
|
||||
Collection c = (Collection) targetObject;
|
||||
if (idx >= c.size()) {
|
||||
@@ -185,7 +188,8 @@ public class Indexer extends SpelNodeImpl {
|
||||
List list = (List)targetObject;
|
||||
Object possiblyConvertedValue = state.convertValue(newValue,TypeDescriptor.valueOf(targetObjectTypeDescriptor.getElementType()));
|
||||
list.set(idx,possiblyConvertedValue);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new SpelEvaluationException(getStartPosition(),SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, contextObject.getClass().getName());
|
||||
}
|
||||
} else {
|
||||
@@ -247,7 +251,6 @@ public class Indexer extends SpelNodeImpl {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Object accessArrayElement(Object ctx, int idx) throws SpelEvaluationException {
|
||||
Class<?> arrayComponentType = ctx.getClass().getComponentType();
|
||||
if (arrayComponentType == Integer.TYPE) {
|
||||
@@ -289,7 +292,6 @@ public class Indexer extends SpelNodeImpl {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkAccess(int arrayLength, int index) throws SpelEvaluationException {
|
||||
if (index > arrayLength) {
|
||||
throw new SpelEvaluationException(getStartPosition(), SpelMessage.ARRAY_INDEX_OUT_OF_BOUNDS, arrayLength, index);
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.springframework.expression.spel.ExpressionState;
|
||||
import org.springframework.expression.spel.SpelEvaluationException;
|
||||
import org.springframework.expression.spel.SpelMessage;
|
||||
import org.springframework.expression.spel.SpelParseException;
|
||||
import org.springframework.expression.spel.standard.InternalParseException;
|
||||
import org.springframework.expression.spel.InternalParseException;
|
||||
|
||||
/**
|
||||
* Common superclass for nodes representing literals (boolean, string, number, etc).
|
||||
|
||||
@@ -51,7 +51,7 @@ public class OpOr extends Operator {
|
||||
}
|
||||
|
||||
if (leftValue == true) {
|
||||
return BooleanTypedValue.True; // no need to evaluate right operand
|
||||
return BooleanTypedValue.TRUE; // no need to evaluate right operand
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class OperatorInstanceof extends Operator {
|
||||
Object leftValue = left.getValue();
|
||||
Object rightValue = right.getValue();
|
||||
if (leftValue == null) {
|
||||
return BooleanTypedValue.False; // null is not an instanceof anything
|
||||
return BooleanTypedValue.FALSE; // null is not an instanceof anything
|
||||
}
|
||||
if (rightValue == null || !(rightValue instanceof Class<?>)) {
|
||||
throw new SpelEvaluationException(getRightOperand().getStartPosition(),
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.ExpressionState;
|
||||
import org.springframework.expression.spel.SpelEvaluationException;
|
||||
import org.springframework.expression.spel.SpelMessage;
|
||||
import org.springframework.expression.spel.support.ReflectivePropertyResolver;
|
||||
import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
|
||||
|
||||
/**
|
||||
* Represents a simple property or field reference.
|
||||
@@ -60,7 +60,8 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
|
||||
TypedValue result = readProperty(state, this.name);
|
||||
|
||||
// Dynamically create the objects if the user has requested that optional behaviour
|
||||
if (result.getValue()==null && state.configuredToDynamicallyCreateNullObjects() && nextChildIs(Indexer.class,PropertyOrFieldReference.class)) {
|
||||
if (result.getValue() == null && state.getConfiguration().isAutoGrowNullReferences() &&
|
||||
nextChildIs(Indexer.class, PropertyOrFieldReference.class)) {
|
||||
TypeDescriptor resultDescriptor = result.getTypeDescriptor();
|
||||
// Creating lists and maps
|
||||
if ((resultDescriptor.getType().equals(List.class) || resultDescriptor.getType().equals(Map.class))) {
|
||||
@@ -161,8 +162,8 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
|
||||
try {
|
||||
for (PropertyAccessor accessor : accessorsToTry) {
|
||||
if (accessor.canRead(eContext, contextObject.getValue(), name)) {
|
||||
if (accessor instanceof ReflectivePropertyResolver) {
|
||||
accessor = ((ReflectivePropertyResolver)accessor).createOptimalAccessor(eContext, contextObject.getValue(), name);
|
||||
if (accessor instanceof ReflectivePropertyAccessor) {
|
||||
accessor = ((ReflectivePropertyAccessor)accessor).createOptimalAccessor(eContext, contextObject.getValue(), name);
|
||||
}
|
||||
this.cachedReadAccessor = accessor;
|
||||
return accessor.read(eContext, contextObject.getValue(), name);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2009 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -13,7 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel.standard.internal;
|
||||
|
||||
package org.springframework.expression.spel.standard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -22,9 +23,10 @@ import java.util.Stack;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.common.TemplateAwareExpressionParser;
|
||||
import org.springframework.expression.spel.SpelExpression;
|
||||
import org.springframework.expression.spel.InternalParseException;
|
||||
import org.springframework.expression.spel.SpelMessage;
|
||||
import org.springframework.expression.spel.SpelParseException;
|
||||
import org.springframework.expression.spel.SpelParserConfiguration;
|
||||
import org.springframework.expression.spel.ast.Assign;
|
||||
import org.springframework.expression.spel.ast.BooleanLiteral;
|
||||
import org.springframework.expression.spel.ast.CompoundExpression;
|
||||
@@ -62,16 +64,14 @@ import org.springframework.expression.spel.ast.StringLiteral;
|
||||
import org.springframework.expression.spel.ast.Ternary;
|
||||
import org.springframework.expression.spel.ast.TypeReference;
|
||||
import org.springframework.expression.spel.ast.VariableReference;
|
||||
import org.springframework.expression.spel.standard.InternalParseException;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParserConfiguration;
|
||||
|
||||
/**
|
||||
* Hand written SpEL parser. Instances are reusable but are not thread safe.
|
||||
* Hand written SpEL parser. Instances are reusable but are not thread safe.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
||||
class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
||||
|
||||
// The expression being parsed
|
||||
private String expressionString;
|
||||
@@ -88,30 +88,20 @@ public class InternalSpelExpressionParser extends TemplateAwareExpressionParser
|
||||
// For rules that build nodes, they are stacked here for return
|
||||
private Stack<SpelNodeImpl> constructedNodes = new Stack<SpelNodeImpl>();
|
||||
|
||||
private int configuration;
|
||||
private SpelParserConfiguration configuration;
|
||||
|
||||
|
||||
/**
|
||||
* Create a parser.
|
||||
* Create a parser with some configured behavior.
|
||||
* @param configuration custom configuration options
|
||||
*/
|
||||
public InternalSpelExpressionParser() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a parser with some configured behaviour. Supported configuration
|
||||
* bit flags can be seen in {@link SpelExpressionParserConfiguration}
|
||||
* @param configuration bitflags for configuration options
|
||||
*/
|
||||
public InternalSpelExpressionParser(int configuration) {
|
||||
public InternalSpelExpressionParser(SpelParserConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public SpelExpression parse(String expressionString) throws ParseException {
|
||||
return doParseExpression(expressionString, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException {
|
||||
protected SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException {
|
||||
try {
|
||||
this.expressionString = expressionString;
|
||||
Tokenizer tokenizer = new Tokenizer(expressionString);
|
||||
@@ -126,7 +116,8 @@ public class InternalSpelExpressionParser extends TemplateAwareExpressionParser
|
||||
}
|
||||
assert constructedNodes.isEmpty();
|
||||
return new SpelExpression(expressionString, ast, configuration);
|
||||
} catch (InternalParseException ipe) {
|
||||
}
|
||||
catch (InternalParseException ipe) {
|
||||
throw ipe.getCause();
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
package org.springframework.expression.spel.standard;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
@@ -22,6 +22,9 @@ import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.common.ExpressionUtils;
|
||||
import org.springframework.expression.spel.ExpressionState;
|
||||
import org.springframework.expression.spel.SpelNode;
|
||||
import org.springframework.expression.spel.SpelParserConfiguration;
|
||||
import org.springframework.expression.spel.ast.SpelNodeImpl;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -38,22 +41,24 @@ public class SpelExpression implements Expression {
|
||||
|
||||
private final String expression;
|
||||
|
||||
private final SpelNodeImpl ast;
|
||||
|
||||
private final SpelParserConfiguration configuration;
|
||||
|
||||
// the default context is used if no override is supplied by the user
|
||||
private transient EvaluationContext defaultContext;
|
||||
private EvaluationContext defaultContext;
|
||||
|
||||
public final SpelNodeImpl ast;
|
||||
|
||||
public final int configuration;
|
||||
|
||||
/**
|
||||
* Construct an expression, only used by the parser.
|
||||
*/
|
||||
public SpelExpression(String expression, SpelNodeImpl ast, int configuration) {
|
||||
public SpelExpression(String expression, SpelNodeImpl ast, SpelParserConfiguration configuration) {
|
||||
this.expression = expression;
|
||||
this.ast = ast;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
// implementing Expression
|
||||
|
||||
public Object getValue() throws EvaluationException {
|
||||
@@ -203,7 +208,6 @@ public class SpelExpression implements Expression {
|
||||
* Produce a string representation of the Abstract Syntax Tree for the expression, this should ideally look like the
|
||||
* input expression, but properly formatted since any unnecessary whitespace will have been discarded during the
|
||||
* parse of the expression.
|
||||
*
|
||||
* @return the string representation of the AST
|
||||
*/
|
||||
public String toStringAST() {
|
||||
@@ -215,7 +219,7 @@ public class SpelExpression implements Expression {
|
||||
* @return the default evaluation context
|
||||
*/
|
||||
public EvaluationContext getEvaluationContext() {
|
||||
if (defaultContext==null) {
|
||||
if (defaultContext == null) {
|
||||
defaultContext = new StandardEvaluationContext();
|
||||
}
|
||||
return defaultContext;
|
||||
@@ -223,7 +227,6 @@ public class SpelExpression implements Expression {
|
||||
|
||||
/**
|
||||
* Set the evaluation context that will be used if none is specified on an evaluation call.
|
||||
*
|
||||
* @param context an evaluation context
|
||||
*/
|
||||
public void setEvaluationContext(EvaluationContext context) {
|
||||
@@ -231,9 +234,10 @@ public class SpelExpression implements Expression {
|
||||
}
|
||||
|
||||
private TypedValue toTypedValue(Object object) {
|
||||
if (object==null) {
|
||||
if (object == null) {
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return new TypedValue(object);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2009 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -13,48 +13,51 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel.standard;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.common.TemplateAwareExpressionParser;
|
||||
import org.springframework.expression.spel.SpelExpression;
|
||||
import org.springframework.expression.spel.standard.internal.InternalSpelExpressionParser;
|
||||
import org.springframework.expression.spel.SpelParserConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* SpEL parser. Instances are reusable and thread safe.
|
||||
* SpEL parser. Instances are reusable and thread-safe.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SpelExpressionParser extends TemplateAwareExpressionParser {
|
||||
|
||||
private int configuration;
|
||||
|
||||
private final SpelParserConfiguration configuration;
|
||||
|
||||
|
||||
/**
|
||||
* Create a parser with some configured behaviour. Supported configuration
|
||||
* bit flags can be seen in {@link SpelExpressionParserConfiguration}
|
||||
* @param configuration bitflags for configuration options
|
||||
* Create a parser with standard configuration.
|
||||
*/
|
||||
public SpelExpressionParser(int configuration) {
|
||||
public SpelExpressionParser() {
|
||||
this.configuration = new SpelParserConfiguration(false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a parser with some configured behavior.
|
||||
* @param configuration custom configuration options
|
||||
*/
|
||||
public SpelExpressionParser(SpelParserConfiguration configuration) {
|
||||
Assert.notNull(configuration, "SpelParserConfiguration must not be null");
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a parser with default behaviour.
|
||||
*/
|
||||
public SpelExpressionParser() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Expression doParseExpression(String expressionString, ParserContext context) throws ParseException {
|
||||
return new InternalSpelExpressionParser(configuration).doParseExpression(expressionString, context);
|
||||
protected SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException {
|
||||
return new InternalSpelExpressionParser(this.configuration).doParseExpression(expressionString, context);
|
||||
}
|
||||
|
||||
public SpelExpression parse(String expressionString) throws ParseException {
|
||||
return new InternalSpelExpressionParser(configuration).parse(expressionString);
|
||||
public SpelExpression parseRaw(String expressionString) throws ParseException {
|
||||
return doParseExpression(expressionString, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008-2009 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.expression.spel.standard;
|
||||
|
||||
/**
|
||||
* Bit flags that configure optional behaviour in the parser. Pass the necessary
|
||||
* bits when calling the expression parser constructor.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface SpelExpressionParserConfiguration {
|
||||
|
||||
/**
|
||||
* This option applies to maps/collections and regular objects. If the initial part of an expression evaluates to null and then an
|
||||
* attempt is made to resolve an index '[]' or property against it, and this option is set, then the relevant object will be constructed so that
|
||||
* the index/property resolution can proceed.
|
||||
*/
|
||||
static final int CreateObjectIfAttemptToReferenceNull = 0x0001;
|
||||
|
||||
/**
|
||||
* This option allows collections to grow if an attempt is made to index an element beyond the current size. Rather than fail the
|
||||
* collection is populated with elements up to the specified index.
|
||||
*/
|
||||
static final int GrowListsOnIndexBeyondSize = 0x0002;
|
||||
|
||||
}
|
||||
@@ -13,7 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel.standard.internal;
|
||||
|
||||
package org.springframework.expression.spel.standard;
|
||||
|
||||
/**
|
||||
* Holder for a kind of token, the associated data and its position in the input data stream (start/end).
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel.standard.internal;
|
||||
package org.springframework.expression.spel.standard;
|
||||
|
||||
/**
|
||||
* @author Andy Clement
|
||||
@@ -13,15 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel.standard.internal;
|
||||
|
||||
package org.springframework.expression.spel.standard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.expression.spel.InternalParseException;
|
||||
import org.springframework.expression.spel.SpelMessage;
|
||||
import org.springframework.expression.spel.SpelParseException;
|
||||
import org.springframework.expression.spel.standard.InternalParseException;
|
||||
|
||||
/**
|
||||
* Lex some input data into a stream of tokens that can then be parsed.
|
||||
@@ -29,7 +30,7 @@ import org.springframework.expression.spel.standard.InternalParseException;
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Tokenizer {
|
||||
class Tokenizer {
|
||||
|
||||
String expressionString;
|
||||
char[] toProcess;
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.springframework.expression.spel.support;
|
||||
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* @author Andy Clement
|
||||
@@ -25,18 +25,23 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||
*/
|
||||
public class BooleanTypedValue extends TypedValue {
|
||||
|
||||
public static final BooleanTypedValue True = new BooleanTypedValue(true);
|
||||
public static final BooleanTypedValue False = new BooleanTypedValue(false);
|
||||
|
||||
public static final BooleanTypedValue TRUE = new BooleanTypedValue(true);
|
||||
|
||||
public static final BooleanTypedValue FALSE = new BooleanTypedValue(false);
|
||||
|
||||
|
||||
private BooleanTypedValue(boolean b) {
|
||||
super(b, TypeDescriptor.valueOf(Boolean.class));
|
||||
}
|
||||
|
||||
|
||||
public static BooleanTypedValue forValue(boolean b) {
|
||||
if (b) {
|
||||
return True;
|
||||
} else {
|
||||
return False;
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,14 +35,14 @@ import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Simple PropertyResolver that uses reflection to access properties for reading and writing. A property can be accessed
|
||||
* Simple PropertyAccessor that uses reflection to access properties for reading and writing. A property can be accessed
|
||||
* if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written).
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ReflectivePropertyResolver implements PropertyAccessor {
|
||||
public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||
|
||||
protected Map<CacheKey, InvokerPair> readerCache;
|
||||
|
||||
@@ -137,7 +137,7 @@ public class StandardEvaluationContext implements EvaluationContext {
|
||||
private void ensurePropertyAccessorsInitialized() {
|
||||
if (this.propertyAccessors == null) {
|
||||
this.propertyAccessors = new ArrayList<PropertyAccessor>();
|
||||
this.propertyAccessors.add(new ReflectivePropertyResolver());
|
||||
this.propertyAccessors.add(new ReflectivePropertyAccessor());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user