Skip to content

Commit 626f427

Browse files
committed
Merge branch '6.1.x'
2 parents 382b51a + fb0a108 commit 626f427

File tree

7 files changed

+45
-37
lines changed

7 files changed

+45
-37
lines changed

spring-expression/src/main/java/org/springframework/expression/ExpressionParser.java

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,7 +18,8 @@
1818

1919
/**
2020
* Parses expression strings into compiled expressions that can be evaluated.
21-
* Supports parsing templates as well as standard expression strings.
21+
*
22+
* <p>Supports parsing template expressions as well as standard expression strings.
2223
*
2324
* @author Keith Donald
2425
* @author Andy Clement
@@ -27,29 +28,31 @@
2728
public interface ExpressionParser {
2829

2930
/**
30-
* Parse the expression string and return an Expression object you can use for repeated evaluation.
31-
* <p>Some examples:
31+
* Parse the expression string and return an {@link Expression} object that
32+
* can be used for repeated evaluation.
33+
* <p>Examples:
3234
* <pre class="code">
3335
* 3 + 4
3436
* name.firstName
3537
* </pre>
3638
* @param expressionString the raw expression string to parse
37-
* @return an evaluator for the parsed expression
38-
* @throws ParseException an exception occurred during parsing
39+
* @return an {@code Expression} for the parsed expression
40+
* @throws ParseException if an exception occurred during parsing
3941
*/
4042
Expression parseExpression(String expressionString) throws ParseException;
4143

4244
/**
43-
* Parse the expression string and return an Expression object you can use for repeated evaluation.
44-
* <p>Some examples:
45+
* Parse the expression string and return an {@link Expression} object that
46+
* can be used for repeated evaluation.
47+
* <p>Examples:
4548
* <pre class="code">
4649
* 3 + 4
4750
* name.firstName
4851
* </pre>
4952
* @param expressionString the raw expression string to parse
50-
* @param context a context for influencing this expression parsing routine (optional)
51-
* @return an evaluator for the parsed expression
52-
* @throws ParseException an exception occurred during parsing
53+
* @param context a context for influencing the expression parsing routine
54+
* @return an {@code Expression} for the parsed expression
55+
* @throws ParseException if an exception occurred during parsing
5356
*/
5457
Expression parseExpression(String expressionString, ParserContext context) throws ParseException;
5558

spring-expression/src/main/java/org/springframework/expression/ParserContext.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -47,16 +47,17 @@ public interface ParserContext {
4747
String getExpressionPrefix();
4848

4949
/**
50-
* For template expressions, return the prefix that identifies the end of an
50+
* For template expressions, returns the prefix that identifies the end of an
5151
* expression block within a string. For example: "}"
5252
* @return the suffix that identifies the end of an expression
5353
*/
5454
String getExpressionSuffix();
5555

5656

5757
/**
58-
* The default ParserContext implementation that enables template expression
59-
* parsing mode. The expression prefix is "#{" and the expression suffix is "}".
58+
* The default {@link ParserContext} implementation that enables template
59+
* expression parsing.
60+
* <p>The expression prefix is "#{", and the expression suffix is "}".
6061
* @see #isTemplate()
6162
*/
6263
ParserContext TEMPLATE_EXPRESSION = new ParserContext() {

spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@
2929
import org.springframework.util.Assert;
3030

3131
/**
32-
* An expression parser that understands templates. It can be subclassed by expression
33-
* parsers that do not offer first class support for templating.
32+
* Abstract base class for {@linkplain ExpressionParser expression parsers} that
33+
* support templates.
34+
*
35+
* <p>Can be subclassed by expression parsers that offer first class support for
36+
* templating.
3437
*
3538
* @author Keith Donald
3639
* @author Juergen Hoeller
@@ -88,7 +91,7 @@ private Expression parseTemplate(String expressionString, ParserContext context)
8891
* single quote '.
8992
* @param expressionString the expression string
9093
* @return the parsed expressions
91-
* @throws ParseException when the expressions cannot be parsed
94+
* @throws ParseException if the expressions cannot be parsed
9295
*/
9396
private Expression[] parseExpressions(String expressionString, ParserContext context) throws ParseException {
9497
List<Expression> expressions = new ArrayList<>();
@@ -229,7 +232,7 @@ private int skipToCorrectEndSuffix(String suffix, String expressionString, int a
229232
* @param expressionString the raw expression string to parse
230233
* @param context a context for influencing this expression parsing routine (optional)
231234
* @return an evaluator for the parsed expression
232-
* @throws ParseException an exception occurred during parsing
235+
* @throws ParseException if an exception occurred during parsing
233236
*/
234237
protected abstract Expression doParseExpression(String expressionString, @Nullable ParserContext context)
235238
throws ParseException;

spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,16 @@ public enum SpelMessage {
293293
NEGATIVE_REPEATED_TEXT_COUNT(Kind.ERROR, 1081,
294294
"Repeat count ''{0}'' must not be negative"),
295295

296+
/** @since 6.1.15 */
297+
UNSUPPORTED_CHARACTER(Kind.ERROR, 1082,
298+
"Unsupported character ''{0}'' ({1}) encountered in expression"),
299+
296300
/** @since 6.2 */
297-
EXCEPTION_DURING_INDEX_READ(Kind.ERROR, 1082,
301+
EXCEPTION_DURING_INDEX_READ(Kind.ERROR, 1083,
298302
"A problem occurred while attempting to read index ''{0}'' in ''{1}''"),
299303

300304
/** @since 6.2 */
301-
EXCEPTION_DURING_INDEX_WRITE(Kind.ERROR, 1083,
305+
EXCEPTION_DURING_INDEX_WRITE(Kind.ERROR, 1084,
302306
"A problem occurred while attempting to write index ''{0}'' in ''{1}''");
303307

304308

spring-expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,7 @@ else if (isTwoCharToken(TokenKind.SAFE_NAVI)) {
266266
raiseParseException(this.pos, SpelMessage.UNEXPECTED_ESCAPE_CHAR);
267267
break;
268268
default:
269-
throw new IllegalStateException(
270-
"Unsupported character '%s' (%d) encountered at position %d in expression."
271-
.formatted(ch, (int) ch, (this.pos + 1)));
269+
raiseParseException(this.pos + 1, SpelMessage.UNSUPPORTED_CHARACTER, ch, (int) ch);
272270
}
273271
}
274272
}

spring-expression/src/test/java/org/springframework/expression/spel/AbstractExpressionTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public abstract class AbstractExpressionTests {
4242
protected static final boolean SHOULD_NOT_BE_WRITABLE = false;
4343

4444

45-
protected final ExpressionParser parser = new SpelExpressionParser();
45+
protected final SpelExpressionParser parser = new SpelExpressionParser();
4646

4747
protected final StandardEvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
4848

spring-expression/src/test/java/org/springframework/expression/spel/ParsingTests.java

+11-12
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818

1919
import org.junit.jupiter.api.Nested;
2020
import org.junit.jupiter.api.Test;
21+
import org.junit.jupiter.params.ParameterizedTest;
22+
import org.junit.jupiter.params.provider.CsvSource;
2123

2224
import org.springframework.expression.spel.standard.SpelExpression;
23-
import org.springframework.expression.spel.standard.SpelExpressionParser;
2425

2526
import static org.assertj.core.api.Assertions.assertThat;
26-
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
2727

2828
/**
2929
* Parse some expressions and check we get the AST we expect.
@@ -34,10 +34,7 @@
3434
* @author Andy Clement
3535
* @author Sam Brannen
3636
*/
37-
class ParsingTests {
38-
39-
private final SpelExpressionParser parser = new SpelExpressionParser();
40-
37+
class ParsingTests extends AbstractExpressionTests {
4138

4239
@Nested
4340
class Miscellaneous {
@@ -104,12 +101,14 @@ void supportedCharactersInIdentifiers() {
104101
parseCheck("have乐趣()");
105102
}
106103

107-
@Test
108-
void unsupportedCharactersInIdentifiers() {
109-
// Invalid syntax
110-
assertThatIllegalStateException()
111-
.isThrownBy(() -> parser.parseRaw("apple~banana"))
112-
.withMessage("Unsupported character '~' (126) encountered at position 6 in expression.");
104+
@ParameterizedTest(name = "expression = ''{0}''")
105+
@CsvSource(textBlock = """
106+
apple~banana, ~, 6
107+
map[‘c], ‘, 5
108+
A § B, §, 3
109+
""")
110+
void unsupportedCharacter(String expression, char ch, int position) {
111+
parseAndCheckError(expression, SpelMessage.UNSUPPORTED_CHARACTER, position, ch, (int) ch);
113112
}
114113

115114
@Test

0 commit comments

Comments
 (0)