Browse Source

Polishing.

Move hasValue(…) from DocumentAccessor to BsonUtils. Fix typo in tests.

See: #3590
Original pull request: #3591.
pull/3585/head
Mark Paluch 5 years ago
parent
commit
78137c882d
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 91
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java
  2. 72
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java
  3. 4
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java

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

@ -21,13 +21,13 @@ import java.util.Map; @@ -21,13 +21,13 @@ import java.util.Map;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
@ -123,28 +123,7 @@ class DocumentAccessor { @@ -123,28 +123,7 @@ class DocumentAccessor {
*/
@Nullable
public Object get(MongoPersistentProperty property) {
String fieldName = property.getFieldName();
Map<String, Object> map = BsonUtils.asMap(document);
if (!fieldName.contains(".")) {
return map.get(fieldName);
}
Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
Map<String, Object> source = map;
Object result = null;
while (source != null && parts.hasNext()) {
result = source.get(parts.next());
if (parts.hasNext()) {
source = getAsMap(result);
}
}
return result;
return BsonUtils.resolveValue(document, property.getFieldName());
}
/**
@ -171,71 +150,7 @@ class DocumentAccessor { @@ -171,71 +150,7 @@ class DocumentAccessor {
Assert.notNull(property, "Property must not be null!");
String fieldName = property.getFieldName();
if (this.document instanceof Document) {
if (((Document) this.document).containsKey(fieldName)) {
return true;
}
} else if (this.document instanceof DBObject) {
if (((DBObject) this.document).containsField(fieldName)) {
return true;
}
}
if (!fieldName.contains(".")) {
return false;
}
String[] parts = fieldName.split("\\.");
Map<String, Object> source;
if (this.document instanceof Document) {
source = ((Document) this.document);
} else {
source = ((DBObject) this.document).toMap();
}
Object result = null;
for (int i = 1; i < parts.length; i++) {
result = source.get(parts[i - 1]);
source = getAsMap(result);
if (source == null) {
return false;
}
}
return source.containsKey(parts[parts.length - 1]);
}
/**
* Returns the given source object as map, i.e. {@link Document}s and maps as is or {@literal null} otherwise.
*
* @param source can be {@literal null}.
* @return can be {@literal null}.
*/
@Nullable
@SuppressWarnings("unchecked")
private static Map<String, Object> getAsMap(Object source) {
if (source instanceof Document) {
return (Document) source;
}
if (source instanceof BasicDBObject) {
return (BasicDBObject) source;
}
if (source instanceof Map) {
return (Map<String, Object>) source;
}
return null;
return BsonUtils.hasValue(document, property.getFieldName());
}
/**

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

@ -390,10 +390,11 @@ public class BsonUtils { @@ -390,10 +390,11 @@ public class BsonUtils {
* returned. If not and the key contains a path using the dot ({@code .}) notation it will try to resolve the path by
* inspecting the individual parts. If one of the intermediate ones is {@literal null} or cannot be inspected further
* (wrong) type, {@literal null} is returned.
*
*
* @param bson the source to inspect. Must not be {@literal null}.
* @param key the key to lookup. Must not be {@literal null}.
* @return can be {@literal null}.
* @since 3.0.8
*/
@Nullable
public static Object resolveValue(Bson bson, String key) {
@ -410,7 +411,7 @@ public class BsonUtils { @@ -410,7 +411,7 @@ public class BsonUtils {
Object result = source.get(parts[i - 1]);
if (result == null || !(result instanceof Bson)) {
if (!(result instanceof Bson)) {
return null;
}
@ -420,6 +421,73 @@ public class BsonUtils { @@ -420,6 +421,73 @@ public class BsonUtils {
return source.get(parts[parts.length - 1]);
}
/**
* Returns whether the underlying {@link Bson bson} has a value ({@literal null} or non-{@literal null}) for the given
* {@code key}.
*
* @param bson the source to inspect. Must not be {@literal null}.
* @param key the key to lookup. Must not be {@literal null}.
* @return {@literal true} if no non {@literal null} value present.
* @since 3.0.8
*/
public static boolean hasValue(Bson bson, String key) {
Map<String, Object> source = asMap(bson);
if (source.get(key) != null) {
return true;
}
if (!key.contains(".")) {
return false;
}
String[] parts = key.split("\\.");
Object result;
for (int i = 1; i < parts.length; i++) {
result = source.get(parts[i - 1]);
source = getAsMap(result);
if (source == null) {
return false;
}
}
return source.containsKey(parts[parts.length - 1]);
}
/**
* Returns the given source object as map, i.e. {@link Document}s and maps as is or {@literal null} otherwise.
*
* @param source can be {@literal null}.
* @return can be {@literal null}.
*/
@Nullable
@SuppressWarnings("unchecked")
private static Map<String, Object> getAsMap(Object source) {
if (source instanceof Document) {
return (Document) source;
}
if (source instanceof BasicDBObject) {
return (BasicDBObject) source;
}
if (source instanceof DBObject) {
return ((DBObject) source).toMap();
}
if (source instanceof Map) {
return (Map<String, Object>) source;
}
return null;
}
/**
* 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

4
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java

@ -1958,7 +1958,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { @@ -1958,7 +1958,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
@Test // GH-3590
void shouldIncludeValueFromNestedShardKeyPath() {
WithShardKeyPoitingToNested source = new WithShardKeyPoitingToNested();
WithShardKeyPointingToNested source = new WithShardKeyPointingToNested();
source.id = "id-1";
source.value = "v1";
source.nested = new WithNamedFields();
@ -2333,7 +2333,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { @@ -2333,7 +2333,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
}
@Sharded(shardKey = {"value", "nested.customName"})
static class WithShardKeyPoitingToNested {
static class WithShardKeyPointingToNested {
String id;
String value;
WithNamedFields nested;

Loading…
Cancel
Save