Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0f55fb3

Browse files
christophstroblmp911de
authored andcommittedMay 26, 2020
DATAMONGO-2545 - Fix full Query Document binding resulting from SpEL.
We reenabled annotated queries using a SpEL expression resulting in the actual query document. Original pull request: #864.
1 parent 5ae7547 commit 0f55fb3

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed
 

‎spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.bson.Transformer;
3939
import org.bson.codecs.*;
4040
import org.bson.codecs.configuration.CodecRegistry;
41+
import org.bson.json.JsonParseException;
4142
import org.springframework.data.spel.EvaluationContextProvider;
4243
import org.springframework.expression.spel.standard.SpelExpressionParser;
4344
import org.springframework.lang.Nullable;
@@ -190,9 +191,26 @@ public Document decode(final BsonReader reader, final DecoderContext decoderCont
190191

191192
Document document = new Document();
192193
reader.readStartDocument();
193-
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
194-
String fieldName = reader.readName();
195-
document.put(fieldName, readValue(reader, decoderContext));
194+
195+
try {
196+
197+
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
198+
String fieldName = reader.readName();
199+
Object value = readValue(reader, decoderContext);
200+
document.put(fieldName, value);
201+
}
202+
} catch (JsonParseException e) {
203+
try {
204+
205+
Object value = readValue(reader, decoderContext);
206+
if (value instanceof Map) {
207+
if (!((Map) value).isEmpty()) {
208+
return new Document((Map) value);
209+
}
210+
}
211+
} catch (Exception ex) {
212+
throw e;
213+
}
196214
}
197215

198216
reader.readEndDocument();

‎spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Calendar;
2626
import java.util.Date;
2727
import java.util.Locale;
28+
import java.util.Map;
2829
import java.util.TimeZone;
2930
import java.util.function.Supplier;
3031
import java.util.regex.Matcher;
@@ -495,6 +496,9 @@ private BsonType bsonTypeForValue(Object value) {
495496
if (ClassUtils.isAssignable(Iterable.class, type)) {
496497
return BsonType.ARRAY;
497498
}
499+
if (ClassUtils.isAssignable(Map.class, type)) {
500+
return BsonType.DOCUMENT;
501+
}
498502

499503
return BsonType.UNDEFINED;
500504
}

‎spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
import static org.assertj.core.api.Assertions.*;
1919

20+
import lombok.AllArgsConstructor;
21+
import lombok.Data;
22+
2023
import java.nio.charset.StandardCharsets;
2124
import java.util.Arrays;
2225
import java.util.Collections;
@@ -310,6 +313,26 @@ void shouldABindArgumentsViaIndexInSpelExpressions() {
310313
assertThat(target).isEqualTo(new Document("isBatman", "nooo"));
311314
}
312315

316+
@Test // DATAMONGO-2545
317+
void evaluatesSpelExpressionDefiningEntireQuery() {
318+
319+
Object[] args = new Object[] {};
320+
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
321+
.getEvaluationContext(args);
322+
evaluationContext.setRootObject(new DummySecurityObject(new DummyWithId("wonderwoman")));
323+
324+
String json = "?#{ T(" + this.getClass().getName()
325+
+ ").isBatman() ? {'_class': { '$eq' : 'region' }} : { '$and' : { {'_class': { '$eq' : 'region' } }, {'user.superviser': principal.id } } } }";
326+
327+
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json,
328+
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
329+
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
330+
331+
assertThat(target)
332+
.isEqualTo(new Document("$and", Arrays.asList(new Document("_class", new Document("$eq", "region")),
333+
new Document("user.superviser", "wonderwoman"))));
334+
}
335+
313336
private static Document parse(String json, Object... args) {
314337

315338
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);
@@ -321,4 +344,16 @@ public static boolean isBatman() {
321344
return false;
322345
}
323346

347+
@Data
348+
@AllArgsConstructor
349+
public static class DummySecurityObject {
350+
DummyWithId principal;
351+
}
352+
353+
@Data
354+
@AllArgsConstructor
355+
public static class DummyWithId {
356+
String id;
357+
}
358+
324359
}

0 commit comments

Comments
 (0)
Please sign in to comment.