Skip to content

Commit f386e05

Browse files
committed
Polishing.
Refine nullability declarations and NPE guards. Reformat code. See #4510 Original pull request: #4517
1 parent 37d6603 commit f386e05

File tree

4 files changed

+67
-37
lines changed

4 files changed

+67
-37
lines changed

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

+11-6
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@
3232
public class MongoConversionContext implements ValueConversionContext<MongoPersistentProperty> {
3333

3434
private final PropertyValueProvider<MongoPersistentProperty> accessor; // TODO: generics
35-
private final MongoPersistentProperty persistentProperty;
35+
private final @Nullable MongoPersistentProperty persistentProperty;
3636
private final MongoConverter mongoConverter;
3737

38-
@Nullable
39-
private final SpELContext spELContext;
38+
@Nullable private final SpELContext spELContext;
4039

4140
public MongoConversionContext(PropertyValueProvider<MongoPersistentProperty> accessor,
42-
MongoPersistentProperty persistentProperty, MongoConverter mongoConverter) {
41+
@Nullable MongoPersistentProperty persistentProperty, MongoConverter mongoConverter) {
4342
this(accessor, persistentProperty, mongoConverter, null);
4443
}
4544

4645
public MongoConversionContext(PropertyValueProvider<MongoPersistentProperty> accessor,
47-
MongoPersistentProperty persistentProperty, MongoConverter mongoConverter, @Nullable SpELContext spELContext) {
46+
@Nullable MongoPersistentProperty persistentProperty, MongoConverter mongoConverter,
47+
@Nullable SpELContext spELContext) {
4848

4949
this.accessor = accessor;
5050
this.persistentProperty = persistentProperty;
@@ -54,12 +54,17 @@ public MongoConversionContext(PropertyValueProvider<MongoPersistentProperty> acc
5454

5555
@Override
5656
public MongoPersistentProperty getProperty() {
57+
58+
if (persistentProperty == null) {
59+
throw new IllegalStateException("No underlying MongoPersistentProperty available");
60+
}
61+
5762
return persistentProperty;
5863
}
5964

6065
@Nullable
6166
public Object getValue(String propertyPath) {
62-
return accessor.getPropertyValue(persistentProperty.getOwner().getRequiredPersistentProperty(propertyPath));
67+
return accessor.getPropertyValue(getProperty().getOwner().getRequiredPersistentProperty(propertyPath));
6368
}
6469

6570
@Override

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

+49-28
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@
1515
*/
1616
package org.springframework.data.mongodb.core.convert;
1717

18-
import java.util.*;
18+
import java.util.AbstractMap;
19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.Collection;
22+
import java.util.Iterator;
23+
import java.util.LinkedHashMap;
24+
import java.util.List;
25+
import java.util.Map;
1926
import java.util.Map.Entry;
27+
import java.util.Optional;
28+
import java.util.Set;
2029
import java.util.regex.Matcher;
2130
import java.util.regex.Pattern;
2231
import java.util.stream.Collectors;
@@ -27,6 +36,7 @@
2736
import org.bson.Document;
2837
import org.bson.conversions.Bson;
2938
import org.bson.types.ObjectId;
39+
3040
import org.springframework.core.convert.ConversionService;
3141
import org.springframework.core.convert.converter.Converter;
3242
import org.springframework.data.annotation.Reference;
@@ -496,7 +506,7 @@ protected boolean isAssociationConversionNecessary(Field documentField, @Nullabl
496506

497507
Assert.notNull(documentField, "Document field must not be null");
498508

499-
if (value == null) {
509+
if (value == null || documentField.getProperty() == null) {
500510
return false;
501511
}
502512

@@ -552,10 +562,6 @@ protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersisten
552562
return getMappedObject((Document) source, entity);
553563
}
554564

555-
if (source instanceof BasicDBList) {
556-
return delegateConvertToMongoType(source, entity);
557-
}
558-
559565
if (isDBObject(source)) {
560566
return getMappedObject((BasicDBObject) source, entity);
561567
}
@@ -564,20 +570,20 @@ protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersisten
564570
return source;
565571
}
566572

567-
if (source instanceof Map<?,?> sourceMap) {
573+
if (source instanceof Map<?, ?> sourceMap) {
568574

569575
Map<String, Object> map = new LinkedHashMap<>(sourceMap.size(), 1F);
570576

571-
sourceMap.entrySet().forEach(it -> {
577+
for (Entry<?, ?> entry : sourceMap.entrySet()) {
572578

573-
String key = ObjectUtils.nullSafeToString(converter.convertToMongoType(it.getKey()));
579+
String key = ObjectUtils.nullSafeToString(converter.convertToMongoType(entry.getKey()));
574580

575-
if (it.getValue() instanceof Document document) {
581+
if (entry.getValue() instanceof Document document) {
576582
map.put(key, getMappedObject(document, entity));
577583
} else {
578-
map.put(key, delegateConvertToMongoType(it.getValue(), entity));
584+
map.put(key, delegateConvertToMongoType(entry.getValue(), entity));
579585
}
580-
});
586+
}
581587

582588
return map;
583589
}
@@ -603,6 +609,7 @@ protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersis
603609
return converter.convertToMongoType(source, entity == null ? null : entity.getTypeInformation());
604610
}
605611

612+
@Nullable
606613
protected Object convertAssociation(Object source, Field field) {
607614
Object value = convertAssociation(source, field.getProperty());
608615
if (value != null && field.isIdField() && field.getFieldType() != value.getClass()) {
@@ -627,8 +634,7 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
627634

628635
if (source instanceof DBRef ref) {
629636

630-
Object id = convertId(ref.getId(),
631-
property != null && property.isIdProperty() ? property.getFieldType() : ObjectId.class);
637+
Object id = convertId(ref.getId(), property.isIdProperty() ? property.getFieldType() : ObjectId.class);
632638

633639
if (StringUtils.hasText(ref.getDatabaseName())) {
634640
return new DBRef(ref.getDatabaseName(), ref.getCollectionName(), id);
@@ -645,9 +651,8 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
645651
return result;
646652
}
647653

648-
if (property.isMap()) {
654+
if (property.isMap() && source instanceof Document dbObject) {
649655
Document result = new Document();
650-
Document dbObject = (Document) source;
651656
for (String key : dbObject.keySet()) {
652657
result.put(key, createReferenceFor(dbObject.get(key), property));
653658
}
@@ -661,19 +666,26 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
661666
private Object convertValue(Field documentField, Object sourceValue, Object value,
662667
PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter) {
663668

664-
MongoConversionContext conversionContext = new MongoConversionContext(new PropertyValueProvider<>() {
665-
@Override
666-
public <T> T getPropertyValue(MongoPersistentProperty property) {
667-
throw new IllegalStateException("No enclosing property available");
668-
}
669-
}, documentField.getProperty(), converter);
669+
MongoPersistentProperty property = documentField.getProperty();
670+
MongoConversionContext conversionContext = new MongoConversionContext(NoPropertyPropertyValueProvider.INSTANCE,
671+
property, converter);
670672

671673
/* might be an $in clause with multiple entries */
672-
if (!documentField.getProperty().isCollectionLike() && sourceValue instanceof Collection<?> collection) {
673-
return collection.stream().map(it -> valueConverter.write(it, conversionContext)).collect(Collectors.toList());
674+
if (property != null && !property.isCollectionLike() && sourceValue instanceof Collection<?> collection) {
675+
676+
if (collection.isEmpty()) {
677+
return collection;
678+
}
679+
680+
List<Object> converted = new ArrayList<>(collection.size());
681+
for (Object o : collection) {
682+
converted.add(valueConverter.write(o, conversionContext));
683+
}
684+
685+
return converted;
674686
}
675687

676-
if (!documentField.getProperty().isMap() && sourceValue instanceof Document document) {
688+
if (property != null && !documentField.getProperty().isMap() && sourceValue instanceof Document document) {
677689

678690
return BsonUtils.mapValues(document, (key, val) -> {
679691
if (isKeyword(key)) {
@@ -687,6 +699,7 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
687699
}
688700

689701
@Nullable
702+
@SuppressWarnings("unchecked")
690703
private Object convertIdField(Field documentField, Object source) {
691704

692705
Object value = source;
@@ -714,8 +727,8 @@ private Object convertIdField(Field documentField, Object source) {
714727
} else {
715728
return getMappedObject(resultDbo, Optional.empty());
716729
}
717-
return resultDbo;
718730

731+
return resultDbo;
719732
}
720733

721734
/**
@@ -1454,15 +1467,13 @@ static class KeyMapper {
14541467

14551468
private final Iterator<String> iterator;
14561469
private int currentIndex;
1457-
private String currentPropertyRoot;
14581470
private final List<String> pathParts;
14591471

14601472
public KeyMapper(String key,
14611473
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
14621474

14631475
this.pathParts = Arrays.asList(key.split("\\."));
14641476
this.iterator = pathParts.iterator();
1465-
this.currentPropertyRoot = iterator.next();
14661477
this.currentIndex = 0;
14671478
}
14681479

@@ -1578,4 +1589,14 @@ public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentPropert
15781589
public MongoConverter getConverter() {
15791590
return converter;
15801591
}
1592+
1593+
private enum NoPropertyPropertyValueProvider implements PropertyValueProvider<MongoPersistentProperty> {
1594+
1595+
INSTANCE;
1596+
1597+
@Override
1598+
public <T> T getPropertyValue(MongoPersistentProperty property) {
1599+
throw new IllegalStateException("No enclosing property source available");
1600+
}
1601+
}
15811602
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.data.annotation.Id;
2222
import org.springframework.data.mapping.PersistentEntity;
2323
import org.springframework.data.mapping.PersistentProperty;
24+
import org.springframework.lang.NonNull;
2425
import org.springframework.lang.Nullable;
2526

2627
/**
@@ -191,6 +192,8 @@ enum PropertyToFieldNameConverter implements Converter<MongoPersistentProperty,
191192

192193
INSTANCE;
193194

195+
@NonNull
196+
@Override
194197
public String convert(MongoPersistentProperty source) {
195198
if (!source.isUnwrapped()) {
196199
return source.getFieldName();

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -723,14 +723,15 @@ public static Document mapValues(Document source, BiFunction<String, Object, Obj
723723
return mapEntries(source, Entry::getKey, entry -> valueMapper.apply(entry.getKey(), entry.getValue()));
724724
}
725725

726-
public static Document mapEntries(Document source, Function<Entry<String,Object>,String> keyMapper, Function<Entry<String,Object>,Object> valueMapper) {
726+
public static Document mapEntries(Document source, Function<Entry<String, Object>, String> keyMapper,
727+
Function<Entry<String, Object>, Object> valueMapper) {
727728

728-
if(source.isEmpty()) {
729+
if (source.isEmpty()) {
729730
return source;
730731
}
731732

732733
Map<String, Object> target = new LinkedHashMap<>(source.size(), 1f);
733-
for(Entry<String,Object> entry : source.entrySet()) {
734+
for (Entry<String, Object> entry : source.entrySet()) {
734735
target.put(keyMapper.apply(entry), valueMapper.apply(entry));
735736
}
736737
return new Document(target);

0 commit comments

Comments
 (0)