jakarta.el.ExpressionFactory Maven / Gradle / Ivy
Show all versions of weld-servlet-shaded Show documentation
/*
* Copyright (c) 1997, 2021 Oracle and/or its affiliates and others.
* All rights reserved.
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jakarta.el;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Properties;
/**
* Provides an implementation for creating and evaluating Jakarta Expression Language expressions.
*
*
* Classes that implement the Jakarta Expression Language expression language expose their functionality via this
* abstract class. An implementation supports the following functionalities.
*
*
* - Parses a
String into a {@link ValueExpression} or {@link MethodExpression} instance for later
* evaluation.
* - Implements an
ELResolver for query operators
* - Provides a default type coercion
*
*
*
* The {@link #newInstance} method can be used to obtain an instance of the implementation. Technologies such as
* Jakarta Server Pages and Jakarta Faces provide access to an implementation via factory methods.
*
*
* The {@link #createValueExpression} method is used to parse expressions that evaluate to values (both l-values and
* r-values are supported). The {@link #createMethodExpression} method is used to parse expressions that evaluate to a
* reference to a method on an object.
*
*
* Resolution of model objects is performed at evaluation time, via the {@link ELResolver} associated with the
* {@link ELContext} passed to the ValueExpression or MethodExpression.
*
*
* The ELContext object also provides access to the {@link FunctionMapper} and {@link VariableMapper} to be used when
* parsing the expression. Jakarta Expression Language function and variable mapping is performed at parse-time, and the
* results are bound to the expression. Therefore, the {@link ELContext}, {@link FunctionMapper}, and
* {@link VariableMapper} are not stored for future use and do not have to be Serializable.
*
*
* The createValueExpression and createMethodExpression methods must be thread-safe. That is,
* multiple threads may call these methods on the same ExpressionFactory object simultaneously.
* Implementations should synchronize access if they depend on transient state. Implementations should not, however,
* assume that only one object of each ExpressionFactory type will be instantiated; global caching should
* therefore be static.
*
*
* The ExpressionFactory must be able to handle the following types of input for the
* expression parameter:
*
* - Single expressions using the
${} delimiter (e.g. "${employee.lastName}").
* - Single expressions using the
#{} delimiter (e.g. "#{employee.lastName}").
* - Literal text containing no
${} or #{} delimiters (e.g. "John Doe").
* - Multiple expressions using the same delimiter (e.g.
"${employee.firstName}${employee.lastName}" or
* "#{employee.firstName}#{employee.lastName}").
* - Mixed literal text and expressions using the same delimiter (e.g.
*
"Name: ${employee.firstName} ${employee.lastName}").
*
*
*
* The following types of input are illegal and must cause an {@link ELException} to be thrown:
*
* - Multiple expressions using different delimiters (e.g.
*
"${employee.firstName}#{employee.lastName}").
* - Mixed literal text and expressions using different delimiters(e.g.
*
"Name: ${employee.firstName} #{employee.lastName}").
*
*
* @since Jakarta Server Pages 2.1
*/
public abstract class ExpressionFactory {
/**
* Creates a new instance of a ExpressionFactory. This method uses the following ordered lookup procedure
* to determine the ExpressionFactory implementation class to load:
*
*
* - Use the Services API (as detailed in the JAR specification).
* - Use the properties file "lib/el.properties" in the JRE directory. If this file exists and it is readable by the
*
java.util.Properties.load(InputStream) method, and it contains an entry whose key is
* "jakarta.el.ExpressionFactory", then the value of that entry is used as the name of the implementation class.
* - Use the
jakarta.el.ExpressionFactory system property. If a system property with this name is defined,
* then its value is used as the name of the implementation class.
* - Use a platform default implementation.
*
*
* @return a new ExpressionFactory instance
*/
public static ExpressionFactory newInstance() {
return ExpressionFactory.newInstance(null);
}
/**
* Create a new instance of a ExpressionFactory, with optional properties.
*
*
* This method uses the same lookup procedure as the one used in newInstance().
*
*
* If the argument properties is not null, and if the implementation contains a constructor with a single
* parameter of type java.util.Properties, then the constructor is used to create the instance.
*
*
* Properties are optional and can be ignored by an implementation.
*
*
* The name of a property should start with "jakarta.el."
*
*
* The following are some suggested names for properties.
*
* - jakarta.el.cacheSize
*
*
* @param properties Properties passed to the implementation. If null, then no properties.
*
* @return a new ExpressionFactory instance
*/
public static ExpressionFactory newInstance(Properties properties) {
return (ExpressionFactory) FactoryFinder.find(ExpressionFactory.class,
"jakarta.el.ExpressionFactory", "com.sun.el.ExpressionFactoryImpl", properties);
}
/**
* Parses an expression into a {@link ValueExpression} for later evaluation. Use this method for expressions that refer
* to values.
*
*
* This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise
* an ELException.
*
* @param context The Jakarta Expression Language context used to parse the expression. The FunctionMapper
* and VariableMapper stored in the ELContext are used to resolve functions and variables found in the
* expression. They can be null, in which case functions or variables are not supported for this
* expression. The object returned must invoke the same functions and access the same variable mappings regardless of
* whether the mappings in the provided FunctionMapper and VariableMapper instances change
* between calling ExpressionFactory.createValueExpression() and any method on
* ValueExpression. Note that within Jakarta Expression Language, the ${} and #{} syntaxes are treated
* identically. This includes the use of VariableMapper and FunctionMapper at expression creation time. Each is invoked
* if not null, independent of whether the #{} or ${} syntax is used for the expression.
* @param expression The expression to parse
* @param expectedType The type the result of the expression will be coerced to after evaluation.
*
* @return The parsed expression
*
* @throws NullPointerException Thrown if expectedType is null.
* @throws ELException Thrown if there are syntactical errors in the provided expression.
*/
public abstract ValueExpression createValueExpression(ELContext context, String expression, Class> expectedType);
/**
* Creates a ValueExpression that wraps an object instance.
*
*
* This method can be used to pass any object as a ValueExpression. The wrapper ValueExpression is read only, and
* returns the wrapped object via its getValue() method, optionally coerced.
*
*
* @param instance The object instance to be wrapped.
* @param expectedType The type the result of the expression will be coerced to after evaluation. There will be no
* coercion if it is Object.class,
* @throws NullPointerException Thrown if expectedType is null.
* @return a ValueExpression that wraps an object instance
*/
public abstract ValueExpression createValueExpression(Object instance, Class> expectedType);
/**
* Parses an expression into a {@link MethodExpression} for later evaluation. Use this method for expressions that refer
* to methods.
*
*
* If the expression is a String literal, a MethodExpression
* is created, which when invoked, returns the String literal, coerced to expectedReturnType. An ELException is
* thrown if expectedReturnType is void or if the coercion of the String literal to the expectedReturnType yields an
* error (see Section "1.16 Type Conversion").
*
*
* This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise
* an ELException.
*
* @param context The Jakarta Expression Language context used to parse the expression. The FunctionMapper
* and VariableMapper stored in the ELContext are used to resolve functions and variables found in the
* expression. They can be null, in which case functions or variables are not supported for this
* expression. The object returned must invoke the same functions and access the same variable mappings regardless of
* whether the mappings in the provided FunctionMapper and VariableMapper instances change
* between calling ExpressionFactory.createMethodExpression() and any method on
* MethodExpression. Note that within the EL, the ${} and #{} syntaxes are treated identically. This
* includes the use of VariableMapper and FunctionMapper at expression creation time. Each is invoked if not null,
* independent of whether the #{} or ${} syntax is used for the expression.
* @param expression The expression to parse
* @param expectedReturnType The expected return type for the method to be found. After evaluating the expression, the
* MethodExpression must check that the return type of the actual method matches this type. Passing in a
* value of null indicates the caller does not care what the return type is, and the check is disabled.
* @param expectedParamTypes The expected parameter types for the method to be found. Must be an array with no elements
* if there are no parameters expected. It is illegal to pass null, unless the method is specified with
* arguments in the Jakarta Expression Language expression, in which case these arguments are used for method selection,
* and this parameter is ignored.
*
* @return The parsed expression
*
* @throws ELException Thrown if there are syntactical errors in the provided expression.
* @throws NullPointerException if paramTypes is null.
*/
public abstract MethodExpression createMethodExpression(ELContext context, String expression, Class> expectedReturnType, Class>[] expectedParamTypes);
/**
* Coerces an object to a specific type according to the Jakarta Expression Language type conversion rules. The custom
* type conversions in the ELResolvers are not considered.
*
*
* An ELException is thrown if an error results from applying the conversion rules.
*
* @param obj The object to coerce.
* @param targetType The target type for the coercion.
*
* @return an object coerced to targetType
*
* @throws ELException thrown if an error results from applying the conversion rules.
*/
public abstract T coerceToType(Object obj, Class targetType);
/**
* Retrieves an ELResolver that implements the operations in collections.
*
*
* This ELResolver resolves the method invocation on the pair (base, property) when
* base is a Collection or a Map, and property is the name of the
* operation.
*
*
* See the specification document for detailed descriptions of these operators, their arguments, and return values.
*
* @return The ELResolver that implements the Query Operators.
*
* @since Jakarta Expression Language 3.0
*/
public ELResolver getStreamELResolver() {
return null;
}
/**
* Retrieve a function map containing a pre-configured function mapping.
*
* @return A initial map for functions, null if there is none.
*
* @since Jakarta Expression Language 3.0
*/
public Map getInitFunctionMap() {
return null;
}
}