This repository was archived by the owner on Jan 30, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathStandardELContext.java
More file actions
308 lines (269 loc) · 10.3 KB
/
StandardELContext.java
File metadata and controls
308 lines (269 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.el;
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Method;
/**
* A standard ELContext suitable for use in a stand alone environment.
* This class provides a default implementation of an ELResolver that contains
* a number of useful ELResolvers. It also provides local repositories for
* the FunctionMapper, VariableMapper, and BeanNameResolver.
*
* @since EL 3.0
*/
public class StandardELContext extends ELContext {
/*
* The ELResolver for this ELContext.
*/
private ELResolver elResolver;
/*
* The list of the custom ELResolvers added to the ELResolvers.
* An ELResolver is added to the list when addELResolver is called.
*/
private CompositeELResolver customResolvers;
/*
* The ELResolver implementing the query operators.
*/
private ELResolver streamELResolver;
/*
* The FunctionMapper for this ELContext.
*/
private FunctionMapper functionMapper;
/*
* The pre-confured init function map;
*/
private Map<String, Method> initFunctionMap;
/*
* The VariableMapper for this ELContext.
*/
private VariableMapper variableMapper;
/*
* If non-null, indicates the presence of a delegate ELContext.
* When a Standard is constructed from another ELContext, there is no
* easy way to get its private context map, therefore delegation is needed.
*/
private ELContext delegate = null;
/**
* A bean repository local to this context
*/
private Map<String, Object> beans = new HashMap<String, Object>();
/**
* Construct a default ELContext for a stand-alone environment.
* @param factory The ExpressionFactory
*/
public StandardELContext(ExpressionFactory factory) {
this.streamELResolver = factory.getStreamELResolver();
initFunctionMap = factory.getInitFunctionMap();
}
/**
* Construct a StandardELContext from another ELContext.
* @param context The ELContext that acts as a delegate in most cases
*/
public StandardELContext(ELContext context) {
this.delegate = context;
// Copy all attributes except map and resolved
CompositeELResolver elr = new CompositeELResolver();
elr.add(new BeanNameELResolver(new LocalBeanNameResolver()));
customResolvers = new CompositeELResolver();
elr.add(customResolvers);
elr.add(context.getELResolver());
elResolver = elr;
functionMapper = context.getFunctionMapper();
variableMapper = context.getVariableMapper();
setLocale(context.getLocale());
}
@Override
public void putContext(Class key, Object contextObject) {
if (delegate !=null) {
delegate.putContext(key, contextObject);
} else {
super.putContext(key, contextObject);
}
}
@Override
public Object getContext(Class key) {
if (delegate !=null) {
return delegate.getContext(key);
} else {
return super.getContext(key);
}
}
/**
* Construct (if needed) and return a default ELResolver.
* <p>Retrieves the <code>ELResolver</code> associated with this context.
* This is a <code>CompositeELResover</code> consists of an ordered list of
* <code>ELResolver</code>s.
* <ol>
* <li>A {@link BeanNameELResolver} for beans defined locally</li>
* <li>Any custom <code>ELResolver</code>s</li>
* <li>An <code>ELResolver</code> supporting the collection operations</li>
* <li>A {@link StaticFieldELResolver} for resolving static fields</li>
* <li>A {@link MapELResolver} for resolving Map properties</li>
* <li>A {@link ResourceBundleELResolver} for resolving ResourceBundle properties</li>
* <li>A {@link ListELResolver} for resolving List properties</li>
* <li>An {@link ArrayELResolver} for resolving array properties</li>
* <li>A {@link BeanELResolver} for resolving bean properties</li>
* </ol>
* </p>
* @return The ELResolver for this context.
*/
@Override
public ELResolver getELResolver() {
if (elResolver == null) {
CompositeELResolver resolver = new CompositeELResolver();
resolver.add(new BeanNameELResolver(new LocalBeanNameResolver()));
customResolvers = new CompositeELResolver();
resolver.add(customResolvers);
if (streamELResolver != null) {
resolver.add(streamELResolver);
}
resolver.add(new StaticFieldELResolver());
resolver.add(new MapELResolver());
resolver.add(new ResourceBundleELResolver());
resolver.add(new ListELResolver());
resolver.add(new ArrayELResolver());
resolver.add(new BeanELResolver());
elResolver = resolver;
}
return elResolver;
}
/**
* Add a custom ELResolver to the context. The list of the custom
* ELResolvers will be accessed in the order they are added.
* A custom ELResolver added to the context cannot be removed.
* @param cELResolver The new ELResolver to be added to the context
*/
public void addELResolver(ELResolver cELResolver) {
getELResolver(); // make sure elResolver is constructed
customResolvers.add(cELResolver);
}
/**
* Get the local bean repository
* @return the bean repository
*/
Map<String, Object> getBeans() {
return beans;
}
/**
* Construct (if needed) and return a default FunctionMapper.
* @return The default FunctionMapper
*/
@Override
public FunctionMapper getFunctionMapper() {
if (functionMapper == null) {
functionMapper = new DefaultFunctionMapper(initFunctionMap);
}
return functionMapper;
}
/**
* Construct (if needed) and return a default VariableMapper() {
* @return The default Variable
*/
@Override
public VariableMapper getVariableMapper() {
if (variableMapper == null) {
variableMapper = new DefaultVariableMapper();
}
return variableMapper;
}
private static class DefaultFunctionMapper extends FunctionMapper {
private Map<String, Method> functions = null;
DefaultFunctionMapper(Map<String, Method> initMap){
functions = (initMap == null)?
new HashMap<String, Method>():
new HashMap<String, Method>(initMap);
}
@Override
public Method resolveFunction(String prefix, String localName) {
return functions.get(prefix + ":" + localName);
}
@Override
public void mapFunction(String prefix, String localName, Method meth){
functions.put(prefix + ":" + localName, meth);
}
}
private static class DefaultVariableMapper extends VariableMapper {
private Map<String, ValueExpression> variables = null;
@Override
public ValueExpression resolveVariable (String variable) {
if (variables == null) {
return null;
}
return variables.get(variable);
}
@Override
public ValueExpression setVariable(String variable,
ValueExpression expression) {
if (variables == null) {
variables = new HashMap<String, ValueExpression>();
}
ValueExpression prev = null;
if (expression == null) {
prev = variables.remove(variable);
} else {
prev = variables.put(variable, expression);
}
return prev;
}
}
private class LocalBeanNameResolver extends BeanNameResolver {
@Override
public boolean isNameResolved(String beanName) {
return beans.containsKey(beanName);
}
@Override
public Object getBean(String beanName) {
return beans.get(beanName);
}
@Override
public void setBeanValue(String beanName, Object value) {
beans.put(beanName, value);
}
@Override
public boolean isReadOnly(String beanName) {
return false;
}
@Override
public boolean canCreateBean(String beanName) {
return true;
}
}
}