|
|
|
@ -16,18 +16,13 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.expression.spel; |
|
|
|
package org.springframework.expression.spel; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.HashMap; |
|
|
|
|
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
import org.junit.jupiter.api.Test; |
|
|
|
import org.junit.jupiter.api.Test; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.expression.EvaluationContext; |
|
|
|
import org.springframework.expression.EvaluationContext; |
|
|
|
import org.springframework.expression.Expression; |
|
|
|
|
|
|
|
import org.springframework.expression.ExpressionParser; |
|
|
|
|
|
|
|
import org.springframework.expression.PropertyAccessor; |
|
|
|
|
|
|
|
import org.springframework.expression.TypedValue; |
|
|
|
import org.springframework.expression.TypedValue; |
|
|
|
import org.springframework.expression.spel.standard.SpelExpressionParser; |
|
|
|
import org.springframework.expression.spel.standard.SpelExpressionParser; |
|
|
|
import org.springframework.expression.spel.support.StandardEvaluationContext; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
|
|
|
|
|
|
|
|
@ -39,147 +34,56 @@ import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
class MapAccessTests extends AbstractExpressionTests { |
|
|
|
class MapAccessTests extends AbstractExpressionTests { |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
void testSimpleMapAccess01() { |
|
|
|
void directMapAccess() { |
|
|
|
evaluate("testMap.get('monday')", "montag", String.class); |
|
|
|
evaluate("testMap.get('monday')", "montag", String.class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
void testMapAccessThroughIndexer() { |
|
|
|
void mapAccessThroughIndexer() { |
|
|
|
evaluate("testMap['monday']", "montag", String.class); |
|
|
|
evaluate("testMap['monday']", "montag", String.class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
void testCustomMapAccessor() { |
|
|
|
void variableMapAccess() { |
|
|
|
ExpressionParser parser = new SpelExpressionParser(); |
|
|
|
var parser = new SpelExpressionParser(); |
|
|
|
StandardEvaluationContext ctx = TestScenarioCreator.getTestEvaluationContext(); |
|
|
|
var ctx = TestScenarioCreator.getTestEvaluationContext(); |
|
|
|
ctx.addPropertyAccessor(new MapAccessor()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Expression expr = parser.parseExpression("testMap.monday"); |
|
|
|
|
|
|
|
Object value = expr.getValue(ctx, String.class); |
|
|
|
|
|
|
|
assertThat(value).isEqualTo("montag"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
void testVariableMapAccess() { |
|
|
|
|
|
|
|
ExpressionParser parser = new SpelExpressionParser(); |
|
|
|
|
|
|
|
StandardEvaluationContext ctx = TestScenarioCreator.getTestEvaluationContext(); |
|
|
|
|
|
|
|
ctx.setVariable("day", "saturday"); |
|
|
|
ctx.setVariable("day", "saturday"); |
|
|
|
|
|
|
|
|
|
|
|
Expression expr = parser.parseExpression("testMap[#day]"); |
|
|
|
var expr = parser.parseExpression("testMap[#day]"); |
|
|
|
Object value = expr.getValue(ctx, String.class); |
|
|
|
assertThat(expr.getValue(ctx, String.class)).isEqualTo("samstag"); |
|
|
|
assertThat(value).isEqualTo("samstag"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
void testGetValue() { |
|
|
|
void mapAccessOnRoot() { |
|
|
|
Map<String, String> props1 = new HashMap<>(); |
|
|
|
var map = Map.of("key", "value"); |
|
|
|
props1.put("key1", "value1"); |
|
|
|
var parser = new SpelExpressionParser(); |
|
|
|
props1.put("key2", "value2"); |
|
|
|
var expr = parser.parseExpression("#root['key']"); |
|
|
|
props1.put("key3", "value3"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object bean = new TestBean("name1", new TestBean("name2", null, "Description 2", 15, props1), "description 1", 6, props1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ExpressionParser parser = new SpelExpressionParser(); |
|
|
|
assertThat(expr.getValue(map)).isEqualTo("value"); |
|
|
|
Expression expr = parser.parseExpression("testBean.properties['key2']"); |
|
|
|
|
|
|
|
assertThat(expr.getValue(bean)).isEqualTo("value2"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
void testGetValueFromRootMap() { |
|
|
|
void mapAccessOnProperty() { |
|
|
|
Map<String, String> map = new HashMap<>(); |
|
|
|
var properties = Map.of("key", "value"); |
|
|
|
map.put("key", "value"); |
|
|
|
var bean = new TestBean(null, new TestBean(properties, null)); |
|
|
|
|
|
|
|
|
|
|
|
ExpressionParser spelExpressionParser = new SpelExpressionParser(); |
|
|
|
var parser = new SpelExpressionParser(); |
|
|
|
Expression expr = spelExpressionParser.parseExpression("#root['key']"); |
|
|
|
var expr = parser.parseExpression("nestedBean.properties['key']"); |
|
|
|
assertThat(expr.getValue(map)).isEqualTo("value"); |
|
|
|
assertThat(expr.getValue(bean)).isEqualTo("value"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
void mapAccessor() { |
|
|
|
|
|
|
|
var parser = new SpelExpressionParser(); |
|
|
|
|
|
|
|
var ctx = TestScenarioCreator.getTestEvaluationContext(); |
|
|
|
|
|
|
|
ctx.addPropertyAccessor(new MapAccessor()); |
|
|
|
|
|
|
|
|
|
|
|
public static class TestBean { |
|
|
|
var expr1 = parser.parseExpression("testMap.monday"); |
|
|
|
|
|
|
|
assertThat(expr1.getValue(ctx, String.class)).isEqualTo("montag"); |
|
|
|
private String name; |
|
|
|
|
|
|
|
private TestBean testBean; |
|
|
|
|
|
|
|
private String description; |
|
|
|
|
|
|
|
private Integer priority; |
|
|
|
|
|
|
|
private Map<String, String> properties; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TestBean(String name, TestBean testBean, String description, Integer priority, Map<String, String> props) { |
|
|
|
|
|
|
|
this.name = name; |
|
|
|
|
|
|
|
this.testBean = testBean; |
|
|
|
|
|
|
|
this.description = description; |
|
|
|
|
|
|
|
this.priority = priority; |
|
|
|
|
|
|
|
this.properties = props; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getName() { |
|
|
|
|
|
|
|
return name; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setName(String name) { |
|
|
|
|
|
|
|
this.name = name; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TestBean getTestBean() { |
|
|
|
|
|
|
|
return testBean; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setTestBean(TestBean testBean) { |
|
|
|
|
|
|
|
this.testBean = testBean; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getDescription() { |
|
|
|
|
|
|
|
return description; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setDescription(String description) { |
|
|
|
|
|
|
|
this.description = description; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Integer getPriority() { |
|
|
|
|
|
|
|
return priority; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setPriority(Integer priority) { |
|
|
|
|
|
|
|
this.priority = priority; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, String> getProperties() { |
|
|
|
|
|
|
|
return properties; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setProperties(Map<String, String> properties) { |
|
|
|
|
|
|
|
this.properties = properties; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class MapAccessor implements PropertyAccessor { |
|
|
|
record TestBean(Map<String, String> properties, TestBean nestedBean) { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean canRead(EvaluationContext context, Object target, String name) { |
|
|
|
|
|
|
|
return (((Map<?, ?>) target).containsKey(name)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public TypedValue read(EvaluationContext context, Object target, String name) { |
|
|
|
|
|
|
|
return new TypedValue(((Map<?, ?>) target).get(name)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean canWrite(EvaluationContext context, Object target, String name) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
public void write(EvaluationContext context, Object target, String name, Object newValue) { |
|
|
|
|
|
|
|
((Map<Object, Object>) target).put(name, newValue); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public Class<?>[] getSpecificTargetClasses() { |
|
|
|
|
|
|
|
return new Class<?>[] {Map.class}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|