Skip to content

Package: StaticFieldELResolver

StaticFieldELResolver

nameinstructionbranchcomplexitylinemethod
StaticFieldELResolver()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getCommonPropertyType(ELContext, Object)
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getFeatureDescriptors(ELContext, Object)
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getType(ELContext, Object, Object)
M: 59 C: 0
0%
M: 10 C: 0
0%
M: 6 C: 0
0%
M: 14 C: 0
0%
M: 1 C: 0
0%
getValue(ELContext, Object, Object)
M: 64 C: 0
0%
M: 10 C: 0
0%
M: 6 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
invoke(ELContext, Object, Object, Class[], Object[])
M: 55 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 14 C: 0
0%
M: 1 C: 0
0%
isReadOnly(ELContext, Object, Object)
M: 21 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
setValue(ELContext, Object, Object, Object)
M: 38 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2012, 2021 Oracle and/or its affiliates and others.
3: * All rights reserved.
4: *
5: * This program and the accompanying materials are made available under the
6: * terms of the Eclipse Public License v. 2.0, which is available at
7: * http://www.eclipse.org/legal/epl-2.0.
8: *
9: * This Source Code may also be made available under the following Secondary
10: * Licenses when the conditions for such availability set forth in the
11: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
12: * version 2 with the GNU Classpath Exception, which is available at
13: * https://www.gnu.org/software/classpath/license.html.
14: *
15: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16: */
17:
18: package jakarta.el;
19:
20: import static java.lang.reflect.Modifier.isPublic;
21: import static java.lang.reflect.Modifier.isStatic;
22: import static jakarta.el.ELUtil.getExceptionMessageString;
23:
24: import java.beans.FeatureDescriptor;
25: import java.lang.reflect.Constructor;
26: import java.lang.reflect.Field;
27: import java.lang.reflect.Method;
28: import java.util.Iterator;
29:
30: /**
31: * An {@link ELResolver} for resolving static fields, enum constants and static methods. Also handles constructor calls
32: * as a special case.
33: *
34: * <p>
35: * The resolver handles base objects of the type {@link ELClass}, which is usually generated by a Jakarta Expression
36: * Language implementation.
37: *
38: * @see ELClass
39: * @since Jakarta Expression Language 3.0
40: */
41: public class StaticFieldELResolver extends ELResolver {
42:
43: /**
44: * <p>
45: * Returns the value of a static field.
46: * </p>
47: * <p>
48: * If the base object is an instance of <code>ELClass</code> and the property is String, the
49: * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by this
50: * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller should
51: * ignore the return value.
52: * </p>
53: *
54: * If the property is a public static field of class specified in <code>ELClass</code>, return the value of the static
55: * field. An Enum constant is a public static field of an Enum object, and is a special case of this.
56: *
57: * @param context The context of this evaluation.
58: * @param base An <code>ELClass</code>.
59: * @param property A static field name.
60: *
61: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
62: * the static field value.
63: *
64: * @throws NullPointerException if context is <code>null</code>.
65: * @throws PropertyNotFoundException if the specified class does not exist, or if the field is not a public static filed
66: * of the class, or if the field is inaccessible.
67: */
68: @Override
69: public Object getValue(ELContext context, Object base, Object property) {
70:• if (context == null) {
71: throw new NullPointerException();
72: }
73:
74:• if (base instanceof ELClass && property instanceof String) {
75: Class<?> klass = ((ELClass) base).getKlass();
76: String fieldName = (String) property;
77: try {
78: context.setPropertyResolved(base, property);
79: Field field = klass.getField(fieldName);
80:
81: int mod = field.getModifiers();
82:• if (isPublic(mod) && isStatic(mod)) {
83: return field.get(null);
84: }
85: } catch (NoSuchFieldException ex) {
86: } catch (IllegalAccessException ex) {
87: }
88:
89: throw new PropertyNotFoundException(getExceptionMessageString(context, "staticFieldReadError", new Object[] { klass.getName(), fieldName }));
90: }
91:
92: return null;
93: }
94:
95: /**
96: * <p>
97: * Attempts to write to a static field.
98: * </p>
99: * <p>
100: * If the base object is an instance of <code>ELClass</code>and the property is String, a
101: * <code>PropertyNotWritableException</code> will always be thrown, because writing to a static field is not allowed.
102: *
103: * @param context The context of this evaluation.
104: * @param base An <code>ELClass</code>
105: * @param property The name of the field
106: * @param value The value to set the field of the class to.
107: * @throws NullPointerException if context is <code>null</code>
108: * @throws PropertyNotWritableException if base object instance of <code>ELClass</code>and <code>property</code>
109: * instance of String
110: */
111: @Override
112: public void setValue(ELContext context, Object base, Object property, Object value) {
113:• if (context == null) {
114: throw new NullPointerException();
115: }
116:
117:• if (base instanceof ELClass && property instanceof String) {
118: Class<?> klass = ((ELClass) base).getKlass();
119: String fieldName = (String) property;
120: throw new PropertyNotWritableException(
121: getExceptionMessageString(context, "staticFieldWriteError", new Object[] { klass.getName(), fieldName }));
122: }
123: }
124:
125: /**
126: * Invokes a public static method or the constructor for a class.
127: *
128: * <p>
129: * If the base object is an instance of <code>ELClass</code> and the method is a String, the
130: * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
131: * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller should
132: * ignore the return value.
133: *
134: * <p>
135: * Invoke the public static method specified by <code>method</code>.
136: *
137: * <p>
138: * The process involved in the method selection is the same as that used in {@link BeanELResolver}.
139: *
140: * <p>
141: * As a special case, if the name of the method is "<init>", the constructor for the class will be invoked.
142: *
143: * @param base An <code>ELClass</code>
144: * @param methodName When coerced to a <code>String</code>, the simple name of the method.
145: * @param paramTypes An array of Class objects identifying the method's formal parameter types, in declared order. Use
146: * an empty array if the method has no parameters. Can be <code>null</code>, in which case the method's formal parameter
147: * types are assumed to be unknown.
148: * @param params The parameters to pass to the method, or <code>null</code> if no parameters.
149: * @return The result of the method invocation (<code>null</code> if the method has a <code>void</code> return type).
150: * @throws MethodNotFoundException if no suitable method can be found.
151: * @throws ELException if an exception was thrown while performing (base, method) resolution. The thrown exception must
152: * be included as the cause property of this exception, if available. If the exception thrown is an
153: * <code>InvocationTargetException</code>, extract its <code>cause</code> and pass it to the <code>ELException</code>
154: * constructor.
155: */
156: @Override
157: public Object invoke(ELContext context, Object base, Object methodName, Class<?>[] paramTypes, Object[] params) {
158:• if (context == null) {
159: throw new NullPointerException();
160: }
161:
162:• if (!(base instanceof ELClass && methodName instanceof String)) {
163: return null;
164: }
165:
166: Class<?> klass = ((ELClass) base).getKlass();
167: String name = (String) methodName;
168:
169: Object ret;
170:• if ("<init>".equals(name)) {
171: Constructor<?> constructor = ELUtil.findConstructor(klass, paramTypes, params);
172: ret = ELUtil.invokeConstructor(context, constructor, params);
173: } else {
174: Method method = ELUtil.findMethod(klass, name, paramTypes, params, true);
175: ret = ELUtil.invokeMethod(context, method, null, params);
176: }
177: context.setPropertyResolved(base, methodName);
178:
179: return ret;
180: }
181:
182: /**
183: * Returns the type of a static field.
184: *
185: * <p>
186: * If the base object is an instance of <code>ELClass</code>and the property is a String, the
187: * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
188: * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller can
189: * safely assume no value has been set.
190: *
191: * @param context The context of this evaluation.
192: * @param base An <code>ELClass</code>.
193: * @param property The name of the field.
194: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
195: * <code>null</code> otherwise undefined.
196: * @throws NullPointerException if context is <code>null</code>.
197: * @throws PropertyNotFoundException if field is not a public static filed of the class, or if the field is
198: * inaccessible.
199: */
200: @Override
201: public Class<?> getType(ELContext context, Object base, Object property) {
202:• if (context == null) {
203: throw new NullPointerException();
204: }
205:
206:• if (base instanceof ELClass && property instanceof String) {
207: Class<?> klass = ((ELClass) base).getKlass();
208: String fieldName = (String) property;
209: try {
210: context.setPropertyResolved(true);
211: Field field = klass.getField(fieldName);
212:
213: int mod = field.getModifiers();
214:• if (isPublic(mod) && isStatic(mod)) {
215: // Resolver is read-only so need to return null if field is
216: // resolved.
217: return null;
218: }
219: } catch (NoSuchFieldException ex) {
220: }
221: throw new PropertyNotFoundException(getExceptionMessageString(context, "staticFieldReadError", new Object[] { klass.getName(), fieldName }));
222: }
223:
224: return null;
225: }
226:
227: /**
228: * <p>
229: * Inquires whether the static field is writable.
230: * </p>
231: * <p>
232: * If the base object is an instance of <code>ELClass</code>and the property is a String, the
233: * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
234: * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller can
235: * safely assume no value has been set.
236: * </p>
237: *
238: * <p>
239: * Always returns a <code>true</code> because writing to a static field is not allowed.
240: * </p>
241: *
242: * @param context The context of this evaluation.
243: * @param base An <code>ELClass</code>.
244: * @param property The name of the bean.
245: * @return <code>true</code>
246: * @throws NullPointerException if context is <code>null</code>.
247: */
248: @Override
249: public boolean isReadOnly(ELContext context, Object base, Object property) {
250:• if (context == null) {
251: throw new NullPointerException();
252: }
253:
254:• if (base instanceof ELClass && property instanceof String) {
255: ((ELClass) base).getKlass();
256: context.setPropertyResolved(true);
257: }
258:
259: return true;
260: }
261:
262: /**
263: * Returns the properties that can be resolved. Always returns <code>null</code>, since there is no reason to iterate
264: * through a list of one element: field name.
265: *
266: * @param context The context of this evaluation.
267: * @param base An <code>ELClass</code>.
268: * @return <code>null</code>.
269: *
270: * @deprecated This method will be removed without replacement in EL 6.0
271: */
272: @Deprecated(forRemoval = true, since = "5.0")
273: @Override
274: public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
275: return null;
276: }
277:
278: /**
279: * Returns the type of the property. Always returns <code>String.class</code>, since a field name is a String.
280: *
281: * @param context The context of this evaluation.
282: * @param base An <code>ELClass</code>.
283: * @return <code>String.class</code>.
284: */
285: @Override
286: public Class<?> getCommonPropertyType(ELContext context, Object base) {
287: return String.class;
288: }
289: }