Skip to content

Package: AstValue

AstValue

nameinstructionbranchcomplexitylinemethod
AstValue(int)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
getArguments(Node)
M: 25 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
getBase(EvaluationContext)
M: 39 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%
getMethodInfo(EvaluationContext, Class[])
M: 33 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
getTarget(EvaluationContext)
M: 63 C: 0
0%
M: 10 C: 0
0%
M: 6 C: 0
0%
M: 13 C: 0
0%
M: 1 C: 0
0%
getType(EvaluationContext)
M: 34 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
getValue(EvaluationContext)
M: 27 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
getValue(Object, Node, EvaluationContext)
M: 62 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 18 C: 0
0%
M: 1 C: 0
0%
getValueReference(EvaluationContext)
M: 21 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
invoke(EvaluationContext, Class[], Object[])
M: 60 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
isParametersProvided()
M: 13 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
isReadOnly(EvaluationContext)
M: 34 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
setValue(EvaluationContext, Object)
M: 78 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package com.sun.el.parser;
18:
19: import java.lang.reflect.Method;
20:
21: import jakarta.el.ELClass;
22: import jakarta.el.ELException;
23: import jakarta.el.ELResolver;
24: import jakarta.el.ImportHandler;
25: import jakarta.el.MethodInfo;
26: import jakarta.el.PropertyNotFoundException;
27: import jakarta.el.PropertyNotWritableException;
28: import jakarta.el.ValueReference;
29:
30: import com.sun.el.lang.ELSupport;
31: import com.sun.el.lang.EvaluationContext;
32: import com.sun.el.util.MessageFactory;
33: import com.sun.el.util.ReflectionUtil;
34:
35: /**
36: * @author Jacob Hookom [jacob@hookom.net]
37: * @author Kin-man Chung
38: * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
39: */
40: public final class AstValue extends SimpleNode {
41:
42: protected static class Target {
43: protected Object base;
44: protected Node suffixNode;
45:
46: Target(Object base, Node suffixNode) {
47: this.base = base;
48: this.suffixNode = suffixNode;
49: }
50:
51: boolean isMethodCall() {
52: return getArguments(suffixNode) != null;
53: }
54: }
55:
56: public AstValue(int id) {
57: super(id);
58: }
59:
60: @Override
61: public Class getType(EvaluationContext ctx) throws ELException {
62: Target t = getTarget(ctx);
63:• if (t.isMethodCall()) {
64: return null;
65: }
66: Object property = t.suffixNode.getValue(ctx);
67: ctx.setPropertyResolved(false);
68: Class ret = ctx.getELResolver().getType(ctx, t.base, property);
69:• if (!ctx.isPropertyResolved()) {
70: ELSupport.throwUnhandled(t.base, property);
71: }
72: return ret;
73: }
74:
75: @Override
76: public ValueReference getValueReference(EvaluationContext ctx) throws ELException {
77: Target t = getTarget(ctx);
78:• if (t.isMethodCall()) {
79: return null;
80: }
81: Object property = t.suffixNode.getValue(ctx);
82: return new ValueReference(t.base, property);
83: }
84:
85: private static AstMethodArguments getArguments(Node n) {
86:• if (n instanceof AstDotSuffix && n.jjtGetNumChildren() > 0) {
87: return (AstMethodArguments) n.jjtGetChild(0);
88: }
89:• if (n instanceof AstBracketSuffix && n.jjtGetNumChildren() > 1) {
90: return (AstMethodArguments) n.jjtGetChild(1);
91: }
92: return null;
93: }
94:
95: private Object getValue(Object base, Node child, EvaluationContext ctx) throws ELException {
96:
97: Object value = null;
98: ELResolver resolver = ctx.getELResolver();
99: Object property = child.getValue(ctx);
100: AstMethodArguments args = getArguments(child);
101:• if (args != null) {
102: // This is a method call
103:• if (!(property instanceof String)) {
104: throw new ELException(MessageFactory.get("error.method.name", property));
105: }
106: Class<?>[] paramTypes = args.getParamTypes();
107: Object[] params = args.getParameters(ctx);
108:
109: ctx.setPropertyResolved(false);
110: value = resolver.invoke(ctx, base, property, paramTypes, params);
111: } else {
112:• if (property != null) {
113: ctx.setPropertyResolved(false);
114: value = resolver.getValue(ctx, base, property);
115:• if (!ctx.isPropertyResolved()) {
116: ELSupport.throwUnhandled(base, property);
117: }
118: }
119: }
120: return value;
121: }
122:
123: private Object getBase(EvaluationContext ctx) {
124: try {
125: return this.children[0].getValue(ctx);
126: } catch (PropertyNotFoundException ex) {
127: // Next check if the base is an imported class
128:• if (this.children[0] instanceof AstIdentifier) {
129: String name = ((AstIdentifier) this.children[0]).image;
130: ImportHandler importHandler = ctx.getImportHandler();
131:• if (importHandler != null) {
132: Class<?> c = importHandler.resolveClass(name);
133:• if (c != null) {
134: return new ELClass(c);
135: }
136: }
137: }
138: throw ex;
139: }
140: }
141:
142: private Target getTarget(EvaluationContext ctx) throws ELException {
143: // evaluate expr-a to value-a
144: Object base = getBase(ctx);
145:
146: // if our base is null (we know there are more properites to evaluate)
147:• if (base == null) {
148: throw new PropertyNotFoundException(MessageFactory.get("error.unreachable.base", this.children[0].getImage()));
149: }
150:
151: // set up our start/end
152: Object property = null;
153: int propCount = this.jjtGetNumChildren() - 1;
154: int i = 1;
155:
156: // evaluate any properties before our target
157:• if (propCount > 1) {
158:• while (base != null && i < propCount) {
159: base = getValue(base, this.children[i], ctx);
160: i++;
161: }
162: // if we are in this block, we have more properties to resolve,
163: // but our base was null
164:• if (base == null) {
165: throw new PropertyNotFoundException(MessageFactory.get("error.unreachable.property", property));
166: }
167: }
168: return new Target(base, this.children[propCount]);
169: }
170:
171: @Override
172: public Object getValue(EvaluationContext ctx) throws ELException {
173: Object base = getBase(ctx);
174: int propCount = this.jjtGetNumChildren();
175: int i = 1;
176:• while (base != null && i < propCount) {
177: base = getValue(base, this.children[i], ctx);
178: i++;
179: }
180: return base;
181: }
182:
183: @Override
184: public boolean isReadOnly(EvaluationContext ctx) throws ELException {
185: Target t = getTarget(ctx);
186:• if (t.isMethodCall()) {
187: return true;
188: }
189: Object property = t.suffixNode.getValue(ctx);
190: ctx.setPropertyResolved(false);
191: boolean ret = ctx.getELResolver().isReadOnly(ctx, t.base, property);
192:• if (!ctx.isPropertyResolved()) {
193: ELSupport.throwUnhandled(t.base, property);
194: }
195: return ret;
196: }
197:
198: @Override
199: public void setValue(EvaluationContext ctx, Object value) throws ELException {
200: Target t = getTarget(ctx);
201:• if (t.isMethodCall()) {
202: throw new PropertyNotWritableException(MessageFactory.get("error.syntax.set"));
203: }
204: Object property = t.suffixNode.getValue(ctx);
205: ELResolver elResolver = ctx.getELResolver();
206:
207: /*
208: * Note by kchung 10/2013 The spec does not say if the value should be cocerced to the target type before setting the
209: * value to the target. The conversion is kept here to be backward compatible.
210: */
211: ctx.setPropertyResolved(false);
212: Class<?> targetType = elResolver.getType(ctx, t.base, property);
213:• if (ctx.isPropertyResolved()) {
214: ctx.setPropertyResolved(false);
215: Object targetValue = elResolver.convertToType(ctx, value, targetType);
216:
217:• if (ctx.isPropertyResolved()) {
218: value = targetValue;
219: } else {
220:• if (value != null || (targetType != null && targetType.isPrimitive())) {
221: value = ELSupport.coerceToType(value, targetType);
222: }
223: }
224: }
225:
226: ctx.setPropertyResolved(false);
227: elResolver.setValue(ctx, t.base, property, value);
228:• if (!ctx.isPropertyResolved()) {
229: ELSupport.throwUnhandled(t.base, property);
230: }
231: }
232:
233: @Override
234: public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException {
235: Target t = getTarget(ctx);
236:• if (t.isMethodCall()) {
237: return null;
238: }
239: Object property = t.suffixNode.getValue(ctx);
240: Method m = ReflectionUtil.findMethod(t.base.getClass(), property.toString(), paramTypes, null);
241: return new MethodInfo(m.getName(), m.getReturnType(), m.getParameterTypes());
242: }
243:
244: @Override
245: public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException {
246: Target t = getTarget(ctx);
247:• if (t.isMethodCall()) {
248: AstMethodArguments args = getArguments(t.suffixNode);
249: // Always use the param types in the expression, and ignore those
250: // specified elsewhere, such as TLD
251: paramTypes = args.getParamTypes();
252: Object[] params = args.getParameters(ctx);
253: String method = (String) t.suffixNode.getValue(ctx);
254:
255: ctx.setPropertyResolved(false);
256: ELResolver resolver = ctx.getELResolver();
257: return resolver.invoke(ctx, t.base, method, paramTypes, params);
258: }
259: Object property = t.suffixNode.getValue(ctx);
260: Method m = ReflectionUtil.findMethod(t.base.getClass(), property.toString(), paramTypes, paramValues);
261: return ReflectionUtil.invokeMethod(ctx, m, t.base, paramValues);
262: }
263:
264: @Override
265: public boolean isParametersProvided() {
266:• return getArguments(this.children[this.jjtGetNumChildren() - 1]) != null;
267: }
268: }