Skip to content

Package: ExpressionFactory

ExpressionFactory

nameinstructionbranchcomplexitylinemethod
ExpressionFactory()
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%
getInitFunctionMap()
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%
getStreamELResolver()
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%
newInstance()
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%
newInstance(Properties)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 1997, 2021 Oracle and/or its affiliates and others.
3: * All rights reserved.
4: * Copyright 2004 The Apache Software Foundation
5: *
6: * Licensed under the Apache License, Version 2.0 (the "License");
7: * you may not use this file except in compliance with the License.
8: * You may obtain a copy of the License at
9: *
10: * http://www.apache.org/licenses/LICENSE-2.0
11: *
12: * Unless required by applicable law or agreed to in writing, software
13: * distributed under the License is distributed on an "AS IS" BASIS,
14: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15: * See the License for the specific language governing permissions and
16: * limitations under the License.
17: */
18:
19: package jakarta.el;
20:
21: import java.lang.reflect.Method;
22: import java.util.Map;
23: import java.util.Properties;
24:
25: /**
26: * Provides an implementation for creating and evaluating Jakarta Expression Language expressions.
27: *
28: * <p>
29: * Classes that implement the Jakarta Expression Language expression language expose their functionality via this
30: * abstract class. An implementation supports the following functionalities.
31: *
32: * <ul>
33: * <li>Parses a <code>String</code> into a {@link ValueExpression} or {@link MethodExpression} instance for later
34: * evaluation.</li>
35: * <li>Implements an <code>ELResolver</code> for query operators</li>
36: * <li>Provides a default type coercion</li>
37: * </ul>
38: *
39: * <p>
40: * The {@link #newInstance} method can be used to obtain an instance of the implementation. Technologies such as
41: * Jakarta Server Pages and Jakarta Faces provide access to an implementation via factory methods.
42: *
43: * <p>
44: * The {@link #createValueExpression} method is used to parse expressions that evaluate to values (both l-values and
45: * r-values are supported). The {@link #createMethodExpression} method is used to parse expressions that evaluate to a
46: * reference to a method on an object.
47: *
48: * <p>
49: * Resolution of model objects is performed at evaluation time, via the {@link ELResolver} associated with the
50: * {@link ELContext} passed to the <code>ValueExpression</code> or <code>MethodExpression</code>.
51: *
52: * <p>
53: * The ELContext object also provides access to the {@link FunctionMapper} and {@link VariableMapper} to be used when
54: * parsing the expression. Jakarta Expression Language function and variable mapping is performed at parse-time, and the
55: * results are bound to the expression. Therefore, the {@link ELContext}, {@link FunctionMapper}, and
56: * {@link VariableMapper} are not stored for future use and do not have to be <code>Serializable</code>.
57: *
58: * <p>
59: * The <code>createValueExpression</code> and <code>createMethodExpression</code> methods must be thread-safe. That is,
60: * multiple threads may call these methods on the same <code>ExpressionFactory</code> object simultaneously.
61: * Implementations should synchronize access if they depend on transient state. Implementations should not, however,
62: * assume that only one object of each <code>ExpressionFactory</code> type will be instantiated; global caching should
63: * therefore be static.
64: *
65: * <p>
66: * The <code>ExpressionFactory</code> must be able to handle the following types of input for the
67: * <code>expression</code> parameter:
68: * <ul>
69: * <li>Single expressions using the <code>${}</code> delimiter (e.g. <code>"${employee.lastName}"</code>).</li>
70: * <li>Single expressions using the <code>#{}</code> delimiter (e.g. <code>"#{employee.lastName}"</code>).</li>
71: * <li>Literal text containing no <code>${}</code> or <code>#{}</code> delimiters (e.g. <code>"John Doe"</code>).</li>
72: * <li>Multiple expressions using the same delimiter (e.g. <code>"${employee.firstName}${employee.lastName}"</code> or
73: * <code>"#{employee.firstName}#{employee.lastName}"</code>).</li>
74: * <li>Mixed literal text and expressions using the same delimiter (e.g.
75: * <code>"Name: ${employee.firstName} ${employee.lastName}"</code>).</li>
76: * </ul>
77: *
78: * <p>
79: * The following types of input are illegal and must cause an {@link ELException} to be thrown:
80: * <ul>
81: * <li>Multiple expressions using different delimiters (e.g.
82: * <code>"${employee.firstName}#{employee.lastName}"</code>).</li>
83: * <li>Mixed literal text and expressions using different delimiters(e.g.
84: * <code>"Name: ${employee.firstName} #{employee.lastName}"</code>).</li>
85: * </ul>
86: *
87: * @since Jakarta Server Pages 2.1
88: */
89: public abstract class ExpressionFactory {
90:
91: /**
92: * Creates a new instance of a <code>ExpressionFactory</code>. This method uses the following ordered lookup procedure
93: * to determine the <code>ExpressionFactory</code> implementation class to load:
94: *
95: * <ul>
96: * <li>Use the Services API (as detailed in the JAR specification).</li>
97: * <li>Use the properties file "lib/el.properties" in the JRE directory. If this file exists and it is readable by the
98: * <code> java.util.Properties.load(InputStream)</code> method, and it contains an entry whose key is
99: * "jakarta.el.ExpressionFactory", then the value of that entry is used as the name of the implementation class.</li>
100: * <li>Use the <code>jakarta.el.ExpressionFactory</code> system property. If a system property with this name is defined,
101: * then its value is used as the name of the implementation class.</li>
102: * <li>Use a platform default implementation.</li>
103: * </ul>
104: *
105: * @return a new <code>ExpressionFactory</code> instance
106: */
107: public static ExpressionFactory newInstance() {
108: return ExpressionFactory.newInstance(null);
109: }
110:
111: /**
112: * Create a new instance of a <code>ExpressionFactory</code>, with optional properties.
113: *
114: * <p>
115: * This method uses the same lookup procedure as the one used in <code>newInstance()</code>.
116: *
117: * <p>
118: * If the argument <code>properties</code> is not null, and if the implementation contains a constructor with a single
119: * parameter of type <code>java.util.Properties</code>, then the constructor is used to create the instance.
120: *
121: * <p>
122: * Properties are optional and can be ignored by an implementation.
123: *
124: * <p>
125: * The name of a property should start with "jakarta.el."
126: *
127: * <p>
128: * The following are some suggested names for properties.
129: * <ul>
130: * <li>jakarta.el.cacheSize</li>
131: * </ul>
132: *
133: * @param properties Properties passed to the implementation. If null, then no properties.
134: *
135: * @return a new <code>ExpressionFactory</code> instance
136: */
137: public static ExpressionFactory newInstance(Properties properties) {
138: return (ExpressionFactory) FactoryFinder.find(ExpressionFactory.class,
139: "jakarta.el.ExpressionFactory", "com.sun.el.ExpressionFactoryImpl", properties);
140: }
141:
142: /**
143: * Parses an expression into a {@link ValueExpression} for later evaluation. Use this method for expressions that refer
144: * to values.
145: *
146: * <p>
147: * This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise
148: * an <code>ELException</code>.
149: *
150: * @param context The Jakarta Expression Language context used to parse the expression. The <code>FunctionMapper</code>
151: * and <code>VariableMapper</code> stored in the ELContext are used to resolve functions and variables found in the
152: * expression. They can be <code>null</code>, in which case functions or variables are not supported for this
153: * expression. The object returned must invoke the same functions and access the same variable mappings regardless of
154: * whether the mappings in the provided <code>FunctionMapper</code> and <code>VariableMapper</code> instances change
155: * between calling <code>ExpressionFactory.createValueExpression()</code> and any method on
156: * <code>ValueExpression</code>. Note that within Jakarta Expression Language, the ${} and #{} syntaxes are treated
157: * identically. This includes the use of VariableMapper and FunctionMapper at expression creation time. Each is invoked
158: * if not null, independent of whether the #{} or ${} syntax is used for the expression.
159: * @param expression The expression to parse
160: * @param expectedType The type the result of the expression will be coerced to after evaluation.
161: *
162: * @return The parsed expression
163: *
164: * @throws NullPointerException Thrown if expectedType is null.
165: * @throws ELException Thrown if there are syntactical errors in the provided expression.
166: */
167: public abstract ValueExpression createValueExpression(ELContext context, String expression, Class<?> expectedType);
168:
169: /**
170: * Creates a ValueExpression that wraps an object instance.
171: *
172: * <p>
173: * This method can be used to pass any object as a ValueExpression. The wrapper ValueExpression is read only, and
174: * returns the wrapped object via its <code>getValue()</code> method, optionally coerced.
175: * </p>
176: *
177: * @param instance The object instance to be wrapped.
178: * @param expectedType The type the result of the expression will be coerced to after evaluation. There will be no
179: * coercion if it is Object.class,
180: * @throws NullPointerException Thrown if expectedType is null.
181: * @return a ValueExpression that wraps an object instance
182: */
183: public abstract ValueExpression createValueExpression(Object instance, Class<?> expectedType);
184:
185: /**
186: * Parses an expression into a {@link MethodExpression} for later evaluation. Use this method for expressions that refer
187: * to methods.
188: *
189: * <p>
190: * If the expression is a String literal, a <code>MethodExpression
191: * </code> is created, which when invoked, returns the String literal, coerced to expectedReturnType. An ELException is
192: * thrown if expectedReturnType is void or if the coercion of the String literal to the expectedReturnType yields an
193: * error (see Section "1.16 Type Conversion").
194: *
195: * <p>
196: * This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise
197: * an <code>ELException</code>.
198: *
199: * @param context The Jakarta Expression Language context used to parse the expression. The <code>FunctionMapper</code>
200: * and <code>VariableMapper</code> stored in the ELContext are used to resolve functions and variables found in the
201: * expression. They can be <code>null</code>, in which case functions or variables are not supported for this
202: * expression. The object returned must invoke the same functions and access the same variable mappings regardless of
203: * whether the mappings in the provided <code>FunctionMapper</code> and <code>VariableMapper</code> instances change
204: * between calling <code>ExpressionFactory.createMethodExpression()</code> and any method on
205: * <code>MethodExpression</code>. Note that within the EL, the ${} and #{} syntaxes are treated identically. This
206: * includes the use of VariableMapper and FunctionMapper at expression creation time. Each is invoked if not null,
207: * independent of whether the #{} or ${} syntax is used for the expression.
208: * @param expression The expression to parse
209: * @param expectedReturnType The expected return type for the method to be found. After evaluating the expression, the
210: * <code>MethodExpression</code> must check that the return type of the actual method matches this type. Passing in a
211: * value of <code>null</code> indicates the caller does not care what the return type is, and the check is disabled.
212: * @param expectedParamTypes The expected parameter types for the method to be found. Must be an array with no elements
213: * if there are no parameters expected. It is illegal to pass <code>null</code>, unless the method is specified with
214: * arguments in the Jakarta Expression Language expression, in which case these arguments are used for method selection,
215: * and this parameter is ignored.
216: *
217: * @return The parsed expression
218: *
219: * @throws ELException Thrown if there are syntactical errors in the provided expression.
220: * @throws NullPointerException if paramTypes is <code>null</code>.
221: */
222: public abstract MethodExpression createMethodExpression(ELContext context, String expression, Class<?> expectedReturnType, Class<?>[] expectedParamTypes);
223:
224: /**
225: * Coerces an object to a specific type according to the Jakarta Expression Language type conversion rules. The custom
226: * type conversions in the <code>ELResolver</code>s are not considered.
227: *
228: * <p>
229: * An <code>ELException</code> is thrown if an error results from applying the conversion rules.
230: *
231: * @param obj The object to coerce.
232: * @param targetType The target type for the coercion.
233: *
234: * @return an object coerced to <code>targetType</code>
235: *
236: * @throws ELException thrown if an error results from applying the conversion rules.
237: */
238: public abstract <T> T coerceToType(Object obj, Class<T> targetType);
239:
240: /**
241: * Retrieves an ELResolver that implements the operations in collections.
242: *
243: * <p>
244: * This ELResolver resolves the method invocation on the pair (<code>base</code>, <code>property</code>) when
245: * <code>base</code> is a <code>Collection</code> or a <code>Map</code>, and <code>property</code> is the name of the
246: * operation.
247: *
248: * <p>
249: * See the specification document for detailed descriptions of these operators, their arguments, and return values.
250: *
251: * @return The <code>ELResolver</code> that implements the Query Operators.
252: *
253: * @since Jakarta Expression Language 3.0
254: */
255: public ELResolver getStreamELResolver() {
256: return null;
257: }
258:
259: /**
260: * Retrieve a function map containing a pre-configured function mapping.
261: *
262: * @return A initial map for functions, null if there is none.
263: *
264: * @since Jakarta Expression Language 3.0
265: */
266: public Map<String, Method> getInitFunctionMap() {
267: return null;
268: }
269: }