/* * Copyright 2002-2016 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; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.junit.Test; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.TypedValue; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import static org.junit.Assert.*; /** * @author Mark Fisher * @author Sam Brannen * @author Juergen Hoeller */ public class SelectionAndProjectionTests { @Test public void selectionWithList() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ListTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof List); List<?> list = (List<?>) value; assertEquals(5, list.size()); assertEquals(0, list.get(0)); assertEquals(1, list.get(1)); assertEquals(2, list.get(2)); assertEquals(3, list.get(3)); assertEquals(4, list.get(4)); } @Test public void selectFirstItemInList() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ListTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(0, value); } @Test public void selectLastItemInList() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ListTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(4, value); } @Test public void selectionWithSet() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new SetTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof List); List<?> list = (List<?>) value; assertEquals(5, list.size()); assertEquals(0, list.get(0)); assertEquals(1, list.get(1)); assertEquals(2, list.get(2)); assertEquals(3, list.get(3)); assertEquals(4, list.get(4)); } @Test public void selectFirstItemInSet() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new SetTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(0, value); } @Test public void selectLastItemInSet() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new SetTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(4, value); } @Test public void selectionWithIterable() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new IterableTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof List); List<?> list = (List<?>) value; assertEquals(5, list.size()); assertEquals(0, list.get(0)); assertEquals(1, list.get(1)); assertEquals(2, list.get(2)); assertEquals(3, list.get(3)); assertEquals(4, list.get(4)); } @Test public void selectionWithArray() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean()); Object value = expression.getValue(context); assertTrue(value.getClass().isArray()); TypedValue typedValue = new TypedValue(value); assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementTypeDescriptor().getType()); Integer[] array = (Integer[]) value; assertEquals(5, array.length); assertEquals(new Integer(0), array[0]); assertEquals(new Integer(1), array[1]); assertEquals(new Integer(2), array[2]); assertEquals(new Integer(3), array[3]); assertEquals(new Integer(4), array[4]); } @Test public void selectFirstItemInArray() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(0, value); } @Test public void selectLastItemInArray() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(4, value); } @Test public void selectionWithPrimitiveArray() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("ints.?[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean()); Object value = expression.getValue(context); assertTrue(value.getClass().isArray()); TypedValue typedValue = new TypedValue(value); assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementTypeDescriptor().getType()); Integer[] array = (Integer[]) value; assertEquals(5, array.length); assertEquals(new Integer(0), array[0]); assertEquals(new Integer(1), array[1]); assertEquals(new Integer(2), array[2]); assertEquals(new Integer(3), array[3]); assertEquals(new Integer(4), array[4]); } @Test public void selectFirstItemInPrimitiveArray() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("ints.^[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(0, value); } @Test public void selectLastItemInPrimitiveArray() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("ints.$[#this<5]"); EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean()); Object value = expression.getValue(context); assertTrue(value instanceof Integer); assertEquals(4, value); } @Test @SuppressWarnings("unchecked") public void selectionWithMap() { EvaluationContext context = new StandardEvaluationContext(new MapTestBean()); ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("colors.?[key.startsWith('b')]"); Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context); assertEquals(3, colorsMap.size()); assertTrue(colorsMap.containsKey("beige")); assertTrue(colorsMap.containsKey("blue")); assertTrue(colorsMap.containsKey("brown")); } @Test @SuppressWarnings("unchecked") public void selectFirstItemInMap() { EvaluationContext context = new StandardEvaluationContext(new MapTestBean()); ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("colors.^[key.startsWith('b')]"); Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context); assertEquals(1, colorsMap.size()); assertEquals("beige", colorsMap.keySet().iterator().next()); } @Test @SuppressWarnings("unchecked") public void selectLastItemInMap() { EvaluationContext context = new StandardEvaluationContext(new MapTestBean()); ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("colors.$[key.startsWith('b')]"); Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context); assertEquals(1, colorsMap.size()); assertEquals("brown", colorsMap.keySet().iterator().next()); } @Test public void projectionWithList() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("#testList.![wrapper.value]"); EvaluationContext context = new StandardEvaluationContext(); context.setVariable("testList", IntegerTestBean.createList()); Object value = expression.getValue(context); assertTrue(value instanceof List); List<?> list = (List<?>) value; assertEquals(3, list.size()); assertEquals(5, list.get(0)); assertEquals(6, list.get(1)); assertEquals(7, list.get(2)); } @Test public void projectionWithSet() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("#testList.![wrapper.value]"); EvaluationContext context = new StandardEvaluationContext(); context.setVariable("testList", IntegerTestBean.createSet()); Object value = expression.getValue(context); assertTrue(value instanceof List); List<?> list = (List<?>) value; assertEquals(3, list.size()); assertEquals(5, list.get(0)); assertEquals(6, list.get(1)); assertEquals(7, list.get(2)); } @Test public void projectionWithIterable() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("#testList.![wrapper.value]"); EvaluationContext context = new StandardEvaluationContext(); context.setVariable("testList", IntegerTestBean.createIterable()); Object value = expression.getValue(context); assertTrue(value instanceof List); List<?> list = (List<?>) value; assertEquals(3, list.size()); assertEquals(5, list.get(0)); assertEquals(6, list.get(1)); assertEquals(7, list.get(2)); } @Test public void projectionWithArray() throws Exception { Expression expression = new SpelExpressionParser().parseRaw("#testArray.![wrapper.value]"); EvaluationContext context = new StandardEvaluationContext(); context.setVariable("testArray", IntegerTestBean.createArray()); Object value = expression.getValue(context); assertTrue(value.getClass().isArray()); TypedValue typedValue = new TypedValue(value); assertEquals(Number.class, typedValue.getTypeDescriptor().getElementTypeDescriptor().getType()); Number[] array = (Number[]) value; assertEquals(3, array.length); assertEquals(new Integer(5), array[0]); assertEquals(5.9f, array[1]); assertEquals(new Integer(7), array[2]); } static class ListTestBean { private final List<Integer> integers = new ArrayList<>(); ListTestBean() { for (int i = 0; i < 10; i++) { integers.add(i); } } public List<Integer> getIntegers() { return integers; } } static class SetTestBean { private final Set<Integer> integers = new LinkedHashSet<>(); SetTestBean() { for (int i = 0; i < 10; i++) { integers.add(i); } } public Set<Integer> getIntegers() { return integers; } } static class IterableTestBean { private final Set<Integer> integers = new LinkedHashSet<>(); IterableTestBean() { for (int i = 0; i < 10; i++) { integers.add(i); } } public Iterable<Integer> getIntegers() { return new Iterable<Integer>() { @Override public Iterator<Integer> iterator() { return integers.iterator(); } }; } } static class ArrayTestBean { private final int[] ints = new int[10]; private final Integer[] integers = new Integer[10]; ArrayTestBean() { for (int i = 0; i < 10; i++) { ints[i] = i; integers[i] = i; } } public int[] getInts() { return ints; } public Integer[] getIntegers() { return integers; } } static class MapTestBean { private final Map<String, String> colors = new TreeMap<>(); MapTestBean() { // colors.put("black", "schwarz"); colors.put("red", "rot"); colors.put("brown", "braun"); colors.put("blue", "blau"); colors.put("yellow", "gelb"); colors.put("beige", "beige"); } public Map<String, String> getColors() { return colors; } } static class IntegerTestBean { private final IntegerWrapper wrapper; IntegerTestBean(Number value) { this.wrapper = new IntegerWrapper(value); } public IntegerWrapper getWrapper() { return this.wrapper; } static List<IntegerTestBean> createList() { List<IntegerTestBean> list = new ArrayList<>(); for (int i = 0; i < 3; i++) { list.add(new IntegerTestBean(i + 5)); } return list; } static Set<IntegerTestBean> createSet() { Set<IntegerTestBean> set = new LinkedHashSet<>(); for (int i = 0; i < 3; i++) { set.add(new IntegerTestBean(i + 5)); } return set; } static Iterable<IntegerTestBean> createIterable() { final Set<IntegerTestBean> set = createSet(); return new Iterable<IntegerTestBean>() { @Override public Iterator<IntegerTestBean> iterator() { return set.iterator(); } }; } static IntegerTestBean[] createArray() { IntegerTestBean[] array = new IntegerTestBean[3]; for (int i = 0; i < 3; i++) { if (i == 1) { array[i] = new IntegerTestBean(5.9f); } else { array[i] = new IntegerTestBean(i + 5); } } return array; } } static class IntegerWrapper { private final Number value; IntegerWrapper(Number value) { this.value = value; } public Number getValue() { return this.value; } } }