Compare commits

...

11 Commits

Author SHA1 Message Date
Jens Schauder
a4cb0d6432 DATAMONGO-2422 - Release version 2.2.3 (Moore SR3). 2019-12-04 14:12:24 +01:00
Jens Schauder
437368bedb DATAMONGO-2422 - Prepare 2.2.3 (Moore SR3). 2019-12-04 14:11:44 +01:00
Jens Schauder
4057b193d6 DATAMONGO-2422 - Updated changelog. 2019-12-04 14:11:36 +01:00
Jens Schauder
89b1b5c7f6 DATAMONGO-2421 - Updated changelog. 2019-12-04 12:09:48 +01:00
Mark Paluch
60d3438277 DATAMONGO-2430 - Upgrade to mongo-java-driver 3.11.2. 2019-12-04 11:42:04 +01:00
Mark Paluch
a578a10b5b DATAMONGO-2418 - Polishing.
Reformat code.

Original pull request: #814.
2019-12-04 10:31:33 +01:00
Christoph Strobl
5cf24af00b DATAMONGO-2418 - Obtain EvaluationContextExtensions lazily when parsing Bson queries.
An eager evaluation of the context extension can lead to errors when e.g. the security context was not present.

Original pull request: #814.
2019-12-04 10:31:33 +01:00
Mark Paluch
6c0e455146 DATAMONGO-2410 - Polishing.
Simplify cast. Extend test with DBObject interface.

Original pull request: #813.
2019-12-04 08:56:54 +01:00
Christoph Strobl
932a946868 DATAMONGO-2410 - Fix Document to BasicDBObject conversion.
Original pull request: #813.
2019-12-04 08:56:54 +01:00
Mark Paluch
99a1cfbff9 DATAMONGO-2402 - After release cleanups. 2019-11-18 12:42:05 +01:00
Mark Paluch
d7bbdde1e7 DATAMONGO-2402 - Prepare next development iteration. 2019-11-18 12:42:04 +01:00
16 changed files with 132 additions and 25 deletions

View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.2.RELEASE</version>
<version>2.2.3.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.2.2.RELEASE</version>
<version>2.2.3.RELEASE</version>
</parent>
<modules>
@@ -26,8 +26,8 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.2.2.RELEASE</springdata.commons>
<mongo>3.11.1</mongo>
<springdata.commons>2.2.3.RELEASE</springdata.commons>
<mongo>3.11.2</mongo>
<mongo.reactivestreams>1.12.0</mongo.reactivestreams>
<jmh.version>1.19</jmh.version>
</properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.2.RELEASE</version>
<version>2.2.3.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.2.RELEASE</version>
<version>2.2.3.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.2.RELEASE</version>
<version>2.2.3.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -239,11 +239,20 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return conversionService.convert(bson, rawType);
}
if (DBObject.class.isAssignableFrom(rawType)) {
if (Document.class.isAssignableFrom(rawType)) {
return (S) bson;
}
if (Document.class.isAssignableFrom(rawType)) {
if (DBObject.class.isAssignableFrom(rawType)) {
if (bson instanceof DBObject) {
return (S) bson;
}
if (bson instanceof Document) {
return (S) new BasicDBObject((Document) bson);
}
return (S) bson;
}
@@ -273,9 +282,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (codecRegistryProvider != null) {
Optional<? extends Codec<? extends S>> codec = codecRegistryProvider.getCodecFor(rawType);
if(codec.isPresent()) {
return codec.get().decode(new JsonReader(target.toJson()),
DecoderContext.builder().build());
if (codec.isPresent()) {
return codec.get().decode(new JsonReader(target.toJson()), DecoderContext.builder().build());
}
}

View File

@@ -113,7 +113,7 @@ class AggregationUtils {
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
ParameterBindingContext bindingContext = new ParameterBindingContext((accessor::getBindableValue), expressionParser,
evaluationContextProvider.getEvaluationContext(method.getParameters(), accessor.getValues()));
() -> evaluationContextProvider.getEvaluationContext(method.getParameters(), accessor.getValues()));
List<AggregationOperation> target = new ArrayList<>(method.getAnnotatedAggregation().length);
for (String source : method.getAnnotatedAggregation()) {

View File

@@ -73,7 +73,7 @@ class CollationUtils {
if (StringUtils.trimLeadingWhitespace(collationExpression).startsWith("{")) {
ParameterBindingContext bindingContext = new ParameterBindingContext((accessor::getBindableValue),
expressionParser, evaluationContextProvider.getEvaluationContext(parameters, accessor.getValues()));
expressionParser, () -> evaluationContextProvider.getEvaluationContext(parameters, accessor.getValues()));
return Collation.from(CODEC.decode(collationExpression, bindingContext));
}

View File

@@ -117,7 +117,7 @@ public class ReactiveStringBasedMongoQuery extends AbstractReactiveMongoQuery {
protected Query createQuery(ConvertingParameterAccessor accessor) {
ParameterBindingContext bindingContext = new ParameterBindingContext((accessor::getBindableValue), expressionParser,
evaluationContextProvider.getEvaluationContext(getQueryMethod().getParameters(), accessor.getValues()));
() -> evaluationContextProvider.getEvaluationContext(getQueryMethod().getParameters(), accessor.getValues()));
Document queryObject = CODEC.decode(this.query, bindingContext);
Document fieldsObject = CODEC.decode(this.fieldSpec, bindingContext);

View File

@@ -116,7 +116,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
protected Query createQuery(ConvertingParameterAccessor accessor) {
ParameterBindingContext bindingContext = new ParameterBindingContext((accessor::getBindableValue), expressionParser,
evaluationContextProvider.getEvaluationContext(getQueryMethod().getParameters(), accessor.getValues()));
() -> evaluationContextProvider.getEvaluationContext(getQueryMethod().getParameters(), accessor.getValues()));
Document queryObject = CODEC.decode(this.query, bindingContext);
Document fieldsObject = CODEC.decode(this.fieldSpec, bindingContext);

View File

@@ -15,28 +15,54 @@
*/
package org.springframework.data.mongodb.util.json;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.function.Supplier;
import org.springframework.data.util.Lazy;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.lang.Nullable;
/**
* Reusable context for binding parameters to an placeholder or a SpEL expression within a JSON structure. <br />
* Reusable context for binding parameters to a placeholder or a SpEL expression within a JSON structure. <br />
* To be used along with {@link ParameterBindingDocumentCodec#decode(String, ParameterBindingContext)}.
*
* @author Christoph Strobl
* @since 2.2
*/
@RequiredArgsConstructor
@Getter
public class ParameterBindingContext {
private final ValueProvider valueProvider;
private final SpelExpressionParser expressionParser;
private final EvaluationContext evaluationContext;
private final Lazy<EvaluationContext> evaluationContext;
/**
* @param valueProvider
* @param expressionParser
* @param evaluationContext
* @deprecated since 2.2.3 - Please use
* {@link #ParameterBindingContext(ValueProvider, SpelExpressionParser, Supplier)} instead.
*/
@Deprecated
public ParameterBindingContext(ValueProvider valueProvider, SpelExpressionParser expressionParser,
EvaluationContext evaluationContext) {
this(valueProvider, expressionParser, () -> evaluationContext);
}
/**
* @param valueProvider
* @param expressionParser
* @param evaluationContext a {@link Supplier} for {@link Lazy} context retrieval.
* @since 2.2.3
*/
public ParameterBindingContext(ValueProvider valueProvider, SpelExpressionParser expressionParser,
Supplier<EvaluationContext> evaluationContext) {
this.valueProvider = valueProvider;
this.expressionParser = expressionParser;
this.evaluationContext = evaluationContext instanceof Lazy ? (Lazy) evaluationContext : Lazy.of(evaluationContext);
}
@Nullable
public Object bindableValueForIndex(int index) {
@@ -47,6 +73,18 @@ public class ParameterBindingContext {
public Object evaluateExpression(String expressionString) {
Expression expression = expressionParser.parseExpression(expressionString);
return expression.getValue(this.evaluationContext, Object.class);
return expression.getValue(getEvaluationContext(), Object.class);
}
public EvaluationContext getEvaluationContext() {
return this.evaluationContext.get();
}
public SpelExpressionParser getExpressionParser() {
return expressionParser;
}
public ValueProvider getValueProvider() {
return valueProvider;
}
}

View File

@@ -162,7 +162,7 @@ public class ParameterBindingDocumentCodec implements CollectibleCodec<Document>
public Document decode(@Nullable String json, Object[] values) {
return decode(json, new ParameterBindingContext((index) -> values[index], new SpelExpressionParser(),
EvaluationContextProvider.DEFAULT.getEvaluationContext(values)));
() -> EvaluationContextProvider.DEFAULT.getEvaluationContext(values)));
}
public Document decode(@Nullable String json, ParameterBindingContext bindingContext) {

View File

@@ -26,6 +26,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -96,6 +97,15 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
public ParameterBindingJsonReader(String json, ValueProvider accessor, SpelExpressionParser spelExpressionParser,
EvaluationContext evaluationContext) {
this(json, accessor, spelExpressionParser, () -> evaluationContext);
}
/**
* @since 2.2.3
*/
public ParameterBindingJsonReader(String json, ValueProvider accessor, SpelExpressionParser spelExpressionParser,
Supplier<EvaluationContext> evaluationContext) {
this.scanner = new JsonScanner(json);
setContext(new Context(null, BsonContextType.TOP_LEVEL));

View File

@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.springframework.data.mongodb.core.DocumentTestUtils.*;
import com.mongodb.DBObject;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
@@ -77,6 +78,7 @@ import org.springframework.data.util.ClassTypeInformation;
import org.springframework.test.util.ReflectionTestUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBRef;
/**
@@ -2067,6 +2069,15 @@ public class MappingMongoConverterUnitTests {
assertThat(target.dateAsObjectId).isEqualTo(new Date(reference.getTimestamp()));
}
@Test // DATAMONGO-2410
public void shouldAllowReadingBackDbObject() {
assertThat(converter.read(BasicDBObject.class, new org.bson.Document("property", "value")))
.isEqualTo(new BasicDBObject("property", "value"));
assertThat(converter.read(DBObject.class, new org.bson.Document("property", "value")))
.isEqualTo(new BasicDBObject("property", "value"));
}
static class GenericType<T> {
T content;
}

View File

@@ -26,6 +26,10 @@ import java.util.List;
import org.bson.Document;
import org.bson.codecs.DecoderContext;
import org.junit.Test;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
* Unit tests for {@link ParameterBindingJsonReader}.
@@ -197,6 +201,25 @@ public class ParameterBindingJsonReaderUnitTests {
assertThat(target).isEqualTo(Document.parse("{ 'end_date' : { $gte : { $date : " + time + " } } } "));
}
@Test // DATAMONGO-2418
public void shouldNotAccessSpElEvaluationContextWhenNoSpElPresentInBindableTarget() {
Object[] args = new Object[] { "value" };
EvaluationContext evaluationContext = new StandardEvaluationContext() {
@Override
public TypedValue getRootObject() {
throw new RuntimeException("o_O");
}
};
ParameterBindingJsonReader reader = new ParameterBindingJsonReader("{ 'name':'?0' }",
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
assertThat(target).isEqualTo(new Document("name", "value"));
}
private static Document parse(String json, Object... args) {
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);

View File

@@ -1,6 +1,20 @@
Spring Data MongoDB Changelog
=============================
Changes in version 2.2.3.RELEASE (2019-12-04)
---------------------------------------------
* DATAMONGO-2430 - Upgrade to mongo-java-driver 3.11.2.
* DATAMONGO-2422 - Release 2.2.3 (Moore SR3).
* DATAMONGO-2418 - Application Context Doesn't start with @Query.
* DATAMONGO-2410 - Using BasicDBObject as an entity caused java.lang.ClassCastException in runtime.
Changes in version 2.1.14.RELEASE (2019-12-04)
----------------------------------------------
* DATAMONGO-2421 - Release 2.1.14 (Lovelace SR14).
* DATAMONGO-2410 - Using BasicDBObject as an entity caused java.lang.ClassCastException in runtime.
Changes in version 2.2.2.RELEASE (2019-11-18)
---------------------------------------------
* DATAMONGO-2414 - ReactiveGridFsResource.getDownloadStream(…) hang if completion happens on event loop.
@@ -2814,3 +2828,5 @@ Repository
* Namespace support for Mongo repositories
* Allow usage of pagination and sorting with repositories

View File

@@ -1,4 +1,4 @@
Spring Data MongoDB 2.2.2
Spring Data MongoDB 2.2.3
Copyright (c) [2010-2019] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -8,3 +8,4 @@ This product may include a number of subcomponents with
separate copyright notices and license terms. Your use of the source
code for the these subcomponents is subject to the terms and
conditions of the subcomponent's license, as noted in the LICENSE file.