diff --git a/src/main/java/org/springframework/data/util/KotlinReflectionUtils.java b/src/main/java/org/springframework/data/util/KotlinReflectionUtils.java index 16206b4cd..674e36ee4 100644 --- a/src/main/java/org/springframework/data/util/KotlinReflectionUtils.java +++ b/src/main/java/org/springframework/data/util/KotlinReflectionUtils.java @@ -155,7 +155,10 @@ public final class KotlinReflectionUtils { } private static boolean isLast(MethodParameter parameter) { - return parameter.getParameterIndex() == parameter.getMethod().getParameterCount() - 1; + + Method method = parameter.getMethod(); + + return method != null && parameter.getParameterIndex() == method.getParameterCount() - 1; } /** diff --git a/src/main/java/org/springframework/data/util/Lazy.java b/src/main/java/org/springframework/data/util/Lazy.java index 276507ff2..8385a13bb 100644 --- a/src/main/java/org/springframework/data/util/Lazy.java +++ b/src/main/java/org/springframework/data/util/Lazy.java @@ -38,14 +38,29 @@ public class Lazy implements Supplier { private final Supplier supplier; - private @Nullable T value = null; - private boolean resolved = false; + private @Nullable T value; + private boolean resolved; + /** + * Creates a new {@link Lazy} instance for the given supplier. + * + * @param supplier + * @deprecated prefer {@link Lazy#of(Supplier)}, to be turned private in 2.5. + */ + @Deprecated public Lazy(Supplier supplier) { - this.supplier = supplier; + this(supplier, null, false); } - private Lazy(Supplier supplier, T value, boolean resolved) { + /** + * Creates a new {@link Lazy} for the given {@link Supplier}, value and whether it has been resolved or not. + * + * @param supplier must not be {@literal null}. + * @param value can be {@literal null}. + * @param resolved whether the value handed into the constructor represents a resolved value. + */ + private Lazy(Supplier supplier, @Nullable T value, boolean resolved) { + this.supplier = supplier; this.value = value; this.resolved = resolved; @@ -226,7 +241,7 @@ public class Lazy implements Supplier { * @see java.lang.Object#equals(java.lang.Object) */ @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; @@ -255,9 +270,12 @@ public class Lazy implements Supplier { */ @Override public int hashCode() { + int result = ObjectUtils.nullSafeHashCode(supplier); + result = 31 * result + ObjectUtils.nullSafeHashCode(value); result = 31 * result + (resolved ? 1 : 0); + return result; } } diff --git a/src/main/java/org/springframework/data/util/MethodInvocationRecorder.java b/src/main/java/org/springframework/data/util/MethodInvocationRecorder.java index afebb22ba..e1db51af0 100644 --- a/src/main/java/org/springframework/data/util/MethodInvocationRecorder.java +++ b/src/main/java/org/springframework/data/util/MethodInvocationRecorder.java @@ -25,10 +25,10 @@ import java.util.Optional; import java.util.function.Function; import org.aopalliance.intercept.MethodInvocation; - import org.springframework.aop.framework.ProxyFactory; import org.springframework.core.CollectionFactory; import org.springframework.core.ResolvableType; +import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -170,9 +170,12 @@ public class MethodInvocationRecorder { private static final InvocationInformation NOT_INVOKED = new InvocationInformation(new Unrecorded(), null); private final Recorded recorded; - @Nullable private final Method invokedMethod; + private final @Nullable Method invokedMethod; + + public InvocationInformation(Recorded recorded, @Nullable Method invokedMethod) { + + Assert.notNull(recorded, "Recorded must not be null!"); - public InvocationInformation(Recorded recorded, Method invokedMethod) { this.recorded = recorded; this.invokedMethod = invokedMethod; } @@ -220,7 +223,7 @@ public class MethodInvocationRecorder { * @see java.lang.Object#equals(java.lang.Object) */ @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; @@ -245,8 +248,11 @@ public class MethodInvocationRecorder { */ @Override public int hashCode() { + int result = ObjectUtils.nullSafeHashCode(recorded); + result = 31 * result + ObjectUtils.nullSafeHashCode(invokedMethod); + return result; } @@ -275,7 +281,7 @@ public class MethodInvocationRecorder { * (non-Javadoc) * @see org.springframework.hateoas.core.Recorder.PropertyNameDetectionStrategy#getPropertyName(java.lang.reflect.Method) */ - + @NonNull @Override public String getPropertyName(Method method) { return getPropertyName(method.getReturnType(), method.getName()); @@ -299,7 +305,8 @@ public class MethodInvocationRecorder { private final @Nullable T currentInstance; private final @Nullable MethodInvocationRecorder recorder; - public Recorded(T currentInstance, MethodInvocationRecorder recorder) { + Recorded(@Nullable T currentInstance, @Nullable MethodInvocationRecorder recorder) { + this.currentInstance = currentInstance; this.recorder = recorder; } @@ -367,6 +374,7 @@ public class MethodInvocationRecorder { */ @Override public String toString() { + return "MethodInvocationRecorder.Recorded(currentInstance=" + this.currentInstance + ", recorder=" + this.recorder + ")"; } @@ -378,7 +386,6 @@ public class MethodInvocationRecorder { static class Unrecorded extends Recorded { - @SuppressWarnings("null") private Unrecorded() { super(null, null); } diff --git a/src/main/java/org/springframework/data/util/Pair.java b/src/main/java/org/springframework/data/util/Pair.java index 0178d6277..db3d311a3 100644 --- a/src/main/java/org/springframework/data/util/Pair.java +++ b/src/main/java/org/springframework/data/util/Pair.java @@ -20,6 +20,7 @@ import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -90,7 +91,7 @@ public final class Pair { * @see java.lang.Object#equals(java.lang.Object) */ @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; diff --git a/src/main/java/org/springframework/data/util/ParameterTypes.java b/src/main/java/org/springframework/data/util/ParameterTypes.java index 175650209..9798d38f8 100644 --- a/src/main/java/org/springframework/data/util/ParameterTypes.java +++ b/src/main/java/org/springframework/data/util/ParameterTypes.java @@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ObjectUtils; @@ -282,14 +283,18 @@ public class ParameterTypes { * @see java.lang.Object#equals(java.lang.Object) */ @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { + if (this == o) { return true; } + if (!(o instanceof ParameterTypes)) { return false; } + ParameterTypes that = (ParameterTypes) o; + return ObjectUtils.nullSafeEquals(types, that.types); } @@ -348,7 +353,7 @@ public class ParameterTypes { * @see org.springframework.data.util.ParentTypeAwareTypeInformation#equals(java.lang.Object) */ @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; @@ -363,6 +368,7 @@ public class ParameterTypes { } ParentParameterTypes that = (ParentParameterTypes) o; + return ObjectUtils.nullSafeEquals(tail, that.tail); } @@ -372,8 +378,11 @@ public class ParameterTypes { */ @Override public int hashCode() { + int result = super.hashCode(); + result = 31 * result + ObjectUtils.nullSafeHashCode(tail); + return result; } } diff --git a/src/main/java/org/springframework/data/util/TypeDiscoverer.java b/src/main/java/org/springframework/data/util/TypeDiscoverer.java index 908fc3acf..34e68cf8f 100644 --- a/src/main/java/org/springframework/data/util/TypeDiscoverer.java +++ b/src/main/java/org/springframework/data/util/TypeDiscoverer.java @@ -24,16 +24,7 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -629,7 +620,7 @@ class TypeDiscoverer implements TypeInformation { * @see org.springframework.data.util.ParentTypeAwareTypeInformation#equals(java.lang.Object) */ @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; diff --git a/src/main/java/org/springframework/data/web/HateoasSortHandlerMethodArgumentResolver.java b/src/main/java/org/springframework/data/web/HateoasSortHandlerMethodArgumentResolver.java index d2e89e444..8caaad19e 100644 --- a/src/main/java/org/springframework/data/web/HateoasSortHandlerMethodArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/HateoasSortHandlerMethodArgumentResolver.java @@ -37,7 +37,6 @@ import org.springframework.web.util.UriComponentsBuilder; * @author Thomas Darimont * @author Nick Williams */ -@SuppressWarnings("null") public class HateoasSortHandlerMethodArgumentResolver extends SortHandlerMethodArgumentResolver implements UriComponentsContributor { diff --git a/src/main/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactory.java b/src/main/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactory.java index 0865224b8..1f2f2ae1b 100644 --- a/src/main/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactory.java +++ b/src/main/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactory.java @@ -29,7 +29,6 @@ import java.util.Map; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; - import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.projection.Accessor; @@ -136,7 +135,7 @@ public class JsonProjectingMethodInterceptorFactory implements MethodInterceptor */ @Nullable @Override - public Object invoke(@SuppressWarnings("null") MethodInvocation invocation) throws Throwable { + public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); TypeInformation returnType = ClassTypeInformation.fromReturnTypeOf(method); diff --git a/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java b/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java index 804351a64..95765bef9 100644 --- a/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java +++ b/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java @@ -92,7 +92,6 @@ public class PagedResourcesAssembler implements RepresentationModelAssembler< * @see org.springframework.hateoas.server.RepresentationModelAssembler#toModel(java.lang.Object) */ @Override - @SuppressWarnings("null") public PagedModel> toModel(Page entity) { return toModel(entity, EntityModel::of); } diff --git a/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java b/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java index adc7c591a..12110a3cc 100644 --- a/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java @@ -49,7 +49,7 @@ import org.springframework.web.util.UriComponentsBuilder; */ public class PagedResourcesAssemblerArgumentResolver implements HandlerMethodArgumentResolver { - private static final Log logger = LogFactory.getLog(PagedResourcesAssemblerArgumentResolver.class); + private static final Log logger = LogFactory.getLog(PagedResourcesAssemblerArgumentResolver.class); private static final String SUPERFLOUS_QUALIFIER = "Found qualified %s parameter, but a unique unqualified %s parameter. Using that one, but you might want to check your controller method configuration!"; private static final String PARAMETER_AMBIGUITY = "Discovered multiple parameters of type Pageable but no qualifier annotations to disambiguate!"; @@ -152,7 +152,8 @@ public class PagedResourcesAssemblerArgumentResolver implements HandlerMethodArg MethodParameter matchingParameter = returnIfQualifiersMatch(pageableParameter, assemblerQualifier); if (matchingParameter == null) { - logger.info(LogMessage.format(SUPERFLOUS_QUALIFIER, PagedResourcesAssembler.class.getSimpleName(), Pageable.class.getName())); + logger.info(LogMessage.format(SUPERFLOUS_QUALIFIER, PagedResourcesAssembler.class.getSimpleName(), + Pageable.class.getName())); } return pageableParameter;