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. 70
      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;
import org.bson.Document; import org.bson.Document;
import org.bson.conversions.Bson; import org.bson.conversions.Bson;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject; import com.mongodb.DBObject;
/** /**
@ -123,28 +123,7 @@ class DocumentAccessor {
*/ */
@Nullable @Nullable
public Object get(MongoPersistentProperty property) { public Object get(MongoPersistentProperty property) {
return BsonUtils.resolveValue(document, property.getFieldName());
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;
} }
/** /**
@ -171,71 +150,7 @@ class DocumentAccessor {
Assert.notNull(property, "Property must not be null!"); Assert.notNull(property, "Property must not be null!");
String fieldName = property.getFieldName(); return BsonUtils.hasValue(document, 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;
} }
/** /**

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

@ -394,6 +394,7 @@ public class BsonUtils {
* @param bson the source to inspect. Must not be {@literal null}. * @param bson the source to inspect. Must not be {@literal null}.
* @param key the key to lookup. Must not be {@literal null}. * @param key the key to lookup. Must not be {@literal null}.
* @return can be {@literal null}. * @return can be {@literal null}.
* @since 3.0.8
*/ */
@Nullable @Nullable
public static Object resolveValue(Bson bson, String key) { public static Object resolveValue(Bson bson, String key) {
@ -410,7 +411,7 @@ public class BsonUtils {
Object result = source.get(parts[i - 1]); Object result = source.get(parts[i - 1]);
if (result == null || !(result instanceof Bson)) { if (!(result instanceof Bson)) {
return null; return null;
} }
@ -420,6 +421,73 @@ public class BsonUtils {
return source.get(parts[parts.length - 1]); 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 * 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 * {@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 {
@Test // GH-3590 @Test // GH-3590
void shouldIncludeValueFromNestedShardKeyPath() { void shouldIncludeValueFromNestedShardKeyPath() {
WithShardKeyPoitingToNested source = new WithShardKeyPoitingToNested(); WithShardKeyPointingToNested source = new WithShardKeyPointingToNested();
source.id = "id-1"; source.id = "id-1";
source.value = "v1"; source.value = "v1";
source.nested = new WithNamedFields(); source.nested = new WithNamedFields();
@ -2333,7 +2333,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
} }
@Sharded(shardKey = {"value", "nested.customName"}) @Sharded(shardKey = {"value", "nested.customName"})
static class WithShardKeyPoitingToNested { static class WithShardKeyPointingToNested {
String id; String id;
String value; String value;
WithNamedFields nested; WithNamedFields nested;

Loading…
Cancel
Save