Skip to content

Introduce ConversionContext and clean up MappingMongoConverter #3575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3571-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data MongoDB</name>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3571-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3571-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3571-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ public Object get(MongoPersistentProperty property) {
* @param entity must not be {@literal null}.
* @return
*/
@Nullable
public Object getRawId(MongoPersistentEntity<?> entity) {
return entity.hasIdProperty() ? get(entity.getRequiredIdProperty()) : BsonUtils.asMap(document).get("_id");
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.StringJoiner;
import java.util.function.Function;
import java.util.stream.StreamSupport;

import org.bson.BSONObject;
import org.bson.BsonBinary;
import org.bson.BsonBoolean;
import org.bson.BsonDouble;
Expand All @@ -36,11 +38,11 @@
import org.bson.conversions.Bson;
import org.bson.json.JsonParseException;
import org.bson.types.ObjectId;

import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.CodecRegistryProvider;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

Expand All @@ -50,6 +52,8 @@
import com.mongodb.MongoClientSettings;

/**
* Internal API for operations on {@link Bson} elements that can be either {@link Document} or {@link DBObject}.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.0
Expand All @@ -62,6 +66,47 @@ public static <T> T get(Bson bson, String key) {
return (T) asMap(bson).get(key);
}

/**
* Remove {@code _id : null} from the given {@link Bson} if present.
*
* @param bson must not be {@literal null}.
* @since 2.5
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be @since 3.2

*/
public static void removeNullId(Bson bson) {

if (!contains(bson, "_id", null)) {
return;
}

removeFrom(bson, "_id");
}

/**
* Check if a given entry (key/value pair) is present in the given {@link Bson}.
*
* @param bson must not be {@literal null}.
* @param key must not be {@literal null}.
* @param value can be {@literal null}.
* @return {@literal true} if (key/value pair) is present.
* @since 2.5
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be @since 3.2

*/
public static boolean contains(Bson bson, String key, @Nullable Object value) {

if (bson instanceof Document) {

Document doc = (Document) bson;
return doc.containsKey(key) && ObjectUtils.nullSafeEquals(doc.get(key), value);
}
if (bson instanceof BSONObject) {

BSONObject bsonObject = (BSONObject) bson;
return bsonObject.containsField(key) && ObjectUtils.nullSafeEquals(bsonObject.get(key), value);
}

Map<String, Object> map = asMap(bson);
return map.containsKey(key) && ObjectUtils.nullSafeEquals(map.get(key), value);
}

public static Map<String, Object> asMap(Bson bson) {

if (bson instanceof Document) {
Expand All @@ -70,21 +115,78 @@ public static Map<String, Object> asMap(Bson bson) {
if (bson instanceof BasicDBObject) {
return ((BasicDBObject) bson);
}
if (bson instanceof DBObject) {
return ((DBObject) bson).toMap();
}

return (Map) bson.toBsonDocument(Document.class, MongoClientSettings.getDefaultCodecRegistry());
}

public static void addToMap(Bson bson, String key, @Nullable Object value) {

if (bson instanceof Document) {

((Document) bson).put(key, value);
return;
}
if (bson instanceof DBObject) {
((DBObject) bson).put(key, value);
if (bson instanceof BSONObject) {

((BSONObject) bson).put(key, value);
return;
}
throw new IllegalArgumentException("o_O what's that? Cannot add value to " + bson.getClass());

throw new IllegalArgumentException(String.format(
"Cannot add key/value pair to %s. as map. Given Bson must be a Document or BSONObject!", bson.getClass()));
}

/**
* Add all entries from the given {@literal source} {@link Map} to the {@literal target}.
*
* @param target must not be {@literal null}.
* @param source must not be {@literal null}.
* @since 2.5
*/
public static void addAllToMap(Bson target, Map<String, ?> source) {

if (target instanceof Document) {

((Document) target).putAll(source);
return;
}

if (target instanceof BSONObject) {

((BSONObject) target).putAll(source);
return;
}

throw new IllegalArgumentException(
String.format("Cannot add all to %s. Given Bson must be a Document or BSONObject.", target.getClass()));
}

/**
* Remove the given {@literal key} from the {@link Bson} value.
*
* @param bson must not be {@literal null}.
* @param key must not be {@literal null}.
* @since 2.5
*/
static void removeFrom(Bson bson, String key) {

if (bson instanceof Document) {

((Document) bson).remove(key);
return;
}

if (bson instanceof BSONObject) {

((BSONObject) bson).removeField(key);
return;
}

throw new IllegalArgumentException(
String.format("Cannot remove from %s. Given Bson must be a Document or BSONObject.", bson.getClass()));
}

/**
Expand Down Expand Up @@ -282,6 +384,23 @@ public static Document parse(String json, @Nullable CodecRegistryProvider codecR
.orElseGet(() -> new DocumentCodec(codecRegistryProvider.getCodecRegistry())));
}

/**
* Returns given object as {@link Collection}. Will return the {@link Collection} as is if the source is a
* {@link Collection} already, will convert an array into a {@link Collection} or simply create a single element
* collection for everything else.
*
* @param source
* @return
*/
public static Collection<?> asCollection(Object source) {

if (source instanceof Collection) {
return (Collection<?>) source;
}

return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source);
}

@Nullable
private static String toJson(@Nullable Object value) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
import com.mongodb.client.MongoDatabase;

/**
* Unit tests for {@link DbRefMappingMongoConverter}.
* Unit tests for {@link MappingMongoConverter}.
*
* @author Oliver Gierke
* @author Thomas Darimont
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2177,9 +2177,10 @@ public void readAndConvertDBRefNestedByMapCorrectly() {
MappingMongoConverter spyConverter = spy(converter);
Mockito.doReturn(cluster).when(spyConverter).readRef(dbRef);

Map<Object, Object> result = spyConverter.readMap(ClassTypeInformation.MAP, data, ObjectPath.ROOT);
Map<Object, Object> result = spyConverter.readMap(spyConverter.getConversionContext(ObjectPath.ROOT), data,
ClassTypeInformation.MAP);

assertThat(((LinkedHashMap) result.get("cluster")).get("_id")).isEqualTo(100L);
assertThat(((Map) result.get("cluster")).get("_id")).isEqualTo(100L);
}

@Test // GH-3546
Expand Down