mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 08:24:13 +00:00
Merge branch '7.0.x'
This commit is contained in:
@@ -488,17 +488,23 @@ Kotlin::
|
||||
|
||||
It is possible to configure the SpEL expression parser by using a parser configuration
|
||||
object (`org.springframework.expression.spel.SpelParserConfiguration`). The configuration
|
||||
object controls the behavior of some of the expression components. For example, if you
|
||||
index into a collection and the element at the specified index is `null`, SpEL can
|
||||
automatically create the element. This is useful when using expressions made up of a
|
||||
chain of property references. Similarly, if you index into a collection and specify an
|
||||
index that is greater than the current size of the collection, SpEL can automatically
|
||||
grow the collection to accommodate that index. In order to add an element at the
|
||||
specified index, SpEL will try to create the element using the element type's default
|
||||
constructor before setting the specified value. If the element type does not have a
|
||||
default constructor, `null` will be added to the collection. If there is no built-in
|
||||
converter or custom converter that knows how to set the value, `null` will remain in the
|
||||
collection at the specified index. The following example demonstrates how to
|
||||
object controls the behavior of some of the expression components. To create a
|
||||
`SpelParserConfiguration` instance, favor `SpelParserConfiguration.builder()` over the
|
||||
numerous constructors in `SpelParserConfiguration`, since the builder only requires
|
||||
configuration of the properties that need to deviate from their sensible defaults --
|
||||
or use `SpelParserConfiguration.withDefaults()` if none of those defaults need to be
|
||||
overridden.
|
||||
|
||||
For example, if you index into a collection and the element at the specified index is
|
||||
`null`, SpEL can automatically create the element. This is useful when using expressions
|
||||
made up of a chain of property references. Similarly, if you index into a collection and
|
||||
specify an index that is greater than the current size of the collection, SpEL can
|
||||
automatically grow the collection to accommodate that index. In order to add an element
|
||||
at the specified index, SpEL will try to create the element using the element type's
|
||||
default constructor before setting the specified value. If the element type does not
|
||||
have a default constructor, `null` will be added to the collection. If there is no
|
||||
built-in converter or custom converter that knows how to set the value, `null` will
|
||||
remain in the collection at the specified index. The following example demonstrates how to
|
||||
automatically grow a `List`.
|
||||
|
||||
[tabs]
|
||||
@@ -511,10 +517,10 @@ Java::
|
||||
public List<String> list;
|
||||
}
|
||||
|
||||
// Turn on:
|
||||
// - auto null reference initialization
|
||||
// - auto collection growing
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(true, true);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder()
|
||||
.autoGrowNullReferences()
|
||||
.autoGrowCollections()
|
||||
.build();
|
||||
|
||||
ExpressionParser parser = new SpelExpressionParser(config);
|
||||
|
||||
@@ -536,10 +542,10 @@ Kotlin::
|
||||
var list: List<String>? = null
|
||||
}
|
||||
|
||||
// Turn on:
|
||||
// - auto null reference initialization
|
||||
// - auto collection growing
|
||||
val config = SpelParserConfiguration(true, true)
|
||||
val config = SpelParserConfiguration.builder()
|
||||
.autoGrowNullReferences()
|
||||
.autoGrowCollections()
|
||||
.build()
|
||||
|
||||
val parser = SpelExpressionParser(config)
|
||||
|
||||
@@ -564,7 +570,8 @@ create a `SpelExpressionParser` programmatically, you can specify a custom
|
||||
|
||||
By default, a SpEL expression cannot contain more than 10,000 characters; however, the
|
||||
`maxExpressionLength` is configurable. If you create a `SpelExpressionParser`
|
||||
programmatically, you can specify a custom `maxExpressionLength` when creating the
|
||||
programmatically, you can specify a custom `maxExpressionLength` via
|
||||
`SpelParserConfiguration.builder().maximumExpressionLength(...)` when creating the
|
||||
`SpelParserConfiguration` that you provide to the `SpelExpressionParser`. If you wish to
|
||||
set the `maxExpressionLength` used for parsing SpEL expressions within an
|
||||
`ApplicationContext` -- for example, in XML bean definitions, `@Value`, etc. -- you can
|
||||
@@ -575,12 +582,14 @@ xref:appendix.adoc#appendix-spring-properties[Supported Spring Properties]).
|
||||
Similarly, the number of operations performed during the evaluation of a SpEL expression
|
||||
cannot exceed 10,000 by default; however, the `maxOperations` value is configurable. If
|
||||
you create a `SpelExpressionParser` programmatically (the recommend approach), you can
|
||||
specify a custom `maxOperations` value when creating the `SpelParserConfiguration` that
|
||||
you provide to the `SpelExpressionParser`. If you are not able to configure an explicit
|
||||
value for `maxOperations` via `SpelParserConfiguration`, you can set a JVM system
|
||||
property or Spring property named `spring.expression.maxOperations` to the maximum number
|
||||
of operations required by your application (see
|
||||
xref:appendix.adoc#appendix-spring-properties[Supported Spring Properties]).
|
||||
specify a custom `maxOperations` value via
|
||||
`SpelParserConfiguration.builder().maximumOperations(...)` when creating the
|
||||
`SpelParserConfiguration` that you provide to the `SpelExpressionParser`. If you are not
|
||||
able to configure an explicit value for `maxOperations` via `SpelParserConfiguration`,
|
||||
you can set a JVM system property or Spring property named
|
||||
`spring.expression.maxOperations` to the maximum number of operations required by your
|
||||
application (see xref:appendix.adoc#appendix-spring-properties[Supported Spring
|
||||
Properties]).
|
||||
|
||||
In addition, the result of a `BigDecimal` or `BigInteger` power operation within a SpEL
|
||||
expression cannot exceed 1,000,000 bits by default – approximately equivalent to a
|
||||
@@ -588,19 +597,21 @@ decimal number with 300,000 digits. Power operations involving large base values
|
||||
exponents can be computationally expensive, and this limit ensures that evaluations
|
||||
remain bounded; however, the `maximumBigPowerBits` value is configurable. If you create a
|
||||
`SpelExpressionParser` programmatically (the recommended approach), you can specify a
|
||||
custom `maximumBigPowerBits` value when creating the `SpelParserConfiguration` that you
|
||||
provide to the `SpelExpressionParser`. To remove this limit entirely, pass
|
||||
`Integer.MAX_VALUE` as the `maximumBigPowerBits` value. If you are not able to configure
|
||||
an explicit value for `maximumBigPowerBits` via `SpelParserConfiguration`, you can set a
|
||||
JVM system property or Spring property named `spring.expression.maxBigPowerBits` to the
|
||||
maximum result size in bits (see xref:appendix.adoc#appendix-spring-properties[Supported
|
||||
Spring Properties]).
|
||||
custom `maximumBigPowerBits` value via
|
||||
`SpelParserConfiguration.builder().maximumBigPowerBits(...)` when creating the
|
||||
`SpelParserConfiguration` that you provide to the `SpelExpressionParser`. To remove this
|
||||
limit entirely, pass `Integer.MAX_VALUE` as the `maximumBigPowerBits` value. If you are
|
||||
not able to configure an explicit value for `maximumBigPowerBits` via
|
||||
`SpelParserConfiguration`, you can set a JVM system property or Spring property named
|
||||
`spring.expression.maxBigPowerBits` to the maximum result size in bits (see
|
||||
xref:appendix.adoc#appendix-spring-properties[Supported Spring Properties]).
|
||||
|
||||
Likewise, the structural nesting depth of a SpEL expression -- for example, the depth of
|
||||
nested inline lists or maps, parenthesized expressions, ternary or Elvis expressions, or
|
||||
chained unary operators -- cannot exceed 1,000 by default; however, the
|
||||
`maximumNestingDepth` value is configurable. If you create a `SpelExpressionParser`
|
||||
programmatically, you can specify a custom `maximumNestingDepth` value when creating the
|
||||
programmatically, you can specify a custom `maximumNestingDepth` value via
|
||||
`SpelParserConfiguration.builder().maximumNestingDepth(...)` when creating the
|
||||
`SpelParserConfiguration` that you provide to the `SpelExpressionParser`. Unlike
|
||||
`maxExpressionLength` and `maxOperations`, there is currently no JVM system property or
|
||||
Spring property available for configuring `maximumNestingDepth` globally.
|
||||
@@ -702,8 +713,10 @@ Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
|
||||
this.getClass().getClassLoader());
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.IMMEDIATE)
|
||||
.compilerClassLoader(getClass().getClassLoader())
|
||||
.build();
|
||||
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
|
||||
@@ -718,8 +731,10 @@ Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
val config = SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
|
||||
this.javaClass.classLoader)
|
||||
val config = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.IMMEDIATE)
|
||||
.compilerClassLoader(javaClass.classLoader)
|
||||
.build()
|
||||
|
||||
val parser = SpelExpressionParser(config)
|
||||
|
||||
|
||||
+4
-2
@@ -118,8 +118,10 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
* @param beanClassLoader the factory's bean class loader
|
||||
*/
|
||||
public StandardBeanExpressionResolver(@Nullable ClassLoader beanClassLoader) {
|
||||
SpelParserConfiguration parserConfig = new SpelParserConfiguration(
|
||||
null, beanClassLoader, false, false, Integer.MAX_VALUE, retrieveMaxExpressionLength());
|
||||
SpelParserConfiguration parserConfig = SpelParserConfiguration.builder()
|
||||
.compilerClassLoader(beanClassLoader)
|
||||
.maximumExpressionLength(retrieveMaxExpressionLength())
|
||||
.build();
|
||||
this.expressionParser = new SpelExpressionParser(parserConfig);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ public class ExpressionState {
|
||||
|
||||
|
||||
public ExpressionState(EvaluationContext context) {
|
||||
this(context, context.getRootObject(), new SpelParserConfiguration(false, false));
|
||||
this(context, context.getRootObject(), SpelParserConfiguration.withDefaults());
|
||||
}
|
||||
|
||||
public ExpressionState(EvaluationContext context, SpelParserConfiguration configuration) {
|
||||
@@ -83,7 +83,7 @@ public class ExpressionState {
|
||||
}
|
||||
|
||||
public ExpressionState(EvaluationContext context, TypedValue rootObject) {
|
||||
this(context, rootObject, new SpelParserConfiguration(false, false));
|
||||
this(context, rootObject, SpelParserConfiguration.withDefaults());
|
||||
}
|
||||
|
||||
public ExpressionState(EvaluationContext context, TypedValue rootObject, SpelParserConfiguration configuration) {
|
||||
|
||||
+242
-44
@@ -27,12 +27,22 @@ import org.springframework.util.StringUtils;
|
||||
/**
|
||||
* Configuration object for the SpEL expression parser.
|
||||
*
|
||||
* <p>Rather than using one of the numerous constructors in this class, it is
|
||||
* strongly recommended that you use the {@linkplain #builder() builder API} to
|
||||
* configure and create a {@code SpelParserConfiguration} instance, since the
|
||||
* builder only requires configuration of the properties that need to deviate from
|
||||
* their sensible defaults — or use {@link #withDefaults()} if none of those
|
||||
* defaults need to be overridden. Note that the constructors in this class are
|
||||
* planned to be deprecated in favor of the builder as of Spring Framework 7.1.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
* @author Andy Clement
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @see org.springframework.expression.spel.standard.SpelExpressionParser#SpelExpressionParser(SpelParserConfiguration)
|
||||
* @see #withDefaults()
|
||||
* @see #builder()
|
||||
*/
|
||||
public class SpelParserConfiguration {
|
||||
|
||||
@@ -95,10 +105,10 @@ public class SpelParserConfiguration {
|
||||
/**
|
||||
* System property to configure the default compiler mode for SpEL expression parsers: {@value}.
|
||||
* <p><strong>NOTE</strong>: Instead of relying on a global default, applications
|
||||
* and frameworks should ideally set an explicit custom value via the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor which provides complete configuration control and the ability
|
||||
* to override global defaults per use case.
|
||||
* and frameworks should ideally set an explicit custom value via
|
||||
* {@link Builder#compilerMode(SpelCompilerMode)}, which provides complete
|
||||
* configuration control and the ability to override global defaults per
|
||||
* use case.
|
||||
* <p>Can also be configured via the {@link SpringProperties} mechanism.
|
||||
*/
|
||||
public static final String SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME = "spring.expression.compiler.mode";
|
||||
@@ -107,10 +117,10 @@ public class SpelParserConfiguration {
|
||||
* System property to configure the default maximum number of operations permitted
|
||||
* during SpEL expression evaluation: {@value}.
|
||||
* <p><strong>NOTE</strong>: Instead of relying on a global default, applications
|
||||
* and frameworks should ideally set an explicit custom value via the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor which provides complete configuration control and the ability
|
||||
* to override global defaults per use case.
|
||||
* and frameworks should ideally set an explicit custom value via
|
||||
* {@link Builder#maximumOperations(int)}, which provides complete
|
||||
* configuration control and the ability to override global defaults per
|
||||
* use case.
|
||||
* <p>Can also be configured via the {@link SpringProperties} mechanism.
|
||||
* @since 6.2.19
|
||||
* @see #DEFAULT_MAX_OPERATIONS
|
||||
@@ -122,10 +132,10 @@ public class SpelParserConfiguration {
|
||||
* result of a {@link java.math.BigDecimal} or {@link java.math.BigInteger} power
|
||||
* operation within a SpEL expression: {@value}.
|
||||
* <p><strong>NOTE</strong>: Instead of relying on a global default, applications
|
||||
* and frameworks should ideally set an explicit custom value via the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor which provides complete configuration control and the ability
|
||||
* to override global defaults per use case.
|
||||
* and frameworks should ideally set an explicit custom value via
|
||||
* {@link Builder#maximumBigPowerBits(int)}, which provides complete
|
||||
* configuration control and the ability to override global defaults per
|
||||
* use case.
|
||||
* <p>Can also be configured via the {@link SpringProperties} mechanism.
|
||||
* @since 7.0.9
|
||||
* @see #DEFAULT_MAX_BIG_POWER_BITS
|
||||
@@ -162,12 +172,35 @@ public class SpelParserConfiguration {
|
||||
private final int maximumNestingDepth;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance with the same defaults
|
||||
* applied by {@link #builder()}.
|
||||
* <p>This is shorthand for {@code SpelParserConfiguration.builder().build()},
|
||||
* for use whenever none of the defaults need to be overridden.
|
||||
* @since 7.0.10
|
||||
* @see #builder()
|
||||
*/
|
||||
public static SpelParserConfiguration withDefaults() {
|
||||
return builder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link Builder} for configuring a {@code SpelParserConfiguration}.
|
||||
* <p>The builder only requires configuration of the properties that need
|
||||
* to deviate from their sensible defaults. See {@link Builder} for details
|
||||
* on those defaults.
|
||||
* @since 7.0.10
|
||||
* @see #withDefaults()
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance with default settings.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @see #SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
@@ -179,10 +212,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param compilerMode the compiler mode that parsers using this configuration
|
||||
* should use; or {@code null} to use the default mode
|
||||
* @param compilerClassLoader the {@code ClassLoader} to use as the basis for
|
||||
@@ -198,10 +230,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param autoGrowNullReferences if null references should automatically grow
|
||||
* @param autoGrowCollections if collections should automatically grow
|
||||
* @see #SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME
|
||||
@@ -215,10 +246,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param autoGrowNullReferences if null references should automatically grow
|
||||
* @param autoGrowCollections if collections should automatically grow
|
||||
* @param maximumAutoGrowSize the maximum size to which a collection can auto grow;
|
||||
@@ -234,10 +264,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param compilerMode the compiler mode that parsers using this configuration
|
||||
* should use; or {@code null} to use the default mode
|
||||
* @param compilerClassLoader the {@code ClassLoader} to use as the basis for
|
||||
@@ -260,10 +289,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param compilerMode the compiler mode that parsers using this configuration
|
||||
* should use; or {@code null} to use the default mode
|
||||
* @param compilerClassLoader the {@code ClassLoader} to use as the basis for
|
||||
@@ -290,10 +318,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param compilerMode the compiler mode that parsers using this configuration
|
||||
* should use; must not be {@code null}
|
||||
* @param compilerClassLoader the {@code ClassLoader} to use as the basis for
|
||||
@@ -321,10 +348,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor the
|
||||
* {@link #SpelParserConfiguration(SpelCompilerMode, ClassLoader, boolean, boolean, int, int, int, int, int)}
|
||||
* constructor for complete configuration control and the ability to override
|
||||
* global defaults per use case.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param compilerMode the compiler mode that parsers using this configuration
|
||||
* should use; must not be {@code null}
|
||||
* @param compilerClassLoader the {@code ClassLoader} to use as the basis for
|
||||
@@ -354,6 +380,9 @@ public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* <p><strong>NOTE</strong>: Favor {@link #builder()} for complete
|
||||
* configuration control and the ability to override global defaults
|
||||
* per use case.
|
||||
* @param compilerMode the compiler mode that parsers using this configuration
|
||||
* should use; must not be {@code null}
|
||||
* @param compilerClassLoader the {@code ClassLoader} to use as the basis for
|
||||
@@ -504,4 +533,173 @@ public class SpelParserConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fluent builder API for {@link SpelParserConfiguration}.
|
||||
* <p>Each property defaults to the same value as the corresponding
|
||||
* property in a {@code SpelParserConfiguration} created via the
|
||||
* {@linkplain SpelParserConfiguration#SpelParserConfiguration() no-arg constructor}
|
||||
* — including honoring the system properties or Spring properties named
|
||||
* {@value #SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME},
|
||||
* {@value #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME}, and
|
||||
* {@value #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME}.
|
||||
* <p>Only configure the properties that need to deviate from those defaults.
|
||||
* @since 7.0.10
|
||||
* @see SpelParserConfiguration#builder()
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
private SpelCompilerMode compilerMode = defaultCompilerMode;
|
||||
|
||||
private @Nullable ClassLoader compilerClassLoader;
|
||||
|
||||
private boolean autoGrowNullReferences = false;
|
||||
|
||||
private boolean autoGrowCollections = false;
|
||||
|
||||
private int maximumAutoGrowSize = DEFAULT_MAX_AUTO_GROW_SIZE;
|
||||
|
||||
private int maximumExpressionLength = DEFAULT_MAX_EXPRESSION_LENGTH;
|
||||
|
||||
private @Nullable Integer maximumOperations;
|
||||
|
||||
private @Nullable Integer maximumBigPowerBits;
|
||||
|
||||
private int maximumNestingDepth = DEFAULT_MAX_EXPRESSION_NESTING_DEPTH;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compiler mode that parsers using this configuration should use.
|
||||
* <p>By default, set to the value configured via {@link SpringProperties}
|
||||
* for a system property or Spring property named
|
||||
* {@value #SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME}, or
|
||||
* {@link SpelCompilerMode#OFF} if that property is not set.
|
||||
* @param compilerMode the compiler mode to use; must not be {@code null}
|
||||
*/
|
||||
public Builder compilerMode(SpelCompilerMode compilerMode) {
|
||||
Assert.notNull(compilerMode, "'compilerMode' must not be null");
|
||||
this.compilerMode = compilerMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code ClassLoader} to use as the basis for expression compilation.
|
||||
* <p>By default, set to {@code null}, indicating that the default
|
||||
* {@code ClassLoader} should be used.
|
||||
* @param compilerClassLoader the {@code ClassLoader} to use
|
||||
*/
|
||||
public Builder compilerClassLoader(@Nullable ClassLoader compilerClassLoader) {
|
||||
this.compilerClassLoader = compilerClassLoader;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable automatic growth of {@code null} references encountered while
|
||||
* traversing a property path.
|
||||
* <p>By default, this is disabled.
|
||||
*/
|
||||
public Builder autoGrowNullReferences() {
|
||||
this.autoGrowNullReferences = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable automatic growth of collections and arrays encountered while
|
||||
* traversing a property path.
|
||||
* <p>By default, this is disabled.
|
||||
* @see #maximumAutoGrowSize(int)
|
||||
*/
|
||||
public Builder autoGrowCollections() {
|
||||
this.autoGrowCollections = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum size to which a collection or array can automatically grow.
|
||||
* <p>By default, set to {@link #DEFAULT_MAX_AUTO_GROW_SIZE}.
|
||||
* @param maximumAutoGrowSize the maximum auto-grow size; must not be
|
||||
* negative, and a value of {@code 0} effectively disables growing a
|
||||
* collection or array beyond its current size
|
||||
* @see #autoGrowCollections()
|
||||
*/
|
||||
public Builder maximumAutoGrowSize(int maximumAutoGrowSize) {
|
||||
Assert.isTrue(maximumAutoGrowSize >= 0, "'maximumAutoGrowSize' must not be negative");
|
||||
this.maximumAutoGrowSize = maximumAutoGrowSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum length permitted for a SpEL expression.
|
||||
* <p>By default, set to {@link #DEFAULT_MAX_EXPRESSION_LENGTH}.
|
||||
* @param maximumExpressionLength the maximum expression length; must be
|
||||
* a positive number
|
||||
*/
|
||||
public Builder maximumExpressionLength(int maximumExpressionLength) {
|
||||
Assert.isTrue(maximumExpressionLength > 0, "'maximumExpressionLength' must be a positive number");
|
||||
this.maximumExpressionLength = maximumExpressionLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of operations permitted during SpEL expression evaluation.
|
||||
* <p>By default, set to the value configured via {@link SpringProperties}
|
||||
* for a system property or Spring property named
|
||||
* {@value #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME}, or
|
||||
* {@link #DEFAULT_MAX_OPERATIONS} if that property is not set.
|
||||
* @param maximumOperations the maximum number of operations; must be a
|
||||
* positive number
|
||||
*/
|
||||
public Builder maximumOperations(int maximumOperations) {
|
||||
Assert.isTrue(maximumOperations > 0, "'maximumOperations' must be a positive number");
|
||||
this.maximumOperations = maximumOperations;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of bits permitted in the result of a
|
||||
* {@link java.math.BigDecimal} or {@link java.math.BigInteger} power
|
||||
* operation within a SpEL expression.
|
||||
* <p>By default, set to the value configured via {@link SpringProperties}
|
||||
* for a system property or Spring property named
|
||||
* {@value #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME}, or
|
||||
* {@link #DEFAULT_MAX_BIG_POWER_BITS} if that property is not set.
|
||||
* @param maximumBigPowerBits the maximum number of bits; must be a
|
||||
* positive number; use {@link Integer#MAX_VALUE} for no limit
|
||||
*/
|
||||
public Builder maximumBigPowerBits(int maximumBigPowerBits) {
|
||||
Assert.isTrue(maximumBigPowerBits > 0, "'maximumBigPowerBits' must be a positive number");
|
||||
this.maximumBigPowerBits = maximumBigPowerBits;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum nesting depth permitted within a SpEL expression.
|
||||
* <p>By default, set to {@link #DEFAULT_MAX_EXPRESSION_NESTING_DEPTH}.
|
||||
* @param maximumNestingDepth the maximum nesting depth; must be a
|
||||
* positive number
|
||||
* @since 7.1
|
||||
*/
|
||||
public Builder maximumNestingDepth(int maximumNestingDepth) {
|
||||
Assert.isTrue(maximumNestingDepth > 0, "'maximumNestingDepth' must be a positive number");
|
||||
this.maximumNestingDepth = maximumNestingDepth;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the {@link SpelParserConfiguration} configured via this builder.
|
||||
*/
|
||||
public SpelParserConfiguration build() {
|
||||
int maximumOperations = (this.maximumOperations != null ?
|
||||
this.maximumOperations : retrieveMaxOperations());
|
||||
int maximumBigPowerBits = (this.maximumBigPowerBits != null ?
|
||||
this.maximumBigPowerBits : retrieveMaxBigPowerBits());
|
||||
return new SpelParserConfiguration(this.compilerMode, this.compilerClassLoader,
|
||||
this.autoGrowNullReferences, this.autoGrowCollections, this.maximumAutoGrowSize,
|
||||
this.maximumExpressionLength, maximumOperations, maximumBigPowerBits, this.maximumNestingDepth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class SpelExpressionParser extends TemplateAwareExpressionParser {
|
||||
* Create a parser with default settings.
|
||||
*/
|
||||
public SpelExpressionParser() {
|
||||
this.configuration = new SpelParserConfiguration();
|
||||
this.configuration = SpelParserConfiguration.withDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+66
-30
@@ -86,8 +86,9 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
String expression = "'%s'".formatted("Y".repeat(19_998));
|
||||
assertThat(expression).hasSize(maximumExpressionLength);
|
||||
|
||||
SpelParserConfiguration configuration =
|
||||
new SpelParserConfiguration(null, null, false, false, 0, maximumExpressionLength);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.maximumExpressionLength(maximumExpressionLength)
|
||||
.build();
|
||||
ExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
|
||||
Expression expr = parser.parseExpression(expression);
|
||||
@@ -111,8 +112,11 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
Expression expr1 = parser.parseExpression(expression);
|
||||
assertThat(expr1.getValue(Boolean.class)).isTrue();
|
||||
|
||||
SpelParserConfiguration configuration =
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, maxLength, maxOperations);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.OFF)
|
||||
.maximumExpressionLength(maxLength)
|
||||
.maximumOperations(maxOperations)
|
||||
.build();
|
||||
parser = new SpelExpressionParser(configuration);
|
||||
Expression expr2 = parser.parseExpression(expression);
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
@@ -167,13 +171,20 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
SpringProperties.setProperty(SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME, "" + maxOperations / 2);
|
||||
|
||||
// maxOperations + 1 should override maxOperations / 2
|
||||
SpelParserConfiguration configuration =
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, maxLength, maxOperations + 1);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.OFF)
|
||||
.maximumExpressionLength(maxLength)
|
||||
.maximumOperations(maxOperations + 1)
|
||||
.build();
|
||||
parser = new SpelExpressionParser(configuration);
|
||||
expr1 = parser.parseExpression(expression);
|
||||
assertThat(expr1.getValue(Boolean.class)).isTrue();
|
||||
|
||||
configuration = new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, maxLength, maxOperations);
|
||||
configuration = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.OFF)
|
||||
.maximumExpressionLength(maxLength)
|
||||
.maximumOperations(maxOperations)
|
||||
.build();
|
||||
parser = new SpelExpressionParser(configuration);
|
||||
Expression expr2 = parser.parseExpression(expression);
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
@@ -191,7 +202,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void createListsOnAttemptToIndexNull01() throws EvaluationException, ParseException {
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e = parser.parseExpression("list[0]");
|
||||
TestClass testClass = new TestClass();
|
||||
|
||||
@@ -213,7 +225,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void createMapsOnAttemptToIndexNull() {
|
||||
TestClass testClass = new TestClass();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(testClass);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
|
||||
Object o = parser.parseExpression("map['a']").getValue(ctx);
|
||||
assertThat(o).isNull();
|
||||
@@ -230,7 +243,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void createObjectsOnAttemptToReferenceNull() {
|
||||
TestClass testClass = new TestClass();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(testClass);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
|
||||
Object o = parser.parseExpression("wibble.bar").getValue(ctx);
|
||||
assertThat(o).isEqualTo("hello");
|
||||
@@ -385,7 +399,7 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void initializingCollectionElementsOnWrite() {
|
||||
TestPerson person = new TestPerson();
|
||||
EvaluationContext context = new StandardEvaluationContext(person);
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(true, true);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build();
|
||||
ExpressionParser parser = new SpelExpressionParser(config);
|
||||
Expression e = parser.parseExpression("name");
|
||||
e.setValue(context, "Oleg");
|
||||
@@ -452,7 +466,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
|
||||
// Add a new element to the list
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(instance);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e = parser.parseExpression("listOfStrings[++index3]='def'");
|
||||
e.getValue(ctx);
|
||||
assertThat(instance.listOfStrings).hasSize(2);
|
||||
@@ -460,7 +475,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
|
||||
// Check reference beyond end of collection
|
||||
ctx = new StandardEvaluationContext(instance);
|
||||
parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
e = parser.parseExpression("listOfStrings[0]");
|
||||
String value = e.getValue(ctx, String.class);
|
||||
assertThat(value).isEqualTo("abc");
|
||||
@@ -473,7 +489,7 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
|
||||
// Now turn off growing and reference off the end
|
||||
StandardEvaluationContext failCtx = new StandardEvaluationContext(instance);
|
||||
parser = new SpelExpressionParser(new SpelParserConfiguration(false, false));
|
||||
parser = new SpelExpressionParser(SpelParserConfiguration.withDefaults());
|
||||
Expression failExp = parser.parseExpression("listOfStrings[3]");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
.isThrownBy(() -> failExp.getValue(failCtx, String.class))
|
||||
@@ -484,7 +500,12 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void limitCollectionGrowing() {
|
||||
TestClass instance = new TestClass();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(instance);
|
||||
SpelExpressionParser parser = new SpelExpressionParser( new SpelParserConfiguration(true, true, 3));
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder()
|
||||
.autoGrowNullReferences()
|
||||
.autoGrowCollections()
|
||||
.maximumAutoGrowSize(3)
|
||||
.build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
Expression e = parser.parseExpression("foo[2]");
|
||||
e.setValue(ctx, "2");
|
||||
assertThat(instance.getFoo()).hasSize(3);
|
||||
@@ -819,9 +840,12 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
// Use a small limit (16 bits) to verify behavior in tests.
|
||||
private static final int TEST_MAX_RESULT_BITS = 16;
|
||||
|
||||
private final SpelExpressionParser limitedParser = new SpelExpressionParser(
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false,
|
||||
0, 10, 10, TEST_MAX_RESULT_BITS));
|
||||
private final SpelExpressionParser limitedParser = new SpelExpressionParser(SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.OFF)
|
||||
.maximumExpressionLength(10)
|
||||
.maximumOperations(10)
|
||||
.maximumBigPowerBits(TEST_MAX_RESULT_BITS)
|
||||
.build());
|
||||
|
||||
|
||||
@Test
|
||||
@@ -1016,7 +1040,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void increment01root() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e = parser.parseExpression("#this++");
|
||||
assertThat(i).isEqualTo(42);
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
@@ -1028,7 +1053,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void increment02postfix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e;
|
||||
|
||||
// BigDecimal
|
||||
@@ -1081,7 +1107,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void increment02prefix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e;
|
||||
|
||||
// BigDecimal
|
||||
@@ -1134,7 +1161,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void increment03() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
|
||||
Expression e1 = parser.parseExpression("m()++");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
@@ -1151,7 +1179,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void increment04() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e1 = parser.parseExpression("++1");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
.isThrownBy(() -> e1.getValue(ctx, double.class))
|
||||
@@ -1166,7 +1195,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void decrement01root() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e = parser.parseExpression("#this--");
|
||||
assertThat(i).isEqualTo(42);
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
@@ -1178,7 +1208,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void decrement02postfix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e;
|
||||
|
||||
// BigDecimal
|
||||
@@ -1231,7 +1262,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void decrement02prefix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e;
|
||||
|
||||
// BigDecimal
|
||||
@@ -1284,7 +1316,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void decrement03() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
|
||||
Expression e1 = parser.parseExpression("m()--");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
@@ -1301,7 +1334,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void decrement04() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e1 = parser.parseExpression("--1");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
.isThrownBy(() -> e1.getValue(ctx, Integer.class))
|
||||
@@ -1317,7 +1351,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void incrementAndDecrementTogether() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e;
|
||||
|
||||
// index1 is 2 at the start - the 'intArray[#root.index1++]' should not be evaluated twice!
|
||||
@@ -1345,7 +1380,8 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void incrementAllNodeTypes() throws SecurityException, NoSuchMethodException {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
ExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression e;
|
||||
|
||||
// BooleanLiteral
|
||||
|
||||
+14
-7
@@ -161,7 +161,8 @@ class IndexingTests {
|
||||
|
||||
@Test
|
||||
void setPropertyContainingMapAutoGrow() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, false));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().build());
|
||||
Expression expression = parser.parseExpression("parameterizedMap");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("java.util.Map<java.lang.Integer, java.lang.Integer>");
|
||||
@@ -206,7 +207,8 @@ class IndexingTests {
|
||||
void setGenericPropertyContainingListAutogrow() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.ArrayList<?>", FieldAnnotation.class.getCanonicalName());
|
||||
@@ -221,7 +223,8 @@ class IndexingTests {
|
||||
@Test
|
||||
void autoGrowListOfElementsWithoutDefaultConstructor() {
|
||||
this.decimals = new ArrayList<>();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
parser.parseExpression("decimals[0]").setValue(this, "123.4");
|
||||
assertThat(decimals).containsExactly(BigDecimal.valueOf(123.4));
|
||||
}
|
||||
@@ -231,7 +234,8 @@ class IndexingTests {
|
||||
this.decimals = new ArrayList<>();
|
||||
this.decimals.add(null);
|
||||
this.decimals.add(BigDecimal.ONE);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
parser.parseExpression("decimals[0]").setValue(this, "9876.5");
|
||||
assertThat(decimals).containsExactly(BigDecimal.valueOf(9876.5), BigDecimal.ONE);
|
||||
}
|
||||
@@ -282,7 +286,8 @@ class IndexingTests {
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingNullList() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelParserConfiguration configuration =
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
@@ -299,7 +304,8 @@ class IndexingTests {
|
||||
void indexIntoGenericPropertyContainingGrowingList() {
|
||||
List<String> property = new ArrayList<>();
|
||||
this.property = property;
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelParserConfiguration configuration =
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
@@ -316,7 +322,8 @@ class IndexingTests {
|
||||
void indexIntoGenericPropertyContainingGrowingList2() {
|
||||
List<String> property2 = new ArrayList<>();
|
||||
this.property2 = property2;
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelParserConfiguration configuration =
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property2");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString().isEqualTo("java.util.ArrayList<?>");
|
||||
|
||||
+25
-15
@@ -260,8 +260,10 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void failsWhenSettingContextForExpression_SPR12326() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, getClass().getClassLoader()));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.OFF)
|
||||
.compilerClassLoader(getClass().getClassLoader())
|
||||
.build());
|
||||
Person3 person = new Person3("foo", 1);
|
||||
SpelExpression expression = parser.parseRaw("#it?.age?.equals([0])");
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] {1});
|
||||
@@ -1237,8 +1239,10 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void opNe_SPR14863() {
|
||||
SpelParserConfiguration configuration =
|
||||
new SpelParserConfiguration(SpelCompilerMode.MIXED, ClassLoader.getSystemClassLoader());
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.MIXED)
|
||||
.compilerClassLoader(ClassLoader.getSystemClassLoader())
|
||||
.build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("data['my-key'] != 'my-value'");
|
||||
|
||||
@@ -1312,7 +1316,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void nullComparison_SPR22358() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.OFF, null);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.OFF).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
ctx.setRootObject(new Reg(1));
|
||||
@@ -3465,8 +3469,10 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void compilationOfBasicNullSafeMethodReference() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, getClass().getClassLoader()));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.OFF)
|
||||
.compilerClassLoader(getClass().getClassLoader())
|
||||
.build());
|
||||
SpelExpression expression = parser.parseRaw("#it?.equals(3)");
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(new Object[] {1});
|
||||
context.setVariable("it", 3);
|
||||
@@ -4137,8 +4143,10 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
assertThat(expression.getValue(context, Boolean.class)).isTrue();
|
||||
|
||||
// Variant of above more like what was in the bug report:
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, getClass().getClassLoader()));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.IMMEDIATE)
|
||||
.compilerClassLoader(getClass().getClassLoader())
|
||||
.build());
|
||||
|
||||
SpelExpression ex = parser.parseRaw("#it?.age.equals([0])");
|
||||
context = new StandardEvaluationContext(new Object[] {person.getAge()});
|
||||
@@ -5273,8 +5281,10 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void indexIntoMap_SPR12045() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(
|
||||
SpelCompilerMode.IMMEDIATE,getClass().getClassLoader());
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.IMMEDIATE)
|
||||
.compilerClassLoader(getClass().getClassLoader())
|
||||
.build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
expression = parser.parseExpression("headers[command]");
|
||||
|
||||
@@ -6074,7 +6084,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void ternaryWithMapAccess() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
|
||||
expression = parser.parseExpression(
|
||||
@@ -6111,7 +6121,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test // gh-19758
|
||||
void ternaryMiscellaneous() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
Expression exp;
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("map", Map.of("foo", "qux"));
|
||||
@@ -6230,7 +6240,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test // gh-19758
|
||||
void elvisMiscellaneous() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
Expression exp;
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar()");
|
||||
@@ -6314,7 +6324,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void elvis_SPR17214() {
|
||||
SpelParserConfiguration spc = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration spc = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser sep = new SpelExpressionParser(spc);
|
||||
|
||||
RecordHolder rh = null;
|
||||
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.expression.spel;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpelParserConfiguration}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 7.0.10
|
||||
*/
|
||||
class SpelParserConfigurationTests {
|
||||
|
||||
@Test
|
||||
void builderAppliesSameDefaultsAsNoArgConstructor() {
|
||||
SpelParserConfiguration expected = new SpelParserConfiguration();
|
||||
SpelParserConfiguration actual = SpelParserConfiguration.builder().build();
|
||||
|
||||
assertThat(actual.getCompilerMode()).isEqualTo(expected.getCompilerMode());
|
||||
assertThat(actual.getCompilerClassLoader()).isEqualTo(expected.getCompilerClassLoader());
|
||||
assertThat(actual.isAutoGrowNullReferences()).isEqualTo(expected.isAutoGrowNullReferences());
|
||||
assertThat(actual.isAutoGrowCollections()).isEqualTo(expected.isAutoGrowCollections());
|
||||
assertThat(actual.getMaximumAutoGrowSize()).isEqualTo(expected.getMaximumAutoGrowSize());
|
||||
assertThat(actual.getMaximumExpressionLength()).isEqualTo(expected.getMaximumExpressionLength());
|
||||
assertThat(actual.getMaximumOperations()).isEqualTo(expected.getMaximumOperations());
|
||||
assertThat(actual.getMaximumBigPowerBits()).isEqualTo(expected.getMaximumBigPowerBits());
|
||||
assertThat(actual.getMaximumNestingDepth()).isEqualTo(expected.getMaximumNestingDepth());
|
||||
}
|
||||
|
||||
@Test
|
||||
void withDefaultsMatchesBuilderDefaults() {
|
||||
SpelParserConfiguration expected = SpelParserConfiguration.builder().build();
|
||||
SpelParserConfiguration actual = SpelParserConfiguration.withDefaults();
|
||||
|
||||
assertThat(actual.getCompilerMode()).isEqualTo(expected.getCompilerMode());
|
||||
assertThat(actual.getCompilerClassLoader()).isEqualTo(expected.getCompilerClassLoader());
|
||||
assertThat(actual.isAutoGrowNullReferences()).isEqualTo(expected.isAutoGrowNullReferences());
|
||||
assertThat(actual.isAutoGrowCollections()).isEqualTo(expected.isAutoGrowCollections());
|
||||
assertThat(actual.getMaximumAutoGrowSize()).isEqualTo(expected.getMaximumAutoGrowSize());
|
||||
assertThat(actual.getMaximumExpressionLength()).isEqualTo(expected.getMaximumExpressionLength());
|
||||
assertThat(actual.getMaximumOperations()).isEqualTo(expected.getMaximumOperations());
|
||||
assertThat(actual.getMaximumBigPowerBits()).isEqualTo(expected.getMaximumBigPowerBits());
|
||||
assertThat(actual.getMaximumNestingDepth()).isEqualTo(expected.getMaximumNestingDepth());
|
||||
}
|
||||
|
||||
@Test
|
||||
void builderAppliesCustomValues() {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.IMMEDIATE)
|
||||
.compilerClassLoader(classLoader)
|
||||
.autoGrowNullReferences()
|
||||
.autoGrowCollections()
|
||||
.maximumAutoGrowSize(99)
|
||||
.maximumExpressionLength(100)
|
||||
.maximumOperations(101)
|
||||
.maximumBigPowerBits(102)
|
||||
.maximumNestingDepth(103)
|
||||
.build();
|
||||
|
||||
assertThat(configuration.getCompilerMode()).isEqualTo(SpelCompilerMode.IMMEDIATE);
|
||||
assertThat(configuration.getCompilerClassLoader()).isSameAs(classLoader);
|
||||
assertThat(configuration.isAutoGrowNullReferences()).isTrue();
|
||||
assertThat(configuration.isAutoGrowCollections()).isTrue();
|
||||
assertThat(configuration.getMaximumAutoGrowSize()).isEqualTo(99);
|
||||
assertThat(configuration.getMaximumExpressionLength()).isEqualTo(100);
|
||||
assertThat(configuration.getMaximumOperations()).isEqualTo(101);
|
||||
assertThat(configuration.getMaximumBigPowerBits()).isEqualTo(102);
|
||||
assertThat(configuration.getMaximumNestingDepth()).isEqualTo(103);
|
||||
}
|
||||
|
||||
@Test
|
||||
void builderRejectsInvalidValues() {
|
||||
SpelParserConfiguration.Builder builder = SpelParserConfiguration.builder();
|
||||
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> builder.compilerMode(null));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> builder.maximumAutoGrowSize(-1));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> builder.maximumExpressionLength(0));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> builder.maximumOperations(0));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> builder.maximumBigPowerBits(0));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> builder.maximumNestingDepth(0));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Regression tests for the legacy constructors in {@link SpelParserConfiguration}.
|
||||
* <p>Elsewhere in the test suite, we prefer {@link SpelParserConfiguration#builder()}
|
||||
* over these constructors. Thus, this nested class exists so that constructor coverage
|
||||
* remains in one place, which will also keep any future deprecation warnings for
|
||||
* these constructors confined to this class.
|
||||
*/
|
||||
@Nested
|
||||
class LegacyConstructorTests {
|
||||
|
||||
@Test
|
||||
void noArgConstructorAppliesDefaults() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration();
|
||||
|
||||
assertThat(configuration.getCompilerMode()).isEqualTo(SpelCompilerMode.OFF);
|
||||
assertThat(configuration.getCompilerClassLoader()).isNull();
|
||||
assertThat(configuration.isAutoGrowNullReferences()).isFalse();
|
||||
assertThat(configuration.isAutoGrowCollections()).isFalse();
|
||||
assertThat(configuration.getMaximumAutoGrowSize())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_AUTO_GROW_SIZE);
|
||||
assertThat(configuration.getMaximumExpressionLength())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_EXPRESSION_LENGTH);
|
||||
assertThat(configuration.getMaximumOperations())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_OPERATIONS);
|
||||
assertThat(configuration.getMaximumBigPowerBits())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_BIG_POWER_BITS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compilerModeAndClassLoaderConstructor() {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
SpelParserConfiguration configuration =
|
||||
new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, classLoader);
|
||||
|
||||
assertThat(configuration.getCompilerMode()).isEqualTo(SpelCompilerMode.IMMEDIATE);
|
||||
assertThat(configuration.getCompilerClassLoader()).isSameAs(classLoader);
|
||||
assertThat(configuration.isAutoGrowNullReferences()).isFalse();
|
||||
assertThat(configuration.isAutoGrowCollections()).isFalse();
|
||||
assertThat(configuration.getMaximumAutoGrowSize())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_AUTO_GROW_SIZE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoGrowFlagsConstructor() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
|
||||
assertThat(configuration.getCompilerMode()).isEqualTo(SpelCompilerMode.OFF);
|
||||
assertThat(configuration.isAutoGrowNullReferences()).isTrue();
|
||||
assertThat(configuration.isAutoGrowCollections()).isTrue();
|
||||
assertThat(configuration.getMaximumAutoGrowSize())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_AUTO_GROW_SIZE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoGrowFlagsAndMaximumAutoGrowSizeConstructor() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true, 99);
|
||||
|
||||
assertThat(configuration.isAutoGrowNullReferences()).isTrue();
|
||||
assertThat(configuration.isAutoGrowCollections()).isTrue();
|
||||
assertThat(configuration.getMaximumAutoGrowSize()).isEqualTo(99);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fiveArgConstructorAppliesAllValues() {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(
|
||||
SpelCompilerMode.IMMEDIATE, classLoader, true, true, 99);
|
||||
|
||||
assertThat(configuration.getCompilerMode()).isEqualTo(SpelCompilerMode.IMMEDIATE);
|
||||
assertThat(configuration.getCompilerClassLoader()).isSameAs(classLoader);
|
||||
assertThat(configuration.isAutoGrowNullReferences()).isTrue();
|
||||
assertThat(configuration.isAutoGrowCollections()).isTrue();
|
||||
assertThat(configuration.getMaximumAutoGrowSize()).isEqualTo(99);
|
||||
assertThat(configuration.getMaximumExpressionLength())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_EXPRESSION_LENGTH);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sixArgConstructorAppliesMaximumExpressionLength() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(
|
||||
SpelCompilerMode.IMMEDIATE, null, true, true, 99, 100);
|
||||
|
||||
assertThat(configuration.getMaximumExpressionLength()).isEqualTo(100);
|
||||
assertThat(configuration.getMaximumOperations())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_OPERATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sevenArgConstructorAppliesMaximumOperations() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(
|
||||
SpelCompilerMode.IMMEDIATE, null, true, true, 99, 100, 101);
|
||||
|
||||
assertThat(configuration.getMaximumOperations()).isEqualTo(101);
|
||||
assertThat(configuration.getMaximumBigPowerBits())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_BIG_POWER_BITS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void eightArgConstructorAppliesMaximumBigPowerBits() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(
|
||||
SpelCompilerMode.IMMEDIATE, null, true, true, 99, 100, 101, 102);
|
||||
|
||||
assertThat(configuration.getMaximumBigPowerBits()).isEqualTo(102);
|
||||
assertThat(configuration.getMaximumNestingDepth())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_EXPRESSION_NESTING_DEPTH);
|
||||
}
|
||||
|
||||
@Test
|
||||
void canonicalConstructorAppliesAllValues() {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(
|
||||
SpelCompilerMode.IMMEDIATE, classLoader, true, true, 99, 100, 101, 102, 103);
|
||||
|
||||
assertThat(configuration.getCompilerMode()).isEqualTo(SpelCompilerMode.IMMEDIATE);
|
||||
assertThat(configuration.getCompilerClassLoader()).isSameAs(classLoader);
|
||||
assertThat(configuration.isAutoGrowNullReferences()).isTrue();
|
||||
assertThat(configuration.isAutoGrowCollections()).isTrue();
|
||||
assertThat(configuration.getMaximumAutoGrowSize()).isEqualTo(99);
|
||||
assertThat(configuration.getMaximumExpressionLength()).isEqualTo(100);
|
||||
assertThat(configuration.getMaximumOperations()).isEqualTo(101);
|
||||
assertThat(configuration.getMaximumBigPowerBits()).isEqualTo(102);
|
||||
assertThat(configuration.getMaximumNestingDepth()).isEqualTo(103);
|
||||
}
|
||||
|
||||
@Test
|
||||
void canonicalConstructorRejectsInvalidValues() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new SpelParserConfiguration(null, null, false, false, 0, 1, 1, 1, 1));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, -1, 1, 1, 1, 1));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, 0, 1, 1, 1));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, 1, 0, 1, 1));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, 1, 1, 0, 1));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, 1, 1, 1, 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -696,8 +696,8 @@ class SpelReproTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void compiledExpressionForProxy_SPR16191() {
|
||||
SpelExpressionParser expressionParser =
|
||||
new SpelExpressionParser(new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null));
|
||||
SpelExpressionParser expressionParser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build());
|
||||
Expression expression = expressionParser.parseExpression("#target.process(#root)");
|
||||
|
||||
VarargsReceiver receiver = new VarargsReceiver();
|
||||
@@ -1274,7 +1274,7 @@ class SpelReproTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void SPR10452() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(false, false);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.withDefaults();
|
||||
ExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
@@ -1299,7 +1299,7 @@ class SpelReproTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void SPR9495() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(false, false);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.withDefaults();
|
||||
ExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
+8
-8
@@ -46,7 +46,7 @@ class SpelCompilerTests {
|
||||
|
||||
@Test // gh-24357
|
||||
void expressionCompilesWhenMethodComesFromPublicInterface() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
|
||||
OrderedComponent component = new OrderedComponent();
|
||||
@@ -59,7 +59,7 @@ class SpelCompilerTests {
|
||||
|
||||
@Test // gh-25706
|
||||
void defaultMethodInvocation() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
@@ -84,7 +84,7 @@ class SpelCompilerTests {
|
||||
|
||||
@Test
|
||||
void simpleEvaluationContextBlocksCompilationByDefault() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
// "order" resides in the public Ordered interface and is therefore compilable,
|
||||
// so any non-compilation is attributable solely to the context's policy.
|
||||
@@ -102,7 +102,7 @@ class SpelCompilerTests {
|
||||
|
||||
@Test
|
||||
void simpleEvaluationContextAllowsCompilationWhenSupported() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
// "order" resides in the public Ordered interface and is therefore compilable.
|
||||
Expression expression = parser.parseExpression("order");
|
||||
@@ -120,7 +120,7 @@ class SpelCompilerTests {
|
||||
|
||||
@Test
|
||||
void simpleEvaluationContextIgnoresPrecompiledExpressionByDefault() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
// "order" resides in the public Ordered interface and is therefore compilable.
|
||||
Expression expression = parser.parseExpression("order");
|
||||
@@ -155,7 +155,7 @@ class SpelCompilerTests {
|
||||
*/
|
||||
@Test
|
||||
void simpleEvaluationContextSetAsDefaultBlocksCompilationForImplicitContextVariants() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
// "order" resides in the public Ordered interface and is therefore compilable,
|
||||
// so any non-compilation is attributable solely to the context's policy.
|
||||
@@ -193,7 +193,7 @@ class SpelCompilerTests {
|
||||
*/
|
||||
@Test
|
||||
void simpleEvaluationContextSetAsDefaultIgnoresPrecompiledExpressionForImplicitContextVariants() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.IMMEDIATE).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
// "order" resides in the public Ordered interface and is therefore compilable.
|
||||
SpelExpression expression = parser.parseRaw("order");
|
||||
@@ -240,7 +240,7 @@ class SpelCompilerTests {
|
||||
|
||||
@Test // gh-28043
|
||||
void changingRegisteredVariableTypeDoesNotResultInFailureInMixedMode() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.MIXED, null);
|
||||
SpelParserConfiguration config = SpelParserConfiguration.builder().compilerMode(SpelCompilerMode.MIXED).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
Expression sharedExpression = parser.parseExpression("#bean.value");
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
Reference in New Issue
Block a user