1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3.internal;
18
19
20 import org.apache.commons.jexl3.JexlBuilder;
21 import org.apache.commons.jexl3.JexlContext;
22 import org.apache.commons.jexl3.JexlOptions;
23 import org.apache.commons.jexl3.parser.ASTArrayAccess;
24 import org.apache.commons.jexl3.parser.ASTAssignment;
25 import org.apache.commons.jexl3.parser.ASTEQNode;
26 import org.apache.commons.jexl3.parser.ASTIdentifier;
27 import org.apache.commons.jexl3.parser.ASTNENode;
28 import org.apache.commons.jexl3.parser.ASTNullpNode;
29 import org.apache.commons.jexl3.parser.ASTReference;
30 import org.apache.commons.jexl3.parser.ASTTernaryNode;
31 import org.apache.commons.jexl3.parser.JexlNode;
32
33
34
35
36 public class Engine32 extends Engine {
37 public Engine32(final JexlBuilder conf) {
38 super(conf);
39 }
40
41 public Engine32() {
42 }
43
44
45
46
47
48
49
50 static boolean isTernaryProtected(final Interpreter ii, JexlNode node) {
51 for (JexlNode walk = node.jjtGetParent(); walk != null; walk = walk.jjtGetParent()) {
52
53 if (walk instanceof ASTTernaryNode
54 || walk instanceof ASTNullpNode
55 || walk instanceof ASTEQNode
56 || walk instanceof ASTNENode) {
57 return node == walk.jjtGetChild(0);
58 }
59 if (!(walk instanceof ASTReference || walk instanceof ASTArrayAccess)) {
60 break;
61 }
62 node = walk;
63 }
64 return false;
65 }
66
67
68
69
70
71
72
73
74
75 static Object getVariable(final Interpreter ii, final Frame frame, final LexicalScope block, final ASTIdentifier identifier) {
76 final int symbol = identifier.getSymbol();
77
78 if ((ii.options.isLexicalShade() || identifier.isLexical()) && identifier.isShaded()) {
79 return ii.undefinedVariable(identifier, identifier.getName());
80 }
81 if (symbol >= 0) {
82 if (frame.has(symbol)) {
83 final Object value = frame.get(symbol);
84 if (value != Scope.UNDEFINED) {
85 return value;
86 }
87 }
88 }
89 final String name = identifier.getName();
90 final Object value = ii.context.get(name);
91 if (value == null && !ii.context.has(name)) {
92 final boolean ignore = (ii.isSafe()
93 && (symbol >= 0
94 || identifier.jjtGetParent() instanceof ASTAssignment))
95 || (identifier.jjtGetParent() instanceof ASTReference);
96 if (!ignore) {
97 return ii.unsolvableVariable(identifier, name, true);
98 }
99 }
100 return value;
101 }
102
103 @Override
104 protected Interpreter createInterpreter(final JexlContext context, final Frame frame, final JexlOptions opts) {
105 return new Interpreter(this, opts, context, frame) {
106 @Override
107 protected boolean isStrictOperand(final JexlNode node) {
108 return false;
109 }
110
111 @Override
112 protected boolean isTernaryProtected( final JexlNode node) {
113 return Engine32.isTernaryProtected(this, node);
114 }
115
116 @Override
117 protected Object getVariable(final Frame frame, final LexicalScope block, final ASTIdentifier identifier) {
118 return Engine32.getVariable(this, frame, block, identifier);
119 }
120 };
121 }
122
123 @Override
124 protected Interpreter createTemplateInterpreter(final TemplateInterpreter.Arguments args) {
125 return new TemplateInterpreter(args) {
126 @Override
127 protected boolean isStrictOperand(final JexlNode node) {
128 return false;
129 }
130
131 @Override
132 protected boolean isTernaryProtected( final JexlNode node) {
133 return Engine32.isTernaryProtected(this, node);
134 }
135
136 @Override
137 protected Object getVariable(final Frame frame, final LexicalScope block, final ASTIdentifier identifier) {
138 return Engine32.getVariable(this, frame, block, identifier);
139 }
140 };
141 }
142 }