Skip to content

Commit af4b178

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

File tree

3 files changed

+74
-92
lines changed

3 files changed

+74
-92
lines changed

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

+3-89
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,16 @@
1717

1818
import java.util.Arrays;
1919
import java.util.Iterator;
20-
import java.util.Map;
2120

2221
import org.bson.Document;
2322
import org.bson.conversions.Bson;
23+
2424
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
2525
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
2626
import org.springframework.data.mongodb.util.BsonUtils;
2727
import org.springframework.lang.Nullable;
2828
import org.springframework.util.Assert;
2929

30-
import com.mongodb.BasicDBObject;
3130
import com.mongodb.DBObject;
3231

3332
/**
@@ -110,28 +109,7 @@ public void put(MongoPersistentProperty prop, @Nullable Object value) {
110109
*/
111110
@Nullable
112111
public Object get(MongoPersistentProperty property) {
113-
114-
String fieldName = property.getFieldName();
115-
Map<String, Object> map = BsonUtils.asMap(document);
116-
117-
if (!fieldName.contains(".")) {
118-
return map.get(fieldName);
119-
}
120-
121-
Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
122-
Map<String, Object> source = map;
123-
Object result = null;
124-
125-
while (source != null && parts.hasNext()) {
126-
127-
result = source.get(parts.next());
128-
129-
if (parts.hasNext()) {
130-
source = getAsMap(result);
131-
}
132-
}
133-
134-
return result;
112+
return BsonUtils.resolveValue(document, property.getFieldName());
135113
}
136114

137115
/**
@@ -157,71 +135,7 @@ public boolean hasValue(MongoPersistentProperty property) {
157135

158136
Assert.notNull(property, "Property must not be null!");
159137

160-
String fieldName = property.getFieldName();
161-
162-
163-
if (this.document instanceof Document) {
164-
165-
if (((Document) this.document).containsKey(fieldName)) {
166-
return true;
167-
}
168-
} else if (this.document instanceof DBObject) {
169-
if (((DBObject) this.document).containsField(fieldName)) {
170-
return true;
171-
}
172-
}
173-
174-
if (!fieldName.contains(".")) {
175-
return false;
176-
}
177-
178-
String[] parts = fieldName.split("\\.");
179-
Map<String, Object> source;
180-
181-
if (this.document instanceof Document) {
182-
source = ((Document) this.document);
183-
} else {
184-
source = ((DBObject) this.document).toMap();
185-
}
186-
187-
Object result = null;
188-
189-
for (int i = 1; i < parts.length; i++) {
190-
191-
result = source.get(parts[i - 1]);
192-
source = getAsMap(result);
193-
194-
if (source == null) {
195-
return false;
196-
}
197-
}
198-
199-
return source.containsKey(parts[parts.length - 1]);
200-
}
201-
202-
/**
203-
* Returns the given source object as map, i.e. {@link Document}s and maps as is or {@literal null} otherwise.
204-
*
205-
* @param source can be {@literal null}.
206-
* @return can be {@literal null}.
207-
*/
208-
@Nullable
209-
@SuppressWarnings("unchecked")
210-
private static Map<String, Object> getAsMap(Object source) {
211-
212-
if (source instanceof Document) {
213-
return (Document) source;
214-
}
215-
216-
if (source instanceof BasicDBObject) {
217-
return (BasicDBObject) source;
218-
}
219-
220-
if (source instanceof Map) {
221-
return (Map<String, Object>) source;
222-
}
223-
224-
return null;
138+
return BsonUtils.hasValue(document, property.getFieldName());
225139
}
226140

227141
/**

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

+69-1
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ public static Document parse(String json, @Nullable CodecRegistryProvider codecR
291291
* @param bson the source to inspect. Must not be {@literal null}.
292292
* @param key the key to lookup. Must not be {@literal null}.
293293
* @return can be {@literal null}.
294+
* @since 3.0.8
294295
*/
295296
@Nullable
296297
public static Object resolveValue(Bson bson, String key) {
@@ -307,7 +308,7 @@ public static Object resolveValue(Bson bson, String key) {
307308

308309
Object result = source.get(parts[i - 1]);
309310

310-
if (result == null || !(result instanceof Bson)) {
311+
if (!(result instanceof Bson)) {
311312
return null;
312313
}
313314

@@ -317,6 +318,73 @@ public static Object resolveValue(Bson bson, String key) {
317318
return source.get(parts[parts.length - 1]);
318319
}
319320

321+
/**
322+
* Returns whether the underlying {@link Bson bson} has a value ({@literal null} or non-{@literal null}) for the given
323+
* {@code key}.
324+
*
325+
* @param bson the source to inspect. Must not be {@literal null}.
326+
* @param key the key to lookup. Must not be {@literal null}.
327+
* @return {@literal true} if no non {@literal null} value present.
328+
* @since 3.0.8
329+
*/
330+
public static boolean hasValue(Bson bson, String key) {
331+
332+
Map<String, Object> source = asMap(bson);
333+
334+
if (source.get(key) != null) {
335+
return true;
336+
}
337+
338+
if (!key.contains(".")) {
339+
return false;
340+
}
341+
342+
String[] parts = key.split("\\.");
343+
344+
Object result;
345+
346+
for (int i = 1; i < parts.length; i++) {
347+
348+
result = source.get(parts[i - 1]);
349+
source = getAsMap(result);
350+
351+
if (source == null) {
352+
return false;
353+
}
354+
}
355+
356+
return source.containsKey(parts[parts.length - 1]);
357+
}
358+
359+
/**
360+
* Returns the given source object as map, i.e. {@link Document}s and maps as is or {@literal null} otherwise.
361+
*
362+
* @param source can be {@literal null}.
363+
* @return can be {@literal null}.
364+
*/
365+
@Nullable
366+
@SuppressWarnings("unchecked")
367+
private static Map<String, Object> getAsMap(Object source) {
368+
369+
if (source instanceof Document) {
370+
return (Document) source;
371+
}
372+
373+
if (source instanceof BasicDBObject) {
374+
return (BasicDBObject) source;
375+
}
376+
377+
if (source instanceof DBObject) {
378+
return ((DBObject) source).toMap();
379+
}
380+
381+
if (source instanceof Map) {
382+
return (Map<String, Object>) source;
383+
}
384+
385+
return null;
386+
}
387+
320388
@Nullable
321389
private static String toJson(@Nullable Object value) {
322390

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1914,7 +1914,7 @@ void saveShouldAppendDefaultShardKeyIfNotPresentInFilter() {
19141914
@Test // GH-3590
19151915
void shouldIncludeValueFromNestedShardKeyPath() {
19161916

1917-
WithShardKeyPoitingToNested source = new WithShardKeyPoitingToNested();
1917+
WithShardKeyPointingToNested source = new WithShardKeyPointingToNested();
19181918
source.id = "id-1";
19191919
source.value = "v1";
19201920
source.nested = new WithNamedFields();
@@ -2266,7 +2266,7 @@ static class Sith {
22662266
}
22672267

22682268
@Sharded(shardKey = {"value", "nested.customName"})
2269-
static class WithShardKeyPoitingToNested {
2269+
static class WithShardKeyPointingToNested {
22702270
String id;
22712271
String value;
22722272
WithNamedFields nested;

0 commit comments

Comments
 (0)