View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jexl3.internal;
18  
19  import org.apache.commons.jexl3.JexlBuilder;
20  import org.apache.commons.jexl3.JexlContext;
21  import org.apache.commons.jexl3.JexlOptions;
22  import org.apache.commons.jexl3.parser.ASTArrayAccess;
23  import org.apache.commons.jexl3.parser.ASTAssignment;
24  import org.apache.commons.jexl3.parser.ASTEQNode;
25  import org.apache.commons.jexl3.parser.ASTIdentifier;
26  import org.apache.commons.jexl3.parser.ASTNENode;
27  import org.apache.commons.jexl3.parser.ASTNullpNode;
28  import org.apache.commons.jexl3.parser.ASTReference;
29  import org.apache.commons.jexl3.parser.ASTTernaryNode;
30  import org.apache.commons.jexl3.parser.JexlNode;
31  
32  /**
33   * An Engine that behaves like JEXL 3.2, bugs included.
34   *
35   * @deprecated 3.6.1, use Engine with JexlOptions instead.
36   */
37  @Deprecated
38  public class Engine32 extends Engine {
39  
40      /**
41       * Static delegation of getVariable.
42       *
43       * @param ii the interpreter
44       * @param frame the frame
45       * @param block the scope
46       * @param identifier the variable identifier
47       * @return the variable value
48       */
49      static Object getVariable(final Interpreter ii, final Frame frame, final LexicalScope block, final ASTIdentifier identifier) {
50          final int symbol = identifier.getSymbol();
51          // if we have a symbol, we have a scope thus a frame
52          if ((ii.options.isLexicalShade() || identifier.isLexical()) && identifier.isShaded()) {
53              return ii.undefinedVariable(identifier, identifier.getName());
54          }
55          if (symbol >= 0 && frame.has(symbol)) {
56              final Object value = frame.get(symbol);
57              if (value != Scope.UNDEFINED) {
58                  return value;
59              }
60          }
61          final String name = identifier.getName();
62          final Object value = ii.context.get(name);
63          if (value == null && !ii.context.has(name)) {
64              final boolean ignore = ii.isSafe()
65                      && (symbol >= 0
66                      || identifier.jjtGetParent() instanceof ASTAssignment)
67                      || identifier.jjtGetParent() instanceof ASTReference;
68              if (!ignore) {
69                  return ii.unsolvableVariable(identifier, name, true); // undefined
70              }
71          }
72          return value;
73      }
74  
75      /**
76       * Static delegation of isTernaryProtected.
77       *
78       * @param ii the interpreter (unused)
79       * @param startNode the node
80       * @return true if node is navigation-safe, false otherwise
81       */
82      static boolean isTernaryProtected(final Interpreter ii, final JexlNode startNode) {
83          JexlNode node = startNode;
84          for (JexlNode walk = node.jjtGetParent(); walk != null; walk = walk.jjtGetParent()) {
85              // protect only the condition part of the ternary
86              if (walk instanceof ASTTernaryNode
87                      || walk instanceof ASTNullpNode
88                      || walk instanceof ASTEQNode
89                      || walk instanceof ASTNENode) {
90                  return node == walk.jjtGetChild(0);
91              }
92              if (!(walk instanceof ASTReference || walk instanceof ASTArrayAccess)) {
93                  break;
94              }
95              node = walk;
96          }
97          return false;
98      }
99  
100     public Engine32() {
101     }
102 
103     public Engine32(final JexlBuilder conf) {
104         super(conf);
105     }
106 
107     @Override
108     protected Interpreter createInterpreter(final JexlContext context, final Frame frame, final JexlOptions opts) {
109         return new Interpreter(this, opts, context, frame) {
110             @Override
111             protected Object getVariable(final Frame frame, final LexicalScope block, final ASTIdentifier identifier) {
112                 return Engine32.getVariable(this, frame, block, identifier);
113             }
114 
115             @Override
116             protected boolean isStrictOperand(final JexlNode node) {
117                 return false;
118             }
119 
120             @Override
121             protected boolean isTernaryProtected(final JexlNode node) {
122                 return Engine32.isTernaryProtected(this, node);
123             }
124         };
125     }
126 
127     @Override
128     protected Interpreter createTemplateInterpreter(final TemplateInterpreter.Arguments args) {
129         return new TemplateInterpreter(args) {
130             @Override
131             protected Object getVariable(final Frame frame, final LexicalScope block, final ASTIdentifier identifier) {
132                 return Engine32.getVariable(this, frame, block, identifier);
133             }
134 
135             @Override
136             protected boolean isStrictOperand(final JexlNode node) {
137                 return false;
138             }
139 
140             @Override
141             protected boolean isTernaryProtected(final JexlNode node) {
142                 return Engine32.isTernaryProtected(this, node);
143             }
144         };
145     }
146 }