DATAMONGO-2545 - Fix regression in String query SpEL parameter binding.
We reenabled parameter binding within SpEL using query parameter placeholders ?0, ?1,... instead of their array index [0],[1],... Original pull request: #864.
This commit is contained in:
committed by
Mark Paluch
parent
af39b422b6
commit
3af7269dbb
@@ -368,26 +368,33 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
|
||||
|
||||
if (token.getType().equals(JsonTokenType.UNQUOTED_STRING)) {
|
||||
|
||||
if (matcher.find()) {
|
||||
|
||||
int index = computeParameterIndex(matcher.group());
|
||||
bindableValue.setValue(getBindableValueForIndex(index));
|
||||
bindableValue.setType(bsonTypeForValue(getBindableValueForIndex(index)));
|
||||
return bindableValue;
|
||||
}
|
||||
|
||||
Matcher regexMatcher = EXPRESSION_BINDING_PATTERN.matcher(tokenValue);
|
||||
if (regexMatcher.find()) {
|
||||
|
||||
String binding = regexMatcher.group();
|
||||
String expression = binding.substring(3, binding.length() - 1);
|
||||
|
||||
Matcher inSpelMatcher = PARAMETER_BINDING_PATTERN.matcher(expression);
|
||||
while (inSpelMatcher.find()) {
|
||||
|
||||
int index = computeParameterIndex(inSpelMatcher.group());
|
||||
expression = expression.replace(inSpelMatcher.group(), getBindableValueForIndex(index).toString());
|
||||
}
|
||||
|
||||
Object value = evaluateExpression(expression);
|
||||
bindableValue.setValue(value);
|
||||
bindableValue.setType(bsonTypeForValue(value));
|
||||
return bindableValue;
|
||||
}
|
||||
|
||||
if (matcher.find()) {
|
||||
|
||||
int index = computeParameterIndex(matcher.group());
|
||||
bindableValue.setValue(getBindableValueForIndex(index));
|
||||
bindableValue.setType(bsonTypeForValue(getBindableValueForIndex(index)));
|
||||
return bindableValue;
|
||||
}
|
||||
|
||||
bindableValue.setValue(tokenValue);
|
||||
bindableValue.setType(BsonType.STRING);
|
||||
return bindableValue;
|
||||
@@ -396,28 +403,37 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
|
||||
|
||||
String computedValue = tokenValue;
|
||||
|
||||
boolean matched = false;
|
||||
|
||||
|
||||
Matcher regexMatcher = EXPRESSION_BINDING_PATTERN.matcher(computedValue);
|
||||
|
||||
while (regexMatcher.find()) {
|
||||
|
||||
String binding = regexMatcher.group();
|
||||
String expression = binding.substring(3, binding.length() - 1);
|
||||
|
||||
Matcher inSpelMatcher = PARAMETER_BINDING_PATTERN.matcher(expression);
|
||||
while (inSpelMatcher.find()) {
|
||||
|
||||
int index = computeParameterIndex(inSpelMatcher.group());
|
||||
expression = expression.replace(inSpelMatcher.group(), getBindableValueForIndex(index).toString());
|
||||
}
|
||||
|
||||
computedValue = computedValue.replace(binding, nullSafeToString(evaluateExpression(expression)));
|
||||
|
||||
bindableValue.setValue(computedValue);
|
||||
bindableValue.setType(BsonType.STRING);
|
||||
|
||||
return bindableValue;
|
||||
}
|
||||
|
||||
while (matcher.find()) {
|
||||
|
||||
matched = true;
|
||||
String group = matcher.group();
|
||||
int index = computeParameterIndex(group);
|
||||
computedValue = computedValue.replace(group, nullSafeToString(getBindableValueForIndex(index)));
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
|
||||
Matcher regexMatcher = EXPRESSION_BINDING_PATTERN.matcher(tokenValue);
|
||||
|
||||
while (regexMatcher.find()) {
|
||||
|
||||
String binding = regexMatcher.group();
|
||||
String expression = binding.substring(3, binding.length() - 1);
|
||||
|
||||
computedValue = computedValue.replace(binding, nullSafeToString(evaluateExpression(expression)));
|
||||
}
|
||||
}
|
||||
|
||||
bindableValue.setValue(computedValue);
|
||||
bindableValue.setType(BsonType.STRING);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
import org.bson.Document;
|
||||
import org.bson.codecs.DecoderContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.spel.EvaluationContextProvider;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
@@ -264,10 +265,60 @@ class ParameterBindingJsonReaderUnitTests {
|
||||
assertThat(target).isEqualTo(Document.parse("{\"$and\": [{\"v1\": {\"$in\": [1]}}]}"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2545
|
||||
void shouldABindArgumentsViaIndexInSpelExpressions() {
|
||||
|
||||
Object[] args = new Object[] { "yess", "nooo" };
|
||||
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
|
||||
.getEvaluationContext(args);
|
||||
|
||||
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(
|
||||
"{ 'isBatman' : ?#{ T(" + this.getClass().getName() + ").isBatman() ? [0] : [1] }}",
|
||||
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
|
||||
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
|
||||
|
||||
assertThat(target).isEqualTo(new Document("isBatman", "nooo"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2545
|
||||
void shouldAllowMethodArgumentPlaceholdersInSpelExpressions/*becuase this worked before*/() {
|
||||
|
||||
Object[] args = new Object[] { "yess", "nooo" };
|
||||
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
|
||||
.getEvaluationContext(args);
|
||||
|
||||
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(
|
||||
"{ 'isBatman' : ?#{ T(" + this.getClass().getName() + ").isBatman() ? '?0' : '?1' }}",
|
||||
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
|
||||
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
|
||||
|
||||
assertThat(target).isEqualTo(new Document("isBatman", "nooo"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2545
|
||||
void shouldAllowMethodArgumentPlaceholdersInQuotedSpelExpressions/*becuase this worked before*/() {
|
||||
|
||||
Object[] args = new Object[] { "yess", "nooo" };
|
||||
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
|
||||
.getEvaluationContext(args);
|
||||
|
||||
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(
|
||||
"{ 'isBatman' : \"?#{ T(" + this.getClass().getName() + ").isBatman() ? '?0' : '?1' }\" }",
|
||||
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
|
||||
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
|
||||
|
||||
assertThat(target).isEqualTo(new Document("isBatman", "nooo"));
|
||||
}
|
||||
|
||||
private static Document parse(String json, Object... args) {
|
||||
|
||||
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);
|
||||
return new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
|
||||
}
|
||||
|
||||
// DATAMONGO-2545
|
||||
public static boolean isBatman() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user