Skip to content

Commit 595a346

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 08c5e5a commit 595a346

File tree

4 files changed

+67
-11
lines changed

4 files changed

+67
-11
lines changed

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

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

19111911
if(ClassUtils.isAssignable(Document.class, typeHint.getType())) {
1912-
return (S) documentConverter.convert(this, (Bson) source, typeHint);
1912+
return (S) documentConverter.convert(this, BsonUtils.asBson(source), typeHint);
19131913
}
19141914

1915-
if(source instanceof Bson) {
1916-
return (S) mapConverter.convert(this, (Bson) source, typeHint);
1917-
}
1918-
if(source instanceof Map) {
1919-
return (S) mapConverter.convert(this, new Document((Map<String,Object>) source), typeHint);
1915+
if (BsonUtils.supportsBson(source)) {
1916+
return (S) mapConverter.convert(this, BsonUtils.asBson(source), typeHint);
19201917
}
19211918

19221919
throw new IllegalArgumentException(String.format("Expected map like structure but found %s", source.getClass()));
@@ -1931,8 +1928,8 @@ public <S extends Object> S convert(Object source, TypeInformation<? extends S>
19311928
String.format(INCOMPATIBLE_TYPES, source, BasicDBList.class, typeHint.getType(), getPath()));
19321929
}
19331930

1934-
if (source instanceof Bson) {
1935-
return (S) documentConverter.convert(this, (Bson) source, typeHint);
1931+
if (BsonUtils.supportsBson(source)) {
1932+
return (S) documentConverter.convert(this, BsonUtils.asBson(source), typeHint);
19361933
}
19371934

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

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

+43
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,49 @@ private static Map<String, Object> getAsMap(Object source) {
488488
return null;
489489
}
490490

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

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();

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)