diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operators.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operators.adoc index 92c0b3db563..37de2a3aedb 100644 --- a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operators.adoc +++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operators.adoc @@ -53,7 +53,7 @@ Kotlin:: val trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean::class.java) // uses CustomValue:::compareTo - val trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean::class.java); + val trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean::class.java) ---- ====== @@ -167,7 +167,7 @@ Kotlin:: [CAUTION] ==== The syntax for the `between` operator is ` between {, }`, -which is effectively a shortcut for ` >= && \<= }`. +which is effectively a shortcut for ` >= && \<= `. Consequently, `1 between {1, 5}` evaluates to `true`, while `1 between {5, 1}` evaluates to `false`. @@ -312,13 +312,13 @@ Kotlin:: // evaluates to 'a' val ch = parser.parseExpression("'d' - 3") - .getValue(Character::class.java); + .getValue(Char::class.java) // -- Repeat -- // evaluates to "abcabc" val repeated = parser.parseExpression("'abc' * 2") - .getValue(String::class.java); + .getValue(String::class.java) ---- ====== @@ -485,7 +485,7 @@ Kotlin:: // -- Operator precedence -- - val minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Int::class.java) // -21 + val minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Int::class.java) // -21 ---- ====== @@ -541,32 +541,7 @@ For example, if we want to overload the `ADD` operator to allow two lists to be concatenated using the `+` sign, we can implement a custom `OperatorOverloader` as follows. -[source,java,indent=0,subs="verbatim,quotes"] ----- - pubic class ListConcatenation implements OperatorOverloader { - - @Override - public boolean overridesOperation(Operation operation, Object left, Object right) { - return (operation == Operation.ADD && - left instanceof List && right instanceof List); - } - - @Override - @SuppressWarnings("unchecked") - public Object operate(Operation operation, Object left, Object right) { - if (operation == Operation.ADD && - left instanceof List list1 && right instanceof List list2) { - - List result = new ArrayList(list1); - result.addAll(list2); - return result; - } - throw new UnsupportedOperationException( - "No overload for operation %s and operands [%s] and [%s]" - .formatted(operation, left, right)); - } - } ----- +include-code::./ListConcatenation[] If we register `ListConcatenation` as the `OperatorOverloader` in a `StandardEvaluationContext`, we can then evaluate expressions like `{1, 2, 3} + {4, 5}` @@ -589,8 +564,8 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - StandardEvaluationContext context = StandardEvaluationContext() - context.setOperatorOverloader(ListConcatenation()) + val context = StandardEvaluationContext() + context.operatorOverloader = ListConcatenation() // evaluates to a new list: [1, 2, 3, 4, 5] parser.parseExpression("{1, 2, 3} + {2 + 2, 5}").getValue(context, List::class.java) diff --git a/framework-docs/src/main/java/org/springframework/docs/core/expressions/languageref/expressionsoperatorsoverloaded/ListConcatenation.java b/framework-docs/src/main/java/org/springframework/docs/core/expressions/languageref/expressionsoperatorsoverloaded/ListConcatenation.java new file mode 100644 index 00000000000..6bd1ea62e2a --- /dev/null +++ b/framework-docs/src/main/java/org/springframework/docs/core/expressions/languageref/expressionsoperatorsoverloaded/ListConcatenation.java @@ -0,0 +1,46 @@ +/* + * Copyright 2026-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.docs.core.expressions.languageref.expressionsoperatorsoverloaded; + +import org.springframework.expression.Operation; +import org.springframework.expression.OperatorOverloader; + +import java.util.ArrayList; +import java.util.List; + +public class ListConcatenation implements OperatorOverloader { + + @Override + public boolean overridesOperation(Operation operation, Object left, Object right) { + return operation == Operation.ADD && left instanceof List && right instanceof List; + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + public Object operate(Operation operation, Object left, Object right) { + if (operation == Operation.ADD && + left instanceof List list1 && right instanceof List list2) { + + List result = new ArrayList(list1); + result.addAll(list2); + return result; + } + throw new UnsupportedOperationException( + "No overload for operation %s and operands [%s] and [%s]" + .formatted(operation, left, right)); + } +} diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/core/expressions/languageref/expressionsoperatorsoverloaded/ListConcatenation.kt b/framework-docs/src/main/kotlin/org/springframework/docs/core/expressions/languageref/expressionsoperatorsoverloaded/ListConcatenation.kt new file mode 100644 index 00000000000..49e113823d0 --- /dev/null +++ b/framework-docs/src/main/kotlin/org/springframework/docs/core/expressions/languageref/expressionsoperatorsoverloaded/ListConcatenation.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2026-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.docs.core.expressions.languageref.expressionsoperatorsoverloaded + +import org.springframework.expression.Operation +import org.springframework.expression.OperatorOverloader + +class ListConcatenation: OperatorOverloader { + + override fun overridesOperation(operation: Operation, left: Any?, right: Any?): Boolean { + return operation == Operation.ADD && left is List<*> && right is List<*> + } + + override fun operate(operation: Operation, left: Any?, right: Any?): Any { + if (operation == Operation.ADD && left is List<*> && right is List<*>) { + return left + right + } + + throw UnsupportedOperationException("No overload for operation $operation and operands [$left] and [$right]") + } +} \ No newline at end of file