added TypeDescriptor resolveCollectionElement and Map key/value types
This commit is contained in:
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.expression;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
@@ -31,12 +34,10 @@ public class TypedValue {
|
||||
|
||||
public static final TypedValue NULL = new TypedValue(null);
|
||||
|
||||
|
||||
private final Object value;
|
||||
|
||||
private TypeDescriptor typeDescriptor;
|
||||
|
||||
|
||||
/**
|
||||
* Create a TypedValue for a simple object. The type descriptor is inferred
|
||||
* from the object, so no generic information is preserved.
|
||||
@@ -44,7 +45,8 @@ public class TypedValue {
|
||||
*/
|
||||
public TypedValue(Object value) {
|
||||
this.value = value;
|
||||
this.typeDescriptor = null; // initialized when/if requested
|
||||
// initialized when/if requested
|
||||
this.typeDescriptor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,10 +56,9 @@ public class TypedValue {
|
||||
*/
|
||||
public TypedValue(Object value, TypeDescriptor typeDescriptor) {
|
||||
this.value = value;
|
||||
this.typeDescriptor = typeDescriptor;
|
||||
this.typeDescriptor = initTypeDescriptor(value, typeDescriptor);
|
||||
}
|
||||
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
@@ -69,12 +70,27 @@ public class TypedValue {
|
||||
return this.typeDescriptor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("TypedValue: '").append(this.value).append("' of [").append(getTypeDescriptor() + "]");
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
// interal helpers
|
||||
|
||||
private static TypeDescriptor initTypeDescriptor(Object value, TypeDescriptor typeDescriptor) {
|
||||
if (value == null) {
|
||||
return typeDescriptor;
|
||||
}
|
||||
if (typeDescriptor.isCollection() && Object.class.equals(typeDescriptor.getElementType())) {
|
||||
return typeDescriptor.resolveCollectionElementType((Collection<?>) value);
|
||||
} else if (typeDescriptor.isMap() && Object.class.equals(typeDescriptor.getMapKeyType())
|
||||
&& Object.class.equals(typeDescriptor.getMapValueType())){
|
||||
return typeDescriptor.resolveMapKeyValueTypes((Map<?, ?>) value);
|
||||
} else {
|
||||
return typeDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -90,13 +90,9 @@ public class Indexer extends SpelNodeImpl {
|
||||
|
||||
// Indexing into a Map
|
||||
if (targetObject instanceof Map) {
|
||||
if (targetObjectTypeDescriptor.isMap()) {
|
||||
Object possiblyConvertedKey = state.convertValue(index, targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
|
||||
Object o = ((Map<?, ?>) targetObject).get(possiblyConvertedKey);
|
||||
return new TypedValue(o, targetObjectTypeDescriptor.getMapValueTypeDescriptor());
|
||||
} else {
|
||||
return new TypedValue(((Map<?, ?>) targetObject).get(index));
|
||||
}
|
||||
Object possiblyConvertedKey = state.convertValue(index, targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
|
||||
Object o = ((Map<?, ?>) targetObject).get(possiblyConvertedKey);
|
||||
return new TypedValue(o, targetObjectTypeDescriptor.getMapValueTypeDescriptor());
|
||||
}
|
||||
|
||||
if (targetObject == null) {
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
public class IndexingTests {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void emptyList() {
|
||||
listOfScalarNotGeneric = new ArrayList();
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfScalarNotGeneric");
|
||||
assertEquals("java.util.List<java.lang.Object>", expression.getValueTypeDescriptor(this).toString());
|
||||
assertEquals("", expression.getValue(this, String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void resolveCollectionElementType() {
|
||||
listNotGeneric = new ArrayList();
|
||||
listNotGeneric.add(5);
|
||||
listNotGeneric.add(6);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listNotGeneric");
|
||||
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.List<@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
|
||||
assertEquals("5,6", expression.getValue(this, String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCollectionElementTypeNull() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listNotGeneric");
|
||||
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.List<@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.Object>", expression.getValueTypeDescriptor(this).toString());
|
||||
}
|
||||
|
||||
@FieldAnnotation
|
||||
public List listNotGeneric;
|
||||
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface FieldAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveMapKeyValueTypes() {
|
||||
mapNotGeneric = new HashMap();
|
||||
mapNotGeneric.put("baseAmount", 3.11);
|
||||
mapNotGeneric.put("bonusAmount", 7.17);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("mapNotGeneric");
|
||||
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.Map<java.lang.String, java.lang.Double>", expression.getValueTypeDescriptor(this).toString());
|
||||
}
|
||||
|
||||
@FieldAnnotation
|
||||
public Map mapNotGeneric;
|
||||
|
||||
@Test
|
||||
public void testListOfScalar() {
|
||||
listOfScalarNotGeneric = new ArrayList();
|
||||
listOfScalarNotGeneric.add("5");
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfScalarNotGeneric[0]");
|
||||
assertEquals(new Integer(5), expression.getValue(this, Integer.class));
|
||||
}
|
||||
|
||||
public List listOfScalarNotGeneric;
|
||||
|
||||
|
||||
@Test
|
||||
public void testListsOfMap() {
|
||||
listOfMapsNotGeneric = new ArrayList();
|
||||
Map map = new HashMap();
|
||||
map.put("fruit", "apple");
|
||||
listOfMapsNotGeneric.add(map);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfMapsNotGeneric[0]['fruit']");
|
||||
assertEquals("apple", expression.getValue(this, String.class));
|
||||
}
|
||||
|
||||
public List listOfMapsNotGeneric;
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import java.util.Map;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -205,14 +206,15 @@ public class SpelDocumentationTests extends ExpressionTestCase {
|
||||
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testDictionaryAccess() throws Exception {
|
||||
StandardEvaluationContext societyContext = new StandardEvaluationContext();
|
||||
societyContext.setRootObject(new IEEE());
|
||||
// Officer's Dictionary
|
||||
// Inventor pupin = parser.parseExpression("officers['president']").getValue(societyContext, Inventor.class);
|
||||
//
|
||||
// // evaluates to "Idvor"
|
||||
// String city = parser.parseExpression("officers['president'].PlaceOfBirth.city").getValue(societyContext, String.class);
|
||||
Inventor pupin = parser.parseExpression("officers['president']").getValue(societyContext, Inventor.class);
|
||||
|
||||
// evaluates to "Idvor"
|
||||
String city = parser.parseExpression("officers['president'].PlaceOfBirth.city").getValue(societyContext, String.class);
|
||||
|
||||
// setting values
|
||||
Inventor i = parser.parseExpression("officers['advisors'][0]").getValue(societyContext,Inventor.class);
|
||||
|
||||
@@ -698,6 +698,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMapOfMap_SPR7244() throws Exception {
|
||||
Map<String,Object> map = new LinkedHashMap();
|
||||
|
||||
Reference in New Issue
Block a user