Skip to content

Commit f38f6d6

Browse files
committed
Polishing.
Support DBObject and Map that as source for entity materialization and map conversion. See #3702 Original pull request: #3704.
1 parent 3f27e8e commit f38f6d6

File tree

4 files changed

+67
-11
lines changed

4 files changed

+67
-11
lines changed

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java

+5-8
Original file line numberDiff line numberDiff line change
@@ -2042,14 +2042,11 @@ public <S extends Object> S convert(Object source, TypeInformation<? extends S>
20422042
if (typeHint.isMap()) {
20432043

20442044
if(ClassUtils.isAssignable(Document.class, typeHint.getType())) {
2045-
return (S) documentConverter.convert(this, (Bson) source, typeHint);
2045+
return (S) documentConverter.convert(this, BsonUtils.asBson(source), typeHint);
20462046
}
20472047

2048-
if(source instanceof Bson) {
2049-
return (S) mapConverter.convert(this, (Bson) source, typeHint);
2050-
}
2051-
if(source instanceof Map) {
2052-
return (S) mapConverter.convert(this, new Document((Map<String,Object>) source), typeHint);
2048+
if (BsonUtils.supportsBson(source)) {
2049+
return (S) mapConverter.convert(this, BsonUtils.asBson(source), typeHint);
20532050
}
20542051

20552052
throw new IllegalArgumentException(String.format("Expected map like structure but found %s", source.getClass()));
@@ -2064,8 +2061,8 @@ public <S extends Object> S convert(Object source, TypeInformation<? extends S>
20642061
String.format(INCOMPATIBLE_TYPES, source, BasicDBList.class, typeHint.getType(), getPath()));
20652062
}
20662063

2067-
if (source instanceof Bson) {
2068-
return (S) documentConverter.convert(this, (Bson) source, typeHint);
2064+
if (BsonUtils.supportsBson(source)) {
2065+
return (S) documentConverter.convert(this, BsonUtils.asBson(source), typeHint);
20692066
}
20702067

20712068
return (S) elementConverter.convert(source, typeHint);

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java

+43
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,49 @@ private static Map<String, Object> getAsMap(Object source) {
494494
return null;
495495
}
496496

497+
/**
498+
* Returns the given source object as {@link Bson}, i.e. {@link Document}s and maps as is or throw
499+
* {@link IllegalArgumentException}.
500+
*
501+
* @param source
502+
* @return the converted/casted source object.
503+
* @throws IllegalArgumentException if {@code source} cannot be converted/cast to {@link Bson}.
504+
* @since 3.2.3
505+
* @see #supportsBson(Object)
506+
*/
507+
@SuppressWarnings("unchecked")
508+
public static Bson asBson(Object source) {
509+
510+
if (source instanceof Document) {
511+
return (Document) source;
512+
}
513+
514+
if (source instanceof BasicDBObject) {
515+
return (BasicDBObject) source;
516+
}
517+
518+
if (source instanceof DBObject) {
519+
return new Document(((DBObject) source).toMap());
520+
}
521+
522+
if (source instanceof Map) {
523+
return new Document((Map<String, Object>) source);
524+
}
525+
526+
throw new IllegalArgumentException(String.format("Cannot convert %s to Bson", source));
527+
}
528+
529+
/**
530+
* Returns the given source can be used/converted as {@link Bson}.
531+
*
532+
* @param source
533+
* @return {@literal true} if the given source can be converted to {@link Bson}.
534+
* @since 3.2.3
535+
*/
536+
public static boolean supportsBson(Object source) {
537+
return source instanceof DBObject || source instanceof Map;
538+
}
539+
497540
/**
498541
* Returns given object as {@link Collection}. Will return the {@link Collection} as is if the source is a
499542
* {@link Collection} already, will convert an array into a {@link Collection} or simply create a single element

Diff for: spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -934,10 +934,11 @@ void convertsSetToBasicDBList() {
934934
assertThat(readResult.iterator().next()).isInstanceOf(Address.class);
935935
}
936936

937-
@Test // DATAMONGO-402
937+
@Test // DATAMONGO-402, GH-3702
938938
void readsMemberClassCorrectly() {
939939

940-
org.bson.Document document = new org.bson.Document("inner", new org.bson.Document("value", "FOO!"));
940+
org.bson.Document document = new org.bson.Document("inner",
941+
new LinkedHashMap<>(new org.bson.Document("value", "FOO!")));
941942

942943
Outer outer = converter.read(Outer.class, document);
943944
assertThat(outer.inner).isNotNull();

Diff for: spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/BsonUtilsTest.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import java.util.ArrayList;
2121
import java.util.Collection;
22-
import java.util.List;
22+
import java.util.Collections;
2323

2424
import org.bson.BsonDouble;
2525
import org.bson.BsonInt32;
@@ -29,10 +29,16 @@
2929
import org.bson.Document;
3030
import org.bson.types.ObjectId;
3131
import org.junit.jupiter.api.Test;
32+
3233
import org.springframework.data.mongodb.util.BsonUtils;
3334

35+
import com.mongodb.BasicDBList;
36+
3437
/**
38+
* Unit tests for {@link BsonUtils}.
39+
*
3540
* @author Christoph Strobl
41+
* @author Mark Paluch
3642
*/
3743
class BsonUtilsTest {
3844

@@ -111,4 +117,13 @@ void asCollectionConvertsWrapsNonIterable() {
111117

112118
assertThat((Collection)BsonUtils.asCollection(source)).containsExactly(source);
113119
}
120+
121+
@Test // GH-3702
122+
void supportsBsonShouldReportIfConversionSupported() {
123+
124+
assertThat(BsonUtils.supportsBson("foo")).isFalse();
125+
assertThat(BsonUtils.supportsBson(new Document())).isTrue();
126+
assertThat(BsonUtils.supportsBson(new BasicDBList())).isTrue();
127+
assertThat(BsonUtils.supportsBson(Collections.emptyMap())).isTrue();
128+
}
114129
}

0 commit comments

Comments
 (0)