Skip to content

Commit 78137c8

Browse files
committed
Polishing.
Move hasValue(…) from DocumentAccessor to BsonUtils. Fix typo in tests. See: #3590 Original pull request: #3591.
1 parent 8033b05 commit 78137c8

File tree

3 files changed

+75
-92
lines changed

3 files changed

+75
-92
lines changed

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

Lines changed: 3 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121

2222
import org.bson.Document;
2323
import org.bson.conversions.Bson;
24+
2425
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
2526
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
2627
import org.springframework.data.mongodb.util.BsonUtils;
2728
import org.springframework.lang.Nullable;
2829
import org.springframework.util.Assert;
2930

30-
import com.mongodb.BasicDBObject;
3131
import com.mongodb.DBObject;
3232

3333
/**
@@ -123,28 +123,7 @@ public void put(MongoPersistentProperty prop, @Nullable Object value) {
123123
*/
124124
@Nullable
125125
public Object get(MongoPersistentProperty property) {
126-
127-
String fieldName = property.getFieldName();
128-
Map<String, Object> map = BsonUtils.asMap(document);
129-
130-
if (!fieldName.contains(".")) {
131-
return map.get(fieldName);
132-
}
133-
134-
Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
135-
Map<String, Object> source = map;
136-
Object result = null;
137-
138-
while (source != null && parts.hasNext()) {
139-
140-
result = source.get(parts.next());
141-
142-
if (parts.hasNext()) {
143-
source = getAsMap(result);
144-
}
145-
}
146-
147-
return result;
126+
return BsonUtils.resolveValue(document, property.getFieldName());
148127
}
149128

150129
/**
@@ -171,71 +150,7 @@ public boolean hasValue(MongoPersistentProperty property) {
171150

172151
Assert.notNull(property, "Property must not be null!");
173152

174-
String fieldName = property.getFieldName();
175-
176-
177-
if (this.document instanceof Document) {
178-
179-
if (((Document) this.document).containsKey(fieldName)) {
180-
return true;
181-
}
182-
} else if (this.document instanceof DBObject) {
183-
if (((DBObject) this.document).containsField(fieldName)) {
184-
return true;
185-
}
186-
}
187-
188-
if (!fieldName.contains(".")) {
189-
return false;
190-
}
191-
192-
String[] parts = fieldName.split("\\.");
193-
Map<String, Object> source;
194-
195-
if (this.document instanceof Document) {
196-
source = ((Document) this.document);
197-
} else {
198-
source = ((DBObject) this.document).toMap();
199-
}
200-
201-
Object result = null;
202-
203-
for (int i = 1; i < parts.length; i++) {
204-
205-
result = source.get(parts[i - 1]);
206-
source = getAsMap(result);
207-
208-
if (source == null) {
209-
return false;
210-
}
211-
}
212-
213-
return source.containsKey(parts[parts.length - 1]);
214-
}
215-
216-
/**
217-
* Returns the given source object as map, i.e. {@link Document}s and maps as is or {@literal null} otherwise.
218-
*
219-
* @param source can be {@literal null}.
220-
* @return can be {@literal null}.
221-
*/
222-
@Nullable
223-
@SuppressWarnings("unchecked")
224-
private static Map<String, Object> getAsMap(Object source) {
225-
226-
if (source instanceof Document) {
227-
return (Document) source;
228-
}
229-
230-
if (source instanceof BasicDBObject) {
231-
return (BasicDBObject) source;
232-
}
233-
234-
if (source instanceof Map) {
235-
return (Map<String, Object>) source;
236-
}
237-
238-
return null;
153+
return BsonUtils.hasValue(document, property.getFieldName());
239154
}
240155

241156
/**

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

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,11 @@ public static Document parse(String json, @Nullable CodecRegistryProvider codecR
390390
* returned. If not and the key contains a path using the dot ({@code .}) notation it will try to resolve the path by
391391
* inspecting the individual parts. If one of the intermediate ones is {@literal null} or cannot be inspected further
392392
* (wrong) type, {@literal null} is returned.
393-
*
393+
*
394394
* @param bson the source to inspect. Must not be {@literal null}.
395395
* @param key the key to lookup. Must not be {@literal null}.
396396
* @return can be {@literal null}.
397+
* @since 3.0.8
397398
*/
398399
@Nullable
399400
public static Object resolveValue(Bson bson, String key) {
@@ -410,7 +411,7 @@ public static Object resolveValue(Bson bson, String key) {
410411

411412
Object result = source.get(parts[i - 1]);
412413

413-
if (result == null || !(result instanceof Bson)) {
414+
if (!(result instanceof Bson)) {
414415
return null;
415416
}
416417

@@ -420,6 +421,73 @@ public static Object resolveValue(Bson bson, String key) {
420421
return source.get(parts[parts.length - 1]);
421422
}
422423

424+
/**
425+
* Returns whether the underlying {@link Bson bson} has a value ({@literal null} or non-{@literal null}) for the given
426+
* {@code key}.
427+
*
428+
* @param bson the source to inspect. Must not be {@literal null}.
429+
* @param key the key to lookup. Must not be {@literal null}.
430+
* @return {@literal true} if no non {@literal null} value present.
431+
* @since 3.0.8
432+
*/
433+
public static boolean hasValue(Bson bson, String key) {
434+
435+
Map<String, Object> source = asMap(bson);
436+
437+
if (source.get(key) != null) {
438+
return true;
439+
}
440+
441+
if (!key.contains(".")) {
442+
return false;
443+
}
444+
445+
String[] parts = key.split("\\.");
446+
447+
Object result;
448+
449+
for (int i = 1; i < parts.length; i++) {
450+
451+
result = source.get(parts[i - 1]);
452+
source = getAsMap(result);
453+
454+
if (source == null) {
455+
return false;
456+
}
457+
}
458+
459+
return source.containsKey(parts[parts.length - 1]);
460+
}
461+
462+
/**
463+
* Returns the given source object as map, i.e. {@link Document}s and maps as is or {@literal null} otherwise.
464+
*
465+
* @param source can be {@literal null}.
466+
* @return can be {@literal null}.
467+
*/
468+
@Nullable
469+
@SuppressWarnings("unchecked")
470+
private static Map<String, Object> getAsMap(Object source) {
471+
472+
if (source instanceof Document) {
473+
return (Document) source;
474+
}
475+
476+
if (source instanceof BasicDBObject) {
477+
return (BasicDBObject) source;
478+
}
479+
480+
if (source instanceof DBObject) {
481+
return ((DBObject) source).toMap();
482+
}
483+
484+
if (source instanceof Map) {
485+
return (Map<String, Object>) source;
486+
}
487+
488+
return null;
489+
}
490+
423491
/**
424492
* Returns given object as {@link Collection}. Will return the {@link Collection} as is if the source is a
425493
* {@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/MongoTemplateUnitTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ void saveShouldAppendDefaultShardKeyIfNotPresentInFilter() {
19581958
@Test // GH-3590
19591959
void shouldIncludeValueFromNestedShardKeyPath() {
19601960

1961-
WithShardKeyPoitingToNested source = new WithShardKeyPoitingToNested();
1961+
WithShardKeyPointingToNested source = new WithShardKeyPointingToNested();
19621962
source.id = "id-1";
19631963
source.value = "v1";
19641964
source.nested = new WithNamedFields();
@@ -2333,7 +2333,7 @@ static class Sith {
23332333
}
23342334

23352335
@Sharded(shardKey = {"value", "nested.customName"})
2336-
static class WithShardKeyPoitingToNested {
2336+
static class WithShardKeyPointingToNested {
23372337
String id;
23382338
String value;
23392339
WithNamedFields nested;

0 commit comments

Comments
 (0)