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 org.springframework.asm.Label;
20 import org.springframework.asm.MethodVisitor;
21 import org.springframework.expression.EvaluationException;
22 import org.springframework.expression.spel.CodeFlow;
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
30
31
32
33
34
35
36 public class OpOr extends Operator {
37
38 public OpOr(int pos, SpelNodeImpl... operands) {
39 super("or", pos, operands);
40 this.exitTypeDescriptor = "Z";
41 }
42
43
44 @Override
45 public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
46 if (getBooleanValue(state, getLeftOperand())) {
47
48 return BooleanTypedValue.TRUE;
49 }
50 return BooleanTypedValue.forValue(getBooleanValue(state, getRightOperand()));
51 }
52
53 private boolean getBooleanValue(ExpressionState state, SpelNodeImpl operand) {
54 try {
55 Boolean value = operand.getValue(state, Boolean.class);
56 assertValueNotNull(value);
57 return value;
58 }
59 catch (SpelEvaluationException ee) {
60 ee.setPosition(operand.getStartPosition());
61 throw ee;
62 }
63 }
64
65 private void assertValueNotNull(Boolean value) {
66 if (value == null) {
67 throw new SpelEvaluationException(SpelMessage.TYPE_CONVERSION_ERROR, "null", "boolean");
68 }
69 }
70
71 @Override
72 public boolean isCompilable() {
73 SpelNodeImpl left = getLeftOperand();
74 SpelNodeImpl right = getRightOperand();
75 return (left.isCompilable() && right.isCompilable() &&
76 CodeFlow.isBooleanCompatible(left.exitTypeDescriptor) &&
77 CodeFlow.isBooleanCompatible(right.exitTypeDescriptor));
78 }
79
80 @Override
81 public void generateCode(MethodVisitor mv, CodeFlow cf) {
82
83 Label elseTarget = new Label();
84 Label endOfIf = new Label();
85 cf.enterCompilationScope();
86 getLeftOperand().generateCode(mv, cf);
87 cf.unboxBooleanIfNecessary(mv);
88 cf.exitCompilationScope();
89 mv.visitJumpInsn(IFEQ, elseTarget);
90 mv.visitLdcInsn(1);
91 mv.visitJumpInsn(GOTO,endOfIf);
92 mv.visitLabel(elseTarget);
93 cf.enterCompilationScope();
94 getRightOperand().generateCode(mv, cf);
95 cf.unboxBooleanIfNecessary(mv);
96 cf.exitCompilationScope();
97 mv.visitLabel(endOfIf);
98 cf.pushDescriptor(this.exitTypeDescriptor);
99 }
100
101 }