TypeDescriptor cleanup and general polishing; fixed a number of bugs related to TypeDescriptor usage in client code across beans and spel packages
This commit is contained in:
@@ -29,7 +29,7 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||
*/
|
||||
public class TypedValue {
|
||||
|
||||
public static final TypedValue NULL = new TypedValue(null, TypeDescriptor.NULL);
|
||||
public static final TypedValue NULL = new TypedValue(null);
|
||||
|
||||
|
||||
private final Object value;
|
||||
|
||||
@@ -44,7 +44,7 @@ public abstract class ExpressionUtils {
|
||||
*/
|
||||
public static <T> T convert(EvaluationContext context, Object value, Class<T> targetType) throws EvaluationException {
|
||||
// TODO remove this function over time and use the one it delegates to
|
||||
return convertTypedValue(context,new TypedValue(value,TypeDescriptor.forObject(value)),targetType);
|
||||
return convertTypedValue(context,new TypedValue(value),targetType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -124,7 +124,7 @@ public class ExpressionState {
|
||||
return TypedValue.NULL;
|
||||
}
|
||||
else {
|
||||
return new TypedValue(value, TypeDescriptor.forObject(value));
|
||||
return new TypedValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ public class ExpressionState {
|
||||
OperatorOverloader overloader = this.relatedContext.getOperatorOverloader();
|
||||
if (overloader.overridesOperation(op, left, right)) {
|
||||
Object returnValue = overloader.operate(op, left, right);
|
||||
return new TypedValue(returnValue,TypeDescriptor.forObject(returnValue));
|
||||
return new TypedValue(returnValue);
|
||||
}
|
||||
else {
|
||||
String leftType = (left==null?"null":left.getClass().getName());
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.expression.spel.ast;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
@@ -234,7 +234,6 @@ public class ConstructorReference extends SpelNodeImpl {
|
||||
else {
|
||||
componentType = arrayTypeCode.getType();
|
||||
}
|
||||
TypeDescriptor td = TypeDescriptor.valueOf(componentType);
|
||||
Object newArray;
|
||||
if (!hasInitializer()) {
|
||||
// Confirm all dimensions were specified (for example [3][][5] is missing the 2nd dimension)
|
||||
@@ -313,7 +312,7 @@ public class ConstructorReference extends SpelNodeImpl {
|
||||
throw new IllegalStateException(arrayTypeCode.name());
|
||||
}
|
||||
}
|
||||
return new TypedValue(newArray, td);
|
||||
return new TypedValue(newArray);
|
||||
}
|
||||
|
||||
private void populateReferenceTypeArray(ExpressionState state, Object newArray, TypeConverter typeConverter,
|
||||
|
||||
@@ -90,20 +90,10 @@ public class Indexer extends SpelNodeImpl {
|
||||
|
||||
// Indexing into a Map
|
||||
if (targetObject instanceof Map) {
|
||||
if (targetObject == null) {
|
||||
// Current decision: attempt to index into null map == exception and does not just return null
|
||||
throw new SpelEvaluationException(getStartPosition(),SpelMessage.CANNOT_INDEX_INTO_NULL_VALUE);
|
||||
}
|
||||
Object possiblyConvertedKey = index;
|
||||
if (targetObjectTypeDescriptor.isMapEntryTypeKnown()) {
|
||||
possiblyConvertedKey = state.convertValue(index,TypeDescriptor.valueOf(targetObjectTypeDescriptor.getMapKeyType()));
|
||||
}
|
||||
possiblyConvertedKey = state.convertValue(index, targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
|
||||
Object o = ((Map<?, ?>) targetObject).get(possiblyConvertedKey);
|
||||
if (targetObjectTypeDescriptor.isMapEntryTypeKnown()) {
|
||||
return new TypedValue(o, targetObjectTypeDescriptor.getMapValueTypeDescriptor());
|
||||
} else {
|
||||
return new TypedValue(o);
|
||||
}
|
||||
return new TypedValue(o, targetObjectTypeDescriptor.getMapValueTypeDescriptor().applyType(o));
|
||||
}
|
||||
|
||||
if (targetObject == null) {
|
||||
@@ -125,7 +115,7 @@ public class Indexer extends SpelNodeImpl {
|
||||
int pos = 0;
|
||||
for (Object o : c) {
|
||||
if (pos == idx) {
|
||||
return new TypedValue(o, targetObjectTypeDescriptor.getElementTypeDescriptor());
|
||||
return new TypedValue(o, targetObjectTypeDescriptor.getElementTypeDescriptor().applyType(o));
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
@@ -195,10 +185,8 @@ public class Indexer extends SpelNodeImpl {
|
||||
Map map = (Map)targetObject;
|
||||
Object possiblyConvertedKey = index;
|
||||
Object possiblyConvertedValue = newValue;
|
||||
if (targetObjectTypeDescriptor.isMapEntryTypeKnown()) {
|
||||
possiblyConvertedKey = state.convertValue(index.getValue(),TypeDescriptor.valueOf(targetObjectTypeDescriptor.getMapKeyType()));
|
||||
possiblyConvertedValue = state.convertValue(newValue,TypeDescriptor.valueOf(targetObjectTypeDescriptor.getMapValueType()));
|
||||
}
|
||||
possiblyConvertedKey = state.convertValue(index.getValue(), targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
|
||||
possiblyConvertedValue = state.convertValue(newValue, targetObjectTypeDescriptor.getMapValueTypeDescriptor());
|
||||
map.put(possiblyConvertedKey,possiblyConvertedValue);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.ExpressionState;
|
||||
@@ -72,8 +71,7 @@ public class InlineList extends SpelNodeImpl {
|
||||
constantList.add(((InlineList) child).getConstantValue());
|
||||
}
|
||||
}
|
||||
this.constant = new TypedValue(Collections.unmodifiableList(constantList), TypeDescriptor
|
||||
.valueOf(List.class));
|
||||
this.constant = new TypedValue(Collections.unmodifiableList(constantList));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +85,7 @@ public class InlineList extends SpelNodeImpl {
|
||||
for (int c = 0; c < childcount; c++) {
|
||||
returnValue.add(getChild(c).getValue(expressionState));
|
||||
}
|
||||
return new TypedValue(returnValue, TypeDescriptor.valueOf(List.class));
|
||||
return new TypedValue(returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.expression.spel.ast;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Operation;
|
||||
import org.springframework.expression.TypedValue;
|
||||
@@ -50,7 +49,7 @@ public class OpDivide extends Operator {
|
||||
}
|
||||
}
|
||||
Object result = state.operate(Operation.DIVIDE, operandOne, operandTwo);
|
||||
return new TypedValue(result,TypeDescriptor.forObject(result));
|
||||
return new TypedValue(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,14 +68,14 @@ public class Projection extends SpelNodeImpl {
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
for (Map.Entry entry : mapData.entrySet()) {
|
||||
try {
|
||||
state.pushActiveContextObject(new TypedValue(entry, TypeDescriptor.valueOf(Map.Entry.class)));
|
||||
state.pushActiveContextObject(new TypedValue(entry));
|
||||
result.add(this.children[0].getValueInternal(state).getValue());
|
||||
}
|
||||
finally {
|
||||
state.popActiveContextObject();
|
||||
}
|
||||
}
|
||||
return new TypedValue(result,TypeDescriptor.valueOf(List.class)); // TODO unable to build correct type descriptor
|
||||
return new TypedValue(result); // TODO unable to build correct type descriptor
|
||||
}
|
||||
else if (operand instanceof Collection || operandIsArray) {
|
||||
Collection<?> data = (operand instanceof Collection ? (Collection<?>) operand :
|
||||
|
||||
@@ -74,7 +74,7 @@ public class Selection extends SpelNodeImpl {
|
||||
Object lastKey = null;
|
||||
for (Map.Entry entry : mapdata.entrySet()) {
|
||||
try {
|
||||
TypedValue kvpair = new TypedValue(entry,TypeDescriptor.valueOf(Map.Entry.class));
|
||||
TypedValue kvpair = new TypedValue(entry);
|
||||
state.pushActiveContextObject(kvpair);
|
||||
Object o = selectionCriteria.getValueInternal(state).getValue();
|
||||
if (o instanceof Boolean) {
|
||||
@@ -95,7 +95,7 @@ public class Selection extends SpelNodeImpl {
|
||||
}
|
||||
}
|
||||
if ((variant == FIRST || variant == LAST) && result.size() == 0) {
|
||||
return new TypedValue(null,TypeDescriptor.NULL);
|
||||
return new TypedValue(null);
|
||||
}
|
||||
if (variant == LAST) {
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.expression.spel.support;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
@@ -31,7 +30,7 @@ public class BooleanTypedValue extends TypedValue {
|
||||
|
||||
|
||||
private BooleanTypedValue(boolean b) {
|
||||
super(b, TypeDescriptor.valueOf(Boolean.class));
|
||||
super(b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ public class ReflectionHelper {
|
||||
TypeDescriptor targetType;
|
||||
if (varargsPosition != null && argPosition >= varargsPosition) {
|
||||
MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, varargsPosition);
|
||||
targetType = new TypeDescriptor(methodParam, methodParam.getParameterType().getComponentType());
|
||||
targetType = new TypeDescriptor(methodParam.getParameterType().getComponentType(), methodParam);
|
||||
}
|
||||
else {
|
||||
targetType = new TypeDescriptor(MethodParameter.forMethodOrConstructor(methodOrCtor, argPosition));
|
||||
@@ -268,7 +268,7 @@ public class ReflectionHelper {
|
||||
TypeDescriptor targetType;
|
||||
if (varargsPosition != null && argPosition >= varargsPosition) {
|
||||
MethodParameter methodParam = new MethodParameter(method, varargsPosition);
|
||||
targetType = new TypeDescriptor(methodParam, methodParam.getParameterType().getComponentType());
|
||||
targetType = new TypeDescriptor(methodParam.getParameterType().getComponentType(), methodParam);
|
||||
}
|
||||
else {
|
||||
targetType = new TypeDescriptor(new MethodParameter(method, argPosition));
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.expression.spel.support;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.ConstructorExecutor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
@@ -65,7 +64,7 @@ class ReflectiveConstructorExecutor implements ConstructorExecutor {
|
||||
arguments = ReflectionHelper.setupArgumentsForVarargsInvocation(this.ctor.getParameterTypes(), arguments);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(this.ctor);
|
||||
return new TypedValue(this.ctor.newInstance(arguments), TypeDescriptor.valueOf(this.ctor.getDeclaringClass()));
|
||||
return new TypedValue(this.ctor.newInstance(arguments));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new AccessException("Problem invoking constructor: " + this.ctor, ex);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||
// The readerCache will only contain gettable properties (let's not worry about setters for now)
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, method, null);
|
||||
TypeDescriptor typeDescriptor =
|
||||
new PropertyTypeDescriptor(propertyDescriptor, new MethodParameter(method, -1));
|
||||
new PropertyTypeDescriptor(new MethodParameter(method, -1), propertyDescriptor);
|
||||
this.readerCache.put(cacheKey, new InvokerPair(method, typeDescriptor));
|
||||
this.typeDescriptorCache.put(cacheKey, typeDescriptor);
|
||||
return true;
|
||||
@@ -128,7 +128,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||
// The readerCache will only contain gettable properties (let's not worry about setters for now)
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, method, null);
|
||||
TypeDescriptor typeDescriptor =
|
||||
new PropertyTypeDescriptor(propertyDescriptor, new MethodParameter(method, -1));
|
||||
new PropertyTypeDescriptor(new MethodParameter(method, -1), propertyDescriptor);
|
||||
invoker = new InvokerPair(method, typeDescriptor);
|
||||
this.readerCache.put(cacheKey, invoker);
|
||||
}
|
||||
@@ -192,7 +192,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||
throw new AccessException("Unable to access property '" + name + "' through setter "+method, ex);
|
||||
}
|
||||
MethodParameter mp = new MethodParameter(method,0);
|
||||
TypeDescriptor typeDescriptor = new PropertyTypeDescriptor(propertyDescriptor, mp);
|
||||
TypeDescriptor typeDescriptor = new PropertyTypeDescriptor(mp, propertyDescriptor);
|
||||
this.writerCache.put(cacheKey, method);
|
||||
this.typeDescriptorCache.put(cacheKey, typeDescriptor);
|
||||
return true;
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.Map;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
@@ -247,7 +246,6 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
private static class FruitColourAccessor implements PropertyAccessor {
|
||||
|
||||
private static Map<String,Color> propertyMap = new HashMap<String,Color>();
|
||||
private static TypeDescriptor mapElementTypeDescriptor = TypeDescriptor.valueOf(Color.class);
|
||||
|
||||
static {
|
||||
propertyMap.put("banana",Color.yellow);
|
||||
@@ -267,7 +265,7 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(propertyMap.get(name),mapElementTypeDescriptor);
|
||||
return new TypedValue(propertyMap.get(name));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
@@ -306,7 +304,7 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(propertyMap.get(name),TypeDescriptor.valueOf(Color.class));
|
||||
return new TypedValue(propertyMap.get(name));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
|
||||
@@ -127,7 +127,7 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
||||
Assert.assertEquals(TypedValue.NULL,state.getRootContextObject());
|
||||
|
||||
|
||||
((StandardEvaluationContext)state.getEvaluationContext()).setRootObject(null,TypeDescriptor.NULL);
|
||||
((StandardEvaluationContext)state.getEvaluationContext()).setRootObject(null);
|
||||
Assert.assertEquals(null,state.getRootContextObject().getValue());
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ public class PropertyAccessTests extends ExpressionTestCase {
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
if (!name.equals("flibbles"))
|
||||
throw new RuntimeException("Assertion Failed! name should be flibbles");
|
||||
return new TypedValue(flibbles, TypeDescriptor.valueOf(String.class));
|
||||
return new TypedValue(flibbles);
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue)
|
||||
|
||||
@@ -20,8 +20,8 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
@@ -222,7 +222,7 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(new Principal(),TypeDescriptor.valueOf(Principal.class));
|
||||
return new TypedValue(new Principal());
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
@@ -252,7 +252,7 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(activePerson,TypeDescriptor.valueOf(Person.class));
|
||||
return new TypedValue(activePerson);
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
|
||||
@@ -69,6 +69,9 @@ public class SpelDocumentationTests extends ExpressionTestCase {
|
||||
public Inventor[] Members = new Inventor[1];
|
||||
public List Members2 = new ArrayList();
|
||||
public Map<String,Object> officers = new HashMap<String,Object>();
|
||||
|
||||
public List reverse = new ArrayList<Map<String, Object>>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
IEEE() {
|
||||
officers.put("president",pupin);
|
||||
@@ -77,6 +80,8 @@ public class SpelDocumentationTests extends ExpressionTestCase {
|
||||
officers.put("advisors",linv);
|
||||
Members2.add(tesla);
|
||||
Members2.add(pupin);
|
||||
|
||||
reverse.add(officers);
|
||||
}
|
||||
|
||||
public boolean isMember(String name) {
|
||||
@@ -215,6 +220,9 @@ public class SpelDocumentationTests extends ExpressionTestCase {
|
||||
|
||||
parser.parseExpression("officers['advisors'][0].PlaceOfBirth.Country").setValue(societyContext, "Croatia");
|
||||
|
||||
Inventor i2 = parser.parseExpression("reverse[0]['advisors'][0]").getValue(societyContext,Inventor.class);
|
||||
Assert.assertEquals("Nikola Tesla",i2.getName());
|
||||
|
||||
}
|
||||
|
||||
// 7.5.3
|
||||
|
||||
Reference in New Issue
Block a user