revised TypeDescriptor NULL and element/mapKey/mapValue type semantics

This commit is contained in:
Keith Donald
2011-06-05 04:43:18 +00:00
parent a2a4929c14
commit c84cccf06d
42 changed files with 732 additions and 758 deletions

View File

@@ -16,15 +16,17 @@
package org.springframework.expression.spel;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static junit.framework.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
@@ -72,13 +74,13 @@ public class ExpressionTestsUsingCoreConversionService extends ExpressionTestCas
TypeConvertorUsingConversionService tcs = new TypeConvertorUsingConversionService();
// ArrayList containing List<Integer> to List<String>
Class<?> clazz = typeDescriptorForListOfString.getElementType();
Class<?> clazz = typeDescriptorForListOfString.getElementType().getType();
assertEquals(String.class,clazz);
List l = (List) tcs.convertValue(listOfInteger, TypeDescriptor.forObject(listOfInteger), typeDescriptorForListOfString);
assertNotNull(l);
// ArrayList containing List<String> to List<Integer>
clazz = typeDescriptorForListOfInteger.getElementType();
clazz = typeDescriptorForListOfInteger.getElementType().getType();
assertEquals(Integer.class,clazz);
l = (List) tcs.convertValue(listOfString, TypeDescriptor.forObject(listOfString), typeDescriptorForListOfString);

View File

@@ -1,42 +1,304 @@
package org.springframework.expression.spel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
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.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class IndexingTests {
@Test
@Ignore
public void indexIntoGenericPropertyContainingMap() {
Map<String, String> property = new HashMap<String, String>();
property.put("foo", "bar");
this.property = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
assertEquals(property, expression.getValue(this, Map.class));
expression = parser.parseExpression("property['foo']");
assertEquals("bar", expression.getValue(this));
}
@FieldAnnotation
public Object property;
@Test
public void indexIntoGenericPropertyContainingMapObject() {
Map<String, Map<String, String>> property = new HashMap<String, Map<String, String>>();
Map<String, String> map = new HashMap<String, String>();
map.put("foo", "bar");
property.put("property", map);
SpelExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.addPropertyAccessor(new MapAccessor());
context.setRootObject(property);
Expression expression = parser.parseExpression("property");
assertEquals("java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(context).toString());
assertEquals(map, expression.getValue(context));
assertEquals(map, expression.getValue(context, Map.class));
expression = parser.parseExpression("property['foo']");
assertEquals("bar", expression.getValue(context));
}
public static class MapAccessor implements PropertyAccessor {
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return (((Map) target).containsKey(name));
}
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
return new TypedValue(((Map) target).get(name));
}
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
return true;
}
@SuppressWarnings("unchecked")
public void write(EvaluationContext context, Object target, String name, Object newValue)
throws AccessException {
((Map) target).put(name, newValue);
}
public Class<?>[] getSpecificTargetClasses() {
return new Class[] { Map.class };
}
}
@Test
public void setGenericPropertyContainingMap() {
Map<String, String> property = new HashMap<String, String>();
property.put("foo", "bar");
this.property = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("property['foo']");
assertEquals("bar", expression.getValue(this));
expression.setValue(this, "baz");
assertEquals("baz", expression.getValue(this));
}
@Test
public void setPropertyContainingMap() {
Map<Integer, Integer> property = new HashMap<Integer, Integer>();
property.put(9, 3);
this.parameterizedMap = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("parameterizedMap");
assertEquals("java.util.HashMap<java.lang.Integer, java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("parameterizedMap['9']");
assertEquals(3, expression.getValue(this));
expression.setValue(this, "37");
assertEquals(37, expression.getValue(this));
}
public Map<Integer, Integer> parameterizedMap;
@Test
public void setPropertyContainingMapAutoGrow() {
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, false));
Expression expression = parser.parseExpression("parameterizedMap");
assertEquals("java.util.Map<java.lang.Integer, java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("parameterizedMap['9']");
assertEquals(null, expression.getValue(this));
expression.setValue(this, "37");
assertEquals(37, expression.getValue(this));
}
@Test
public void indexIntoGenericPropertyContainingList() {
List<String> property = new ArrayList<String>();
property.add("bar");
this.property = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("property[0]");
assertEquals("bar", expression.getValue(this));
}
@Test
public void setGenericPropertyContainingList() {
List<Integer> property = new ArrayList<Integer>();
property.add(3);
this.property = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("property[0]");
assertEquals(3, expression.getValue(this));
expression.setValue(this, "4");
assertEquals("4", expression.getValue(this));
}
@Test
public void setGenericPropertyContainingListAutogrow() {
List<Integer> property = new ArrayList<Integer>();
this.property = property;
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("property[0]");
try {
expression.setValue(this, "4");
} catch (EvaluationException e) {
assertTrue(e.getMessage().startsWith("EL1053E"));
}
}
@Test
public void indexIntoPropertyContainingList() {
List<Integer> property = new ArrayList<Integer>();
property.add(3);
this.parameterizedList = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("parameterizedList");
assertEquals("java.util.ArrayList<java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("parameterizedList[0]");
assertEquals(3, expression.getValue(this));
}
public List<Integer> parameterizedList;
@Test
public void indexIntoPropertyContainingListOfList() {
List<List<Integer>> property = new ArrayList<List<Integer>>();
property.add(Arrays.asList(3));
this.parameterizedListOfList = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("parameterizedListOfList[0]");
assertEquals("java.util.Arrays$ArrayList<java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property.get(0), expression.getValue(this));
expression = parser.parseExpression("parameterizedListOfList[0][0]");
assertEquals(3, expression.getValue(this));
}
public List<List<Integer>> parameterizedListOfList;
@Test
public void setPropertyContainingList() {
List<Integer> property = new ArrayList<Integer>();
property.add(3);
this.parameterizedList = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("parameterizedList");
assertEquals("java.util.ArrayList<java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("parameterizedList[0]");
assertEquals(3, expression.getValue(this));
expression.setValue(this, "4");
assertEquals(4, expression.getValue(this));
}
@Test
public void indexIntoGenericPropertyContainingNullList() {
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
SpelExpressionParser parser = new SpelExpressionParser(configuration);
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.Object", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("property[0]");
try {
assertEquals("bar", expression.getValue(this));
} catch (EvaluationException e) {
assertTrue(e.getMessage().startsWith("EL1027E"));
}
}
@Test
public void indexIntoGenericPropertyContainingGrowingList() {
List<String> property = new ArrayList<String>();
this.property = property;
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
SpelExpressionParser parser = new SpelExpressionParser(configuration);
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("property[0]");
try {
assertEquals("bar", expression.getValue(this));
} catch (EvaluationException e) {
assertTrue(e.getMessage().startsWith("EL1053E"));
}
}
@Test
public void indexIntoGenericPropertyContainingGrowingList2() {
List<String> property2 = new ArrayList<String>();
this.property2 = property2;
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
SpelExpressionParser parser = new SpelExpressionParser(configuration);
Expression expression = parser.parseExpression("property2");
assertEquals("java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
assertEquals(property2, expression.getValue(this));
expression = parser.parseExpression("property2[0]");
try {
assertEquals("bar", expression.getValue(this));
} catch (EvaluationException e) {
assertTrue(e.getMessage().startsWith("EL1053E"));
}
}
public List property2;
@Test
public void indexIntoGenericPropertyContainingArray() {
String[] property = new String[] { "bar" };
this.property = property;
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("property");
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.String[]", expression.getValueTypeDescriptor(this).toString());
assertEquals(property, expression.getValue(this));
expression = parser.parseExpression("property[0]");
assertEquals("bar", expression.getValue(this));
}
@Test
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("java.util.ArrayList<?>", 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("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
assertEquals("5,6", expression.getValue(this, String.class));
}
@@ -44,7 +306,7 @@ public class IndexingTests {
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());
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.List<?>", expression.getValueTypeDescriptor(this).toString());
}
@FieldAnnotation
@@ -63,7 +325,7 @@ public class IndexingTests {
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());
assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(this).toString());
}
@FieldAnnotation

View File

@@ -16,6 +16,9 @@
package org.springframework.expression.spel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
@@ -23,9 +26,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
@@ -112,7 +113,7 @@ public class SelectionAndProjectionTests {
Object value = expression.getValue(context);
assertTrue(value.getClass().isArray());
TypedValue typedValue = new TypedValue(value);
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementType());
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementType().getType());
Integer[] array = (Integer[]) value;
assertEquals(5, array.length);
assertEquals(new Integer(0), array[0]);
@@ -147,7 +148,7 @@ public class SelectionAndProjectionTests {
Object value = expression.getValue(context);
assertTrue(value.getClass().isArray());
TypedValue typedValue = new TypedValue(value);
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementType());
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementType().getType());
Integer[] array = (Integer[]) value;
assertEquals(5, array.length);
assertEquals(new Integer(0), array[0]);
@@ -249,7 +250,7 @@ public class SelectionAndProjectionTests {
Object value = expression.getValue(context);
assertTrue(value.getClass().isArray());
TypedValue typedValue = new TypedValue(value);
assertEquals(Number.class, typedValue.getTypeDescriptor().getElementType());
assertEquals(Number.class, typedValue.getTypeDescriptor().getElementType().getType());
Number[] array = (Number[]) value;
assertEquals(3, array.length);
assertEquals(new Integer(5), array[0]);

View File

@@ -26,7 +26,6 @@ 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;
@@ -206,7 +205,6 @@ public class SpelDocumentationTests extends ExpressionTestCase {
@Test
@Ignore
public void testDictionaryAccess() throws Exception {
StandardEvaluationContext societyContext = new StandardEvaluationContext();
societyContext.setRootObject(new IEEE());

View File

@@ -698,7 +698,6 @@ public class SpringEL300Tests extends ExpressionTestCase {
}
@Test
@Ignore
@SuppressWarnings("unchecked")
public void testMapOfMap_SPR7244() throws Exception {
Map<String,Object> map = new LinkedHashMap();
@@ -727,10 +726,11 @@ public class SpringEL300Tests extends ExpressionTestCase {
String el1 = "ls.![#this.equals('abc')]";
SpelExpression exp = parser.parseRaw(el1);
List value = (List)exp.getValue(ctx);
System.out.println(value);
// value is list containing [true,false]
Assert.assertEquals(Boolean.class,value.get(0).getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(Boolean.class,evaluated.getElementType());
Assert.assertEquals(null, evaluated.getElementType());
}
@Test
@@ -743,7 +743,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
// value is array containing [true,false]
Assert.assertEquals(Boolean.class,value[0].getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(Boolean.class,evaluated.getElementType());
Assert.assertEquals(Boolean.class, evaluated.getElementType().getType());
}
@Test
@@ -756,7 +756,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
// value is list containing [true,false]
Assert.assertEquals(Boolean.class,value.get(0).getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(Boolean.class,evaluated.getElementType());
Assert.assertEquals(null, evaluated.getElementType());
}
static class C {