Skip to content

Commit

Permalink
rearranged spel subpackages in order to avoid package dependency cycl…
Browse files Browse the repository at this point in the history
…e; introduced SpelParserConfiguration object to replace bit flags
  • Loading branch information
jhoeller committed Dec 15, 2009
1 parent b5b1962 commit 086aeb0
Show file tree
Hide file tree
Showing 36 changed files with 292 additions and 304 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
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
Expand All @@ -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();
Expand All @@ -70,14 +70,15 @@ public ExpressionState(EvaluationContext context, TypedValue rootObject) {
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());
Expand Down Expand Up @@ -198,7 +199,11 @@ public List<PropertyAccessor> getPropertyAccessors() {
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
Expand Down Expand Up @@ -233,12 +238,4 @@ public boolean definesVariable(String name) {
}
}

public boolean configuredToGrowCollection() {
return (configuration & SpelExpressionParserConfiguration.GrowListsOnIndexBeyondSize)!=0;
}

public boolean configuredToDynamicallyCreateNullObjects() {
return (configuration & SpelExpressionParserConfiguration.CreateObjectIfAttemptToReferenceNull)!=0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,26 @@
* 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
* @since 3.0
*/
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();
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@
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
*
* @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")
Expand All @@ -48,22 +48,24 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
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)
if (targetObject instanceof Map && (children[0] instanceof PropertyOrFieldReference)) {
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();
}
}
Expand Down Expand Up @@ -100,7 +102,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
} 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 {
Expand All @@ -114,14 +116,14 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
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);
}
}
Expand Down Expand Up @@ -175,7 +177,8 @@ public void setValue(ExpressionState state, Object newValue) throws EvaluationEx
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()) {
Expand All @@ -185,7 +188,8 @@ public void setValue(ExpressionState state, Object newValue) throws EvaluationEx
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 {
Expand Down Expand Up @@ -247,7 +251,6 @@ private void setArrayElement(ExpressionState state, Object ctx, int idx, Object
}
}


private Object accessArrayElement(Object ctx, int idx) throws SpelEvaluationException {
Class<?> arrayComponentType = ctx.getClass().getComponentType();
if (arrayComponentType == Integer.TYPE) {
Expand Down Expand Up @@ -289,7 +292,6 @@ private Object accessArrayElement(Object ctx, int idx) throws SpelEvaluationExce
}
}


private void checkAccess(int arrayLength, int index) throws SpelEvaluationException {
if (index > arrayLength) {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.ARRAY_INDEX_OUT_OF_BOUNDS, arrayLength, index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
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).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
}

if (leftValue == true) {
return BooleanTypedValue.True; // no need to evaluate right operand
return BooleanTypedValue.TRUE; // no need to evaluate right operand
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
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.
Expand Down Expand Up @@ -60,7 +60,8 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
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))) {
Expand Down Expand Up @@ -161,8 +162,8 @@ private TypedValue readProperty(ExpressionState state, String name) throws Evalu
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);
Expand Down
Loading

0 comments on commit 086aeb0

Please sign in to comment.