Polishing.

Refine nullability declarations and NPE guards. Reformat code.

See #4510
Original pull request: #4517
This commit is contained in:
Mark Paluch
2024-02-12 09:48:26 +01:00
parent 37d66034f8
commit f386e05b8f
4 changed files with 67 additions and 37 deletions

View File

@@ -32,19 +32,19 @@ import org.springframework.lang.Nullable;
public class MongoConversionContext implements ValueConversionContext<MongoPersistentProperty> {
private final PropertyValueProvider<MongoPersistentProperty> accessor; // TODO: generics
private final MongoPersistentProperty persistentProperty;
private final @Nullable MongoPersistentProperty persistentProperty;
private final MongoConverter mongoConverter;
@Nullable
private final SpELContext spELContext;
@Nullable private final SpELContext spELContext;
public MongoConversionContext(PropertyValueProvider<MongoPersistentProperty> accessor,
MongoPersistentProperty persistentProperty, MongoConverter mongoConverter) {
@Nullable MongoPersistentProperty persistentProperty, MongoConverter mongoConverter) {
this(accessor, persistentProperty, mongoConverter, null);
}
public MongoConversionContext(PropertyValueProvider<MongoPersistentProperty> accessor,
MongoPersistentProperty persistentProperty, MongoConverter mongoConverter, @Nullable SpELContext spELContext) {
@Nullable MongoPersistentProperty persistentProperty, MongoConverter mongoConverter,
@Nullable SpELContext spELContext) {
this.accessor = accessor;
this.persistentProperty = persistentProperty;
@@ -54,12 +54,17 @@ public class MongoConversionContext implements ValueConversionContext<MongoPersi
@Override
public MongoPersistentProperty getProperty() {
if (persistentProperty == null) {
throw new IllegalStateException("No underlying MongoPersistentProperty available");
}
return persistentProperty;
}
@Nullable
public Object getValue(String propertyPath) {
return accessor.getPropertyValue(persistentProperty.getOwner().getRequiredPersistentProperty(propertyPath));
return accessor.getPropertyValue(getProperty().getOwner().getRequiredPersistentProperty(propertyPath));
}
@Override

View File

@@ -15,8 +15,17 @@
*/
package org.springframework.data.mongodb.core.convert;
import java.util.*;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -27,6 +36,7 @@ import org.bson.BsonValue;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Reference;
@@ -496,7 +506,7 @@ public class QueryMapper {
Assert.notNull(documentField, "Document field must not be null");
if (value == null) {
if (value == null || documentField.getProperty() == null) {
return false;
}
@@ -552,10 +562,6 @@ public class QueryMapper {
return getMappedObject((Document) source, entity);
}
if (source instanceof BasicDBList) {
return delegateConvertToMongoType(source, entity);
}
if (isDBObject(source)) {
return getMappedObject((BasicDBObject) source, entity);
}
@@ -564,20 +570,20 @@ public class QueryMapper {
return source;
}
if (source instanceof Map<?,?> sourceMap) {
if (source instanceof Map<?, ?> sourceMap) {
Map<String, Object> map = new LinkedHashMap<>(sourceMap.size(), 1F);
sourceMap.entrySet().forEach(it -> {
for (Entry<?, ?> entry : sourceMap.entrySet()) {
String key = ObjectUtils.nullSafeToString(converter.convertToMongoType(it.getKey()));
String key = ObjectUtils.nullSafeToString(converter.convertToMongoType(entry.getKey()));
if (it.getValue() instanceof Document document) {
if (entry.getValue() instanceof Document document) {
map.put(key, getMappedObject(document, entity));
} else {
map.put(key, delegateConvertToMongoType(it.getValue(), entity));
map.put(key, delegateConvertToMongoType(entry.getValue(), entity));
}
});
}
return map;
}
@@ -603,6 +609,7 @@ public class QueryMapper {
return converter.convertToMongoType(source, entity == null ? null : entity.getTypeInformation());
}
@Nullable
protected Object convertAssociation(Object source, Field field) {
Object value = convertAssociation(source, field.getProperty());
if (value != null && field.isIdField() && field.getFieldType() != value.getClass()) {
@@ -627,8 +634,7 @@ public class QueryMapper {
if (source instanceof DBRef ref) {
Object id = convertId(ref.getId(),
property != null && property.isIdProperty() ? property.getFieldType() : ObjectId.class);
Object id = convertId(ref.getId(), property.isIdProperty() ? property.getFieldType() : ObjectId.class);
if (StringUtils.hasText(ref.getDatabaseName())) {
return new DBRef(ref.getDatabaseName(), ref.getCollectionName(), id);
@@ -645,9 +651,8 @@ public class QueryMapper {
return result;
}
if (property.isMap()) {
if (property.isMap() && source instanceof Document dbObject) {
Document result = new Document();
Document dbObject = (Document) source;
for (String key : dbObject.keySet()) {
result.put(key, createReferenceFor(dbObject.get(key), property));
}
@@ -661,19 +666,26 @@ public class QueryMapper {
private Object convertValue(Field documentField, Object sourceValue, Object value,
PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter) {
MongoConversionContext conversionContext = new MongoConversionContext(new PropertyValueProvider<>() {
@Override
public <T> T getPropertyValue(MongoPersistentProperty property) {
throw new IllegalStateException("No enclosing property available");
}
}, documentField.getProperty(), converter);
MongoPersistentProperty property = documentField.getProperty();
MongoConversionContext conversionContext = new MongoConversionContext(NoPropertyPropertyValueProvider.INSTANCE,
property, converter);
/* might be an $in clause with multiple entries */
if (!documentField.getProperty().isCollectionLike() && sourceValue instanceof Collection<?> collection) {
return collection.stream().map(it -> valueConverter.write(it, conversionContext)).collect(Collectors.toList());
if (property != null && !property.isCollectionLike() && sourceValue instanceof Collection<?> collection) {
if (collection.isEmpty()) {
return collection;
}
List<Object> converted = new ArrayList<>(collection.size());
for (Object o : collection) {
converted.add(valueConverter.write(o, conversionContext));
}
return converted;
}
if (!documentField.getProperty().isMap() && sourceValue instanceof Document document) {
if (property != null && !documentField.getProperty().isMap() && sourceValue instanceof Document document) {
return BsonUtils.mapValues(document, (key, val) -> {
if (isKeyword(key)) {
@@ -687,6 +699,7 @@ public class QueryMapper {
}
@Nullable
@SuppressWarnings("unchecked")
private Object convertIdField(Field documentField, Object source) {
Object value = source;
@@ -714,8 +727,8 @@ public class QueryMapper {
} else {
return getMappedObject(resultDbo, Optional.empty());
}
return resultDbo;
return resultDbo;
}
/**
@@ -1454,7 +1467,6 @@ public class QueryMapper {
private final Iterator<String> iterator;
private int currentIndex;
private String currentPropertyRoot;
private final List<String> pathParts;
public KeyMapper(String key,
@@ -1462,7 +1474,6 @@ public class QueryMapper {
this.pathParts = Arrays.asList(key.split("\\."));
this.iterator = pathParts.iterator();
this.currentPropertyRoot = iterator.next();
this.currentIndex = 0;
}
@@ -1578,4 +1589,14 @@ public class QueryMapper {
public MongoConverter getConverter() {
return converter;
}
private enum NoPropertyPropertyValueProvider implements PropertyValueProvider<MongoPersistentProperty> {
INSTANCE;
@Override
public <T> T getPropertyValue(MongoPersistentProperty property) {
throw new IllegalStateException("No enclosing property source available");
}
}
}

View File

@@ -21,6 +21,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
/**
@@ -191,6 +192,8 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
INSTANCE;
@NonNull
@Override
public String convert(MongoPersistentProperty source) {
if (!source.isUnwrapped()) {
return source.getFieldName();

View File

@@ -723,14 +723,15 @@ public class BsonUtils {
return mapEntries(source, Entry::getKey, entry -> valueMapper.apply(entry.getKey(), entry.getValue()));
}
public static Document mapEntries(Document source, Function<Entry<String,Object>,String> keyMapper, Function<Entry<String,Object>,Object> valueMapper) {
public static Document mapEntries(Document source, Function<Entry<String, Object>, String> keyMapper,
Function<Entry<String, Object>, Object> valueMapper) {
if(source.isEmpty()) {
if (source.isEmpty()) {
return source;
}
Map<String, Object> target = new LinkedHashMap<>(source.size(), 1f);
for(Entry<String,Object> entry : source.entrySet()) {
for (Entry<String, Object> entry : source.entrySet()) {
target.put(keyMapper.apply(entry), valueMapper.apply(entry));
}
return new Document(target);