View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.expression.spel.ast;
18  
19  import java.util.List;
20  
21  import org.springframework.expression.EvaluationException;
22  import org.springframework.expression.TypeComparator;
23  import org.springframework.expression.spel.ExpressionState;
24  import org.springframework.expression.spel.SpelEvaluationException;
25  import org.springframework.expression.spel.SpelMessage;
26  import org.springframework.expression.spel.support.BooleanTypedValue;
27  
28  /**
29   * Represents the between operator. The left operand to between must be a single value and
30   * the right operand must be a list - this operator returns true if the left operand is
31   * between (using the registered comparator) the two elements in the list. The definition
32   * of between being inclusive follows the SQL BETWEEN definition.
33   *
34   * @author Andy Clement
35   * @since 3.0
36   */
37  public class OperatorBetween extends Operator {
38  
39  	public OperatorBetween(int pos, SpelNodeImpl... operands) {
40  		super("between", pos, operands);
41  	}
42  
43  
44  	/**
45  	 * Returns a boolean based on whether a value is in the range expressed. The first
46  	 * operand is any value whilst the second is a list of two values - those two values
47  	 * being the bounds allowed for the first operand (inclusive).
48  	 * @param state the expression state
49  	 * @return true if the left operand is in the range specified, false otherwise
50  	 * @throws EvaluationException if there is a problem evaluating the expression
51  	 */
52  	@Override
53  	public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
54  		Object left = getLeftOperand().getValueInternal(state).getValue();
55  		Object right = getRightOperand().getValueInternal(state).getValue();
56  		if (!(right instanceof List) || ((List<?>) right).size() != 2) {
57  			throw new SpelEvaluationException(getRightOperand().getStartPosition(),
58  					SpelMessage.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST);
59  		}
60  
61  		List<?> list = (List<?>) right;
62  		Object low = list.get(0);
63  		Object high = list.get(1);
64  		TypeComparator comp = state.getTypeComparator();
65  		try {
66  			return BooleanTypedValue.forValue(comp.compare(left, low) >= 0 && comp.compare(left, high) <= 0);
67  		}
68  		catch (SpelEvaluationException ex) {
69  			ex.setPosition(getStartPosition());
70  			throw ex;
71  		}
72  	}
73  
74  }