1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.expression.spel.ast;
18
19 import java.math.BigDecimal;
20 import java.math.BigInteger;
21
22 import org.springframework.asm.MethodVisitor;
23 import org.springframework.expression.EvaluationException;
24 import org.springframework.expression.spel.CodeFlow;
25 import org.springframework.expression.spel.ExpressionState;
26 import org.springframework.expression.spel.support.BooleanTypedValue;
27 import org.springframework.util.NumberUtils;
28
29
30
31
32
33
34
35
36
37 public class OpLT extends Operator {
38
39 public OpLT(int pos, SpelNodeImpl... operands) {
40 super("<", pos, operands);
41 this.exitTypeDescriptor = "Z";
42 }
43
44
45 @Override
46 public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
47 Object left = getLeftOperand().getValueInternal(state).getValue();
48 Object right = getRightOperand().getValueInternal(state).getValue();
49
50 this.leftActualDescriptor = CodeFlow.toDescriptorFromObject(left);
51 this.rightActualDescriptor = CodeFlow.toDescriptorFromObject(right);
52
53 if (left instanceof Number && right instanceof Number) {
54 Number leftNumber = (Number) left;
55 Number rightNumber = (Number) right;
56
57 if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
58 BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
59 BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
60 return BooleanTypedValue.forValue(leftBigDecimal.compareTo(rightBigDecimal) < 0);
61 }
62 else if (leftNumber instanceof Double || rightNumber instanceof Double) {
63 return BooleanTypedValue.forValue(leftNumber.doubleValue() < rightNumber.doubleValue());
64 }
65 else if (leftNumber instanceof Float || rightNumber instanceof Float) {
66 return BooleanTypedValue.forValue(leftNumber.floatValue() < rightNumber.floatValue());
67 }
68 else if (leftNumber instanceof BigInteger || rightNumber instanceof BigInteger) {
69 BigInteger leftBigInteger = NumberUtils.convertNumberToTargetClass(leftNumber, BigInteger.class);
70 BigInteger rightBigInteger = NumberUtils.convertNumberToTargetClass(rightNumber, BigInteger.class);
71 return BooleanTypedValue.forValue(leftBigInteger.compareTo(rightBigInteger) < 0);
72 }
73 else if (leftNumber instanceof Long || rightNumber instanceof Long) {
74 return BooleanTypedValue.forValue(leftNumber.longValue() < rightNumber.longValue());
75 }
76 else if (leftNumber instanceof Integer || rightNumber instanceof Integer) {
77 return BooleanTypedValue.forValue(leftNumber.intValue() < rightNumber.intValue());
78 }
79 else if (leftNumber instanceof Short || rightNumber instanceof Short) {
80 return BooleanTypedValue.forValue(leftNumber.shortValue() < rightNumber.shortValue());
81 }
82 else if (leftNumber instanceof Byte || rightNumber instanceof Byte) {
83 return BooleanTypedValue.forValue(leftNumber.byteValue() < rightNumber.byteValue());
84 }
85 else {
86
87 return BooleanTypedValue.forValue(leftNumber.doubleValue() < rightNumber.doubleValue());
88 }
89 }
90
91 if (left instanceof CharSequence && right instanceof CharSequence) {
92 left = left.toString();
93 right = right.toString();
94 }
95
96 return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) < 0);
97 }
98
99 @Override
100 public boolean isCompilable() {
101 return isCompilableOperatorUsingNumerics();
102 }
103
104 @Override
105 public void generateCode(MethodVisitor mv, CodeFlow cf) {
106 generateComparisonCode(mv, cf, IFGE, IF_ICMPGE);
107 }
108
109 }