Skip to contentMethod: getValue(ELContext, Object, Object)
1: /*
2: * Copyright (c) 2012, 2022 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: /**
21: * <p>
22: * An <code>ELResolver</code> for resolving user or container managed beans.
23: * </p>
24: * <p>
25: * A {@link BeanNameResolver} is required for its proper operation. The following example creates an
26: * <code>ELResolver</code> that resolves the name "bean" to an instance of MyBean.
27: *
28: * <pre>
29: * <code>
30: * ELResovler elr = new BeanNameELResolver(new BeanNameResolver {
31: * public boolean isNameResolved(String beanName) {
32: * return "bean".equals(beanName);
33: * }
34: * public Object getBean(String beanName) {
35: * return "bean".equals(beanName)? new MyBean(): null;
36: * }
37: * });
38: * </code>
39: * </pre>
40: *
41: * @since Jakarta Expression Language 3.0
42: */
43: public class BeanNameELResolver extends ELResolver {
44:
45: private BeanNameResolver beanNameResolver;
46:
47: /**
48: * Constructor
49: *
50: * @param beanNameResolver The {@link BeanNameResolver} that resolves a bean name.
51: */
52: public BeanNameELResolver(BeanNameResolver beanNameResolver) {
53: this.beanNameResolver = beanNameResolver;
54: }
55:
56: /**
57: * If the base object is <code>null</code> and the property is a name that is resolvable by the BeanNameResolver,
58: * returns the value resolved by the BeanNameResolver.
59: *
60: * <p>
61: * If name is resolved by the BeanNameResolver, the <code>propertyResolved</code> property of the <code>ELContext</code>
62: * object must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code>
63: * after this method is called, the caller should ignore the return value.
64: * </p>
65: *
66: * @param context The context of this evaluation.
67: * @param base <code>null</code>
68: * @param property The name of the bean.
69: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
70: * the value of the bean with the given name. Otherwise, undefined.
71: * @throws NullPointerException if context is <code>null</code>.
72: * @throws ELException if an exception was thrown while performing the property or variable resolution. The thrown
73: * exception must be included as the cause property of this exception, if available.
74: */
75: @Override
76: public Object getValue(ELContext context, Object base, Object property) {
77:• if (context == null) {
78: throw new NullPointerException();
79: }
80:
81:• if (base == null && property instanceof String) {
82:• if (beanNameResolver.isNameResolved((String) property)) {
83: context.setPropertyResolved(base, property);
84: return beanNameResolver.getBean((String) property);
85: }
86: }
87:
88: return null;
89: }
90:
91: /**
92: * If the base is null and the property is a name that is resolvable by the BeanNameResolver, the bean in the
93: * BeanNameResolver is set to the given value.
94: *
95: * <p>
96: * If the name is resolvable by the BeanNameResolver, or if the BeanNameResolver allows creating a new bean, the
97: * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
98: * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller can
99: * safely assume no value has been set.
100: * </p>
101: *
102: * @param context The context of this evaluation.
103: * @param base <code>null</code>
104: * @param property The name of the bean
105: * @param value The value to set the bean with the given name to.
106: * @throws NullPointerException if context is <code>null</code>
107: * @throws PropertyNotWritableException if the BeanNameResolver does not allow the bean to be modified.
108: * @throws ELException if an exception was thrown while attempting to set the bean with the given name. The thrown
109: * exception must be included as the cause property of this exception, if available.
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 == null && property instanceof String) {
118: String beanName = (String) property;
119: if (beanNameResolver.isNameResolved(beanName) || beanNameResolver.canCreateBean(beanName)) {
120: beanNameResolver.setBeanValue(beanName, value);
121: context.setPropertyResolved(base, property);
122: }
123: }
124: }
125:
126: /**
127: * If the base is null and the property is a name resolvable by the BeanNameResolver, return the type of the bean.
128: *
129: * <p>
130: * If the name is resolvable by the BeanNameResolver, the <code>propertyResolved</code> property of the
131: * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
132: * not <code>true</code> after this method is called, the caller can safely assume no value has been set.
133: * </p>
134: *
135: * @param context The context of this evaluation.
136: * @param base <code>null</code>
137: * @param property The name of the bean.
138: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code> and
139: * the associated BeanNameResolver is not read-only then the type of the bean with the given name. If the given
140: * bean name was resolved but the associated BeanNameResolver is read-only then {@code null}. Otherwise, undefined.
141: * @throws NullPointerException if context is <code>null</code>.
142: * @throws ELException if an exception was thrown while performing the property or variable resolution. The thrown
143: * exception must be included as the cause property of this exception, if available.
144: */
145: @Override
146: public Class<?> getType(ELContext context, Object base, Object property) {
147: if (context == null) {
148: throw new NullPointerException();
149: }
150:
151: if (base == null && property instanceof String) {
152: if (beanNameResolver.isNameResolved((String) property)) {
153: context.setPropertyResolved(true);
154:
155: /*
156: * No resolver level isReadOnly property for this resolver
157: */
158: if (beanNameResolver.isReadOnly((String) property)) {
159: return null;
160: }
161:
162: return beanNameResolver.getBean((String) property).getClass();
163: }
164: }
165:
166: return null;
167: }
168:
169: /**
170: * If the base is null and the property is a name resolvable by the BeanNameResolver, attempts to determine if the bean
171: * is writable.
172: *
173: * <p>
174: * If the name is resolvable by the BeanNameResolver, the <code>propertyResolved</code> property of the
175: * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
176: * not <code>true</code> after this method is called, the caller can safely assume no value has been set.
177: * </p>
178: *
179: * @param context The context of this evaluation.
180: * @param base <code>null</code>
181: * @param property The name of the bean.
182: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
183: * <code>true</code> if the property is read-only or <code>false</code> if not; otherwise undefined.
184: * @throws NullPointerException if context is <code>null</code>.
185: * @throws ELException if an exception was thrown while performing the property or variable resolution. The thrown
186: * exception must be included as the cause property of this exception, if available.
187: */
188: @Override
189: public boolean isReadOnly(ELContext context, Object base, Object property) {
190: if (context == null) {
191: throw new NullPointerException();
192: }
193:
194: if (base == null && property instanceof String) {
195: if (beanNameResolver.isNameResolved((String) property)) {
196: context.setPropertyResolved(true);
197: return beanNameResolver.isReadOnly((String) property);
198: }
199: }
200:
201: return false;
202: }
203:
204: /**
205: * Always returns <code>String.class</code>, since a bean name is a String.
206: *
207: * @param context The context of this evaluation.
208: * @param base <code>null</code>.
209: * @return <code>String.class</code>.
210: */
211: @Override
212: public Class<?> getCommonPropertyType(ELContext context, Object base) {
213: return String.class;
214: }
215: }