DATACMNS-1114 - Introduced usage of nullable annotations for API validation.
Marked all packages with Spring Frameworks @NonNullApi. Added Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapted using code to make sure the IDE can evaluate the null flow properly. Fixed Javadoc in places where an invalid null handling policy was advertised. Strengthened null requirements for types that expose null-instances. Removed null handling from converters for JodaTime and ThreeTenBP. Introduced factory methods Page.empty() and Page.empty(Pageable). Introduced default methods getRequiredGetter(), …Setter() and …Field() on PersistentProperty to allow non-nullable lookups of members. The same for TypeInformation.getrequiredActualType(), …SuperTypeInformation(). Tweaked PersistentPropertyCreator.addPropertiesForRemainingDescriptors() to filter unsuitable PropertyDescriptors before actually trying to create a Property instance from them as the new stronger nullability requirements would cause exceptions downstream. Lazy.get() now expects a non-null return value. Clients being able to cope with null need to call ….orElse(…). Original pull request: #232.
This commit is contained in:
@@ -56,6 +56,7 @@ public class QSort extends Sort implements Serializable {
|
||||
*
|
||||
* @param orderSpecifiers must not be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public QSort(List<OrderSpecifier<?>> orderSpecifiers) {
|
||||
|
||||
super(toOrders(orderSpecifiers));
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.querydsl;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.querydsl.core.types.Path;
|
||||
@@ -52,7 +53,7 @@ public class QuerydslUtils {
|
||||
* @param tail must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private static String toDotPath(Path<?> path, String tail) {
|
||||
private static String toDotPath(@Nullable Path<?> path, String tail) {
|
||||
|
||||
if (path == null) {
|
||||
return tail;
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.beans.PropertyDescriptor;
|
||||
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.querydsl.EntityPathResolver;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.querydsl.core.types.Path;
|
||||
|
||||
@@ -56,6 +57,7 @@ interface PathInformation {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
PropertyDescriptor getLeafPropertyDescriptor();
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.querydsl.EntityPathResolver;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.querydsl.core.types.Path;
|
||||
@@ -69,45 +70,46 @@ class PropertyPathInformation implements PathInformation {
|
||||
return PropertyPathInformation.of(PropertyPath.from(path, type));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.querydsl.binding.MappedPath#getLeafType()
|
||||
* @see org.springframework.data.querydsl.binding.PathInformation#getLeafType()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getLeafType() {
|
||||
return path.getLeafProperty().getType();
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.querydsl.binding.MappedPath#getLeafParentType()
|
||||
* @see org.springframework.data.querydsl.binding.PathInformation#getLeafParentType()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getLeafParentType() {
|
||||
return path.getLeafProperty().getOwningType().getType();
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.querydsl.binding.MappedPath#getLeafProperty()
|
||||
* @see org.springframework.data.querydsl.binding.PathInformation#getLeafProperty()
|
||||
*/
|
||||
@Override
|
||||
public String getLeafProperty() {
|
||||
return path.getLeafProperty().getSegment();
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.querydsl.binding.MappedPath#getLeafPropertyDescriptor()
|
||||
* @see org.springframework.data.querydsl.binding.PathInformation#getLeafPropertyDescriptor()
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public PropertyDescriptor getLeafPropertyDescriptor() {
|
||||
return BeanUtils.getPropertyDescriptor(getLeafParentType(), getLeafProperty());
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.querydsl.binding.MappedPath#toDotPath()
|
||||
* @see org.springframework.data.querydsl.binding.PathInformation#toDotPath()
|
||||
*/
|
||||
@Override
|
||||
public String toDotPath() {
|
||||
@@ -125,8 +127,7 @@ class PropertyPathInformation implements PathInformation {
|
||||
|
||||
private static Path<?> reifyPath(EntityPathResolver resolver, PropertyPath path, Optional<Path<?>> base) {
|
||||
|
||||
Optional<Path<?>> map = base.filter(it -> it instanceof CollectionPathBase)
|
||||
.map(CollectionPathBase.class::cast)//
|
||||
Optional<Path<?>> map = base.filter(it -> it instanceof CollectionPathBase).map(CollectionPathBase.class::cast)//
|
||||
.map(CollectionPathBase::any)//
|
||||
.map(Path.class::cast)//
|
||||
.map(it -> reifyPath(resolver, path, Optional.of(it)));
|
||||
@@ -135,11 +136,14 @@ class PropertyPathInformation implements PathInformation {
|
||||
|
||||
Path<?> entityPath = base.orElseGet(() -> resolver.createPath(path.getOwningType().getType()));
|
||||
|
||||
Field field = ReflectionUtils.findField(entityPath.getClass(), path.getSegment());
|
||||
Field field = org.springframework.data.util.ReflectionUtils.findRequiredField(entityPath.getClass(),
|
||||
path.getSegment());
|
||||
Object value = ReflectionUtils.getField(field, entityPath);
|
||||
|
||||
if (path.hasNext()) {
|
||||
return reifyPath(resolver, path.next(), Optional.of((Path<?>) value));
|
||||
PropertyPath next = path.next();
|
||||
|
||||
if (next != null) {
|
||||
return reifyPath(resolver, next, Optional.of((Path<?>) value));
|
||||
}
|
||||
|
||||
return (Path<?>) value;
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.data.mapping.PropertyReferenceException;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.Optionals;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -239,6 +240,7 @@ public class QuerydslBindings {
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
PathInformation getPropertyPath(String path, TypeInformation<?> type) {
|
||||
|
||||
Assert.notNull(path, "Path must not be null!");
|
||||
@@ -316,8 +318,18 @@ public class QuerydslBindings {
|
||||
* @return
|
||||
*/
|
||||
private static String toDotPath(Optional<Path<?>> path) {
|
||||
return path.map(it -> it.toString().substring(it.getMetadata().getRootPath().getMetadata().getName().length() + 1))
|
||||
.orElse("");
|
||||
return path.map(QuerydslBindings::fromRootPath).orElse("");
|
||||
}
|
||||
|
||||
private static String fromRootPath(Path<?> path) {
|
||||
|
||||
Path<?> rootPath = path.getMetadata().getRootPath();
|
||||
|
||||
if (rootPath == null) {
|
||||
throw new IllegalStateException(String.format("Couldn't find root path on path %s!", path));
|
||||
}
|
||||
|
||||
return path.toString().substring(rootPath.getMetadata().getName().length() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,7 +398,7 @@ public class QuerydslBindings {
|
||||
*/
|
||||
public class AliasingPathBinder<P extends Path<? extends T>, T> extends PathBinder<P, T> {
|
||||
|
||||
private final String alias;
|
||||
private final @Nullable String alias;
|
||||
private final P path;
|
||||
|
||||
/**
|
||||
@@ -404,7 +416,7 @@ public class QuerydslBindings {
|
||||
* @param alias can be {@literal null}.
|
||||
* @param path must not be {@literal null}.
|
||||
*/
|
||||
private AliasingPathBinder(String alias, P path) {
|
||||
private AliasingPathBinder(@Nullable String alias, P path) {
|
||||
|
||||
super(path);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.beans.PropertyDescriptor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.querydsl.EntityPathResolver;
|
||||
import org.springframework.data.querydsl.QuerydslUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.querydsl.core.types.Path;
|
||||
|
||||
@@ -55,7 +56,14 @@ class QuerydslPathInformation implements PathInformation {
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getLeafParentType() {
|
||||
return path.getMetadata().getParent().getType();
|
||||
|
||||
Path<?> parent = path.getMetadata().getParent();
|
||||
|
||||
if (parent == null) {
|
||||
throw new IllegalStateException(String.format("Could not obtain metadata for parent node of %s!", path));
|
||||
}
|
||||
|
||||
return parent.getType();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -71,6 +79,7 @@ class QuerydslPathInformation implements PathInformation {
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.querydsl.binding.MappedPath#getLeafPropertyDescriptor()
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public PropertyDescriptor getLeafPropertyDescriptor() {
|
||||
return BeanUtils.getPropertyDescriptor(getLeafParentType(), getLeafProperty());
|
||||
|
||||
@@ -32,9 +32,9 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.querydsl.EntityPathResolver;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.querydsl.core.BooleanBuilder;
|
||||
@@ -81,6 +81,7 @@ public class QuerydslPredicateBuilder {
|
||||
* @param bindings the {@link QuerydslBindings} for the predicate.
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
public Predicate getPredicate(TypeInformation<?> type, MultiValueMap<String, String> values,
|
||||
QuerydslBindings bindings) {
|
||||
|
||||
@@ -173,7 +174,8 @@ public class QuerydslPredicateBuilder {
|
||||
for (String value : source) {
|
||||
|
||||
target.add(conversionService.canConvert(String.class, targetType)
|
||||
? conversionService.convert(value, TypeDescriptor.forObject(value), getTargetTypeDescriptor(path)) : value);
|
||||
? conversionService.convert(value, TypeDescriptor.forObject(value), getTargetTypeDescriptor(path))
|
||||
: value);
|
||||
}
|
||||
|
||||
return target;
|
||||
@@ -193,12 +195,17 @@ public class QuerydslPredicateBuilder {
|
||||
Class<?> owningType = path.getLeafParentType();
|
||||
String leafProperty = path.getLeafProperty();
|
||||
|
||||
if (descriptor == null) {
|
||||
return TypeDescriptor.nested(ReflectionUtils.findField(owningType, leafProperty), 0);
|
||||
TypeDescriptor result = descriptor == null //
|
||||
? TypeDescriptor
|
||||
.nested(org.springframework.data.util.ReflectionUtils.findRequiredField(owningType, leafProperty), 0)
|
||||
: TypeDescriptor
|
||||
.nested(new Property(owningType, descriptor.getReadMethod(), descriptor.getWriteMethod(), leafProperty), 0);
|
||||
|
||||
if (result == null) {
|
||||
throw new IllegalStateException(String.format("Could not obtain TypeDesciptor for PathInformation %s!", path));
|
||||
}
|
||||
|
||||
return TypeDescriptor
|
||||
.nested(new Property(owningType, descriptor.getReadMethod(), descriptor.getWriteMethod(), leafProperty), 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Base classes to implement CDI support for repositories.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.data.querydsl.binding;
|
||||
@@ -3,4 +3,5 @@
|
||||
*
|
||||
* @see <a href="http://www.querydsl.com">http://www.querydsl.com</a>
|
||||
*/
|
||||
package org.springframework.data.querydsl;
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.data.querydsl;
|
||||
|
||||
Reference in New Issue
Block a user